PinnedHeaderListView实现删除
实现 删除
2023-09-14 08:57:56 时间
项目中用到四个List集合展示一个页面,并且每个页面都会有一个标题栏.找了半天资料决定用PinnedHeaderListView开源项目.最后需求又来了,需要一个删除的功能,又去网上找资料,发现没有实现删除的demo,于是自己把PinnedHeaderListView源码分析了下,其实也就一个类.下面我贴上代码,希望后面的朋友少走弯路.
PinnedHeaderListView 实现滚动,重绘,添加回调函数
public static interface PinnedSectionedHeaderAdapter { public boolean isSectionHeader(int position); public int getSectionForPosition(int position); public View getSectionHeaderView(int section, View convertView, ViewGroup parent); public int getSectionHeaderViewType(int section); public int getCount(); } private PinnedSectionedHeaderAdapter mAdapter; private View mCurrentHeader; private int mCurrentHeaderViewType = 0; private float mHeaderOffset; private boolean mShouldPin = true; private int mCurrentSection = 0; private int mWidthMode; private int mHeightMode; public PinnedHeaderListView(Context context) { super(context); super.setOnScrollListener(this); } public PinnedHeaderListView(Context context, AttributeSet attrs) { super(context, attrs); super.setOnScrollListener(this); } public PinnedHeaderListView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); super.setOnScrollListener(this); } public void setPinHeaders(boolean shouldPin) { mShouldPin = shouldPin; } @Override public void setAdapter(ListAdapter adapter) { mCurrentHeader = null; mAdapter = (PinnedSectionedHeaderAdapter) adapter; super.setAdapter(adapter); } @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { if (mOnScrollListener != null) { mOnScrollListener.onScroll(view, firstVisibleItem, visibleItemCount, totalItemCount); } if (mAdapter == null || mAdapter.getCount() == 0 || !mShouldPin || (firstVisibleItem getHeaderViewsCount())) { mCurrentHeader = null; mHeaderOffset = 0.0f; for (int i = firstVisibleItem; i firstVisibleItem + visibleItemCount; i++) { View header = getChildAt(i); if (header != null) { header.setVisibility(VISIBLE); } } return; } firstVisibleItem -= getHeaderViewsCount(); int section = mAdapter.getSectionForPosition(firstVisibleItem); int viewType = mAdapter.getSectionHeaderViewType(section); mCurrentHeader = getSectionHeaderView(section, mCurrentHeaderViewType != viewType ? null : mCurrentHeader); ensurePinnedHeaderLayout(mCurrentHeader); mCurrentHeaderViewType = viewType; mHeaderOffset = 0.0f; for (int i = firstVisibleItem; i firstVisibleItem + visibleItemCount; i++) { if (mAdapter.isSectionHeader(i)) { View header = getChildAt(i - firstVisibleItem); float headerTop = header.getTop(); float pinnedHeaderHeight = mCurrentHeader.getMeasuredHeight(); header.setVisibility(VISIBLE); if (pinnedHeaderHeight = headerTop headerTop 0) { mHeaderOffset = headerTop - header.getHeight(); } else if (headerTop = 0) { header.setVisibility(INVISIBLE); } } } invalidate(); } @Override public void onScrollStateChanged(AbsListView view, int scrollState) { if (mOnScrollListener != null) { mOnScrollListener.onScrollStateChanged(view, scrollState); } } private View getSectionHeaderView(int section, View oldView) { boolean shouldLayout = section != mCurrentSection || oldView == null; View view = mAdapter.getSectionHeaderView(section, oldView, this); if (shouldLayout) { // a new section, thus a new header. We should lay it out again ensurePinnedHeaderLayout(view); mCurrentSection = section; } return view; } private void ensurePinnedHeaderLayout(View header) { if (header.isLayoutRequested()) { int widthSpec = MeasureSpec.makeMeasureSpec(getMeasuredWidth(), mWidthMode); int heightSpec; ViewGroup.LayoutParams layoutParams = header.getLayoutParams(); if (layoutParams != null layoutParams.height 0) { heightSpec = MeasureSpec.makeMeasureSpec(layoutParams.height, MeasureSpec.EXACTLY); } else { heightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); } header.measure(widthSpec, heightSpec); header.layout(0, 0, header.getMeasuredWidth(), header.getMeasuredHeight()); } } @Override protected void dispatchDraw(Canvas canvas) { super.dispatchDraw(canvas); if (mAdapter == null || !mShouldPin || mCurrentHeader == null) return; int saveCount = canvas.save(); canvas.translate(0, mHeaderOffset); canvas.clipRect(0, 0, getWidth(), mCurrentHeader.getMeasuredHeight()); // needed // for // // HONEYCOMB mCurrentHeader.draw(canvas); canvas.restoreToCount(saveCount); } @Override public void setOnScrollListener(OnScrollListener l) { mOnScrollListener = l; } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); mWidthMode = MeasureSpec.getMode(widthMeasureSpec); mHeightMode = MeasureSpec.getMode(heightMeasureSpec); } public void setOnItemClickListener(PinnedHeaderListView.OnItemClickListener listener) { super.setOnItemClickListener(listener); } public static abstract class OnItemClickListener implements AdapterView.OnItemClickListener { @Override public void onItemClick(AdapterView ? adapterView, View view, int rawPosition, long id) { SectionedBaseAdapter adapter; if (adapterView.getAdapter().getClass().equals(HeaderViewListAdapter.class)) { HeaderViewListAdapter wrapperAdapter = (HeaderViewListAdapter) adapterView.getAdapter(); adapter = (SectionedBaseAdapter) wrapperAdapter.getWrappedAdapter(); } else { adapter = (SectionedBaseAdapter) adapterView.getAdapter(); } int section = adapter.getSectionForPosition(rawPosition); int position = adapter.getPositionInSectionForPosition(rawPosition); if (position == -1) { onSectionClick(adapterView, view, section, id); } else { onItemClick(adapterView, view, section, position, id); } } public abstract void onItemClick(AdapterView ? adapterView, View view, int section, int position, long id); public abstract void onSectionClick(AdapterView ? adapterView, View view, int section, long id); }
import android.widget.BaseAdapter; import za.co.immedia.pinnedheaderlistview.PinnedHeaderListView.PinnedSectionedHeaderAdapter; public abstract class SectionedBaseAdapter extends BaseAdapter implements PinnedSectionedHeaderAdapter { private static int HEADER_VIEW_TYPE = 0; private static int ITEM_VIEW_TYPE = 0; /** * Holds the calculated values of @{link getPositionInSectionForPosition} */ private SparseArray Integer mSectionPositionCache; /** * Holds the calculated values of @{link getSectionForPosition} */ private SparseArray Integer mSectionCache; /** * Holds the calculated values of @{link getCountForSection} */ private SparseArray Integer mSectionCountCache; /** * Caches the item count */ private int mCount; /** * Caches the section count */ private int mSectionCount; public SectionedBaseAdapter() { super(); mSectionCache = new SparseArray Integer mSectionPositionCache = new SparseArray Integer mSectionCountCache = new SparseArray Integer mCount = -1; mSectionCount = -1; } @Override public void notifyDataSetChanged() { mSectionCache.clear(); mSectionPositionCache.clear(); mSectionCountCache.clear(); mCount = -1; mSectionCount = -1; super.notifyDataSetChanged(); } @Override public void notifyDataSetInvalidated() { mSectionCache.clear(); mSectionPositionCache.clear(); mSectionCountCache.clear(); mCount = -1; mSectionCount = -1; super.notifyDataSetInvalidated(); } @Override public final int getCount() { if (mCount = 0) { return mCount; } int count = 0; for (int i = 0; i internalGetSectionCount(); i++) { count += internalGetCountForSection(i); count++; // for the header view } mCount = count; return count; } @Override public final Object getItem(int position) { return getItem(getSectionForPosition(position), getPositionInSectionForPosition(position)); } @Override public final long getItemId(int position) { return getItemId(getSectionForPosition(position), getPositionInSectionForPosition(position)); } @Override public final View getView(int position, View convertView, ViewGroup parent) { if (isSectionHeader(position)) { return getSectionHeaderView(getSectionForPosition(position), convertView, parent); } return getItemView(getSectionForPosition(position), getPositionInSectionForPosition(position), convertView, parent); } @Override public final int getItemViewType(int position) { if (isSectionHeader(position)) { return getItemViewTypeCount() + getSectionHeaderViewType(getSectionForPosition(position)); } return getItemViewType(getSectionForPosition(position), getPositionInSectionForPosition(position)); } @Override public final int getViewTypeCount() { return getItemViewTypeCount() + getSectionHeaderViewTypeCount(); } public final int getSectionForPosition(int position) { // first try to retrieve values from cache Integer cachedSection = mSectionCache.get(position); if (cachedSection != null) { return cachedSection; } int sectionStart = 0; for (int i = 0; i internalGetSectionCount(); i++) { int sectionCount = internalGetCountForSection(i); int sectionEnd = sectionStart + sectionCount + 1; if (position = sectionStart position sectionEnd) { mSectionCache.put(position, i); return i; } sectionStart = sectionEnd; } return 0; } public int getPositionInSectionForPosition(int position) { // first try to retrieve values from cache Integer cachedPosition = mSectionPositionCache.get(position); if (cachedPosition != null) { return cachedPosition; } int sectionStart = 0; for (int i = 0; i internalGetSectionCount(); i++) { int sectionCount = internalGetCountForSection(i); int sectionEnd = sectionStart + sectionCount + 1; if (position = sectionStart position sectionEnd) { int positionInSection = position - sectionStart - 1; mSectionPositionCache.put(position, positionInSection); return positionInSection; } sectionStart = sectionEnd; } return 0; } public final boolean isSectionHeader(int position) { int sectionStart = 0; for (int i = 0; i internalGetSectionCount(); i++) { if (position == sectionStart) { return true; } else if (position sectionStart) { return false; } sectionStart += internalGetCountForSection(i) + 1; } return false; } public int getItemViewType(int section, int position) { return ITEM_VIEW_TYPE; } public int getItemViewTypeCount() { return 1; } public int getSectionHeaderViewType(int section) { return HEADER_VIEW_TYPE; } public int getSectionHeaderViewTypeCount() { return 1; } public abstract Object getItem(int section, int position); public abstract long getItemId(int section, int position); public abstract int getSectionCount(); public abstract int getCountForSection(int section); public abstract View getItemView(int section, int position, View convertView, ViewGroup parent); public abstract View getSectionHeaderView(int section, View convertView, ViewGroup parent); private int internalGetCountForSection(int section) { Integer cachedSectionCount = mSectionCountCache.get(section); if (cachedSectionCount != null) { return cachedSectionCount; } int sectionCount = getCountForSection(section); mSectionCountCache.put(section, sectionCount); return sectionCount; } private int internalGetSectionCount() { if (mSectionCount = 0) { return mSectionCount; } mSectionCount = getSectionCount(); return mSectionCount; }
import za.co.immedia.pinnedheaderlistview.SectionedBaseAdapter; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.widget.LinearLayout; import android.widget.RelativeLayout; import android.widget.TextView; public class TestSectionedAdapter extends SectionedBaseAdapter{ private List String titles;//所有标题 private Map String,List SWWSafearea mMap;//根据首字母存放数据 public TestSectionedAdapter(){ List SWWSafearea localWifi=new ArrayList SWWSafearea for(int i=1;i =10;i++){ localWifi.add(new SWWSafearea(i,"10"+i)); } List SWWSafearea localGeography=new ArrayList SWWSafearea for(int i=4;i =15;i++){ localGeography.add(new SWWSafearea(i,"10"+i,i)); } List SWWSafearea serverWifi=new ArrayList SWWSafearea // for(int i=7;i i++){ // serverWifi.add(new SWWSafearea(i,"10"+i)); // } List SWWSafearea serverGeography=new ArrayList SWWSafearea for(int i=30;i =60;i++){ serverGeography.add(new SWWSafearea(i,"10"+i,i)); } titles=new ArrayList String titles.add("1"); titles.add("2"); titles.add("3"); titles.add("4"); mMap = new HashMap String, List SWWSafearea (); mMap.put(titles.get(0),localWifi); mMap.put(titles.get(1),localGeography); mMap.put(titles.get(2),serverWifi); mMap.put(titles.get(3),serverGeography); } @Override public Object getItem(int section, int position) { return mMap.get(titles.get(section)).get(position); } @Override public long getItemId(int section, int position) { return 0; } @Override public int getSectionCount() {//一共显示多少行标题栏 return titles.size(); } //每列显示的行数 @Override public int getCountForSection(int section) { return mMap.get(titles.get(section)).size(); } @Override public View getItemView(final int section,final int position, View convertView, ViewGroup parent) { ViewHolder holder=null; if (null==convertView) { holder=new ViewHolder(); LayoutInflater inflator = (LayoutInflater) parent.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); convertView=(LinearLayout)inflator.inflate(R.layout.list_item, null); holder.name=(TextView) convertView.findViewById(R.id.name); holder.radius=(TextView) convertView.findViewById(R.id.radius); holder.safeareaItem=(RelativeLayout) convertView.findViewById(R.id.safearea_item); convertView.setTag(holder); }else{ holder=(ViewHolder) convertView.getTag(); } SWWSafearea sf=mMap.get(titles.get(section)).get(position); if(section==0||section==2){ holder.name.setText(sf.name); holder.radius.setText(""); }else{ holder.name.setText(sf.name); holder.radius.setText(""+sf.radius); } holder.safeareaItem.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { mMap.get(titles.get(section)).remove(position); notifyDataSetChanged(); } }); return convertView; } private class ViewHolder{ TextView name,radius; RelativeLayout safeareaItem; } @Override public View getSectionHeaderView(int section, View convertView, ViewGroup parent) { LinearLayout layout = null; if (convertView == null) { LayoutInflater inflator = (LayoutInflater) parent.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); layout = (LinearLayout) inflator.inflate(R.layout.header_item, null); } else { layout = (LinearLayout) convertView; } TextView textView=((TextView) layout.findViewById(R.id.textItem)); if(mMap.get(titles.get(section)).size() 0){ textView.setVisibility(View.VISIBLE); textView.setText(titles.get(section)); }else{ textView.setVisibility(View.GONE); } return layout; } //实体类 private class SWWSafearea{ public int id; public String name; public int radius; public SWWSafearea(int id, String name, int radius) { super(); this.id = id; this.name = name; this.radius = radius; } public SWWSafearea(int id, String name) { super(); this.id = id; this.name = name; } }
import android.view.Menu; import za.co.immedia.pinnedheaderlistview.PinnedHeaderListView; public class MainActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); PinnedHeaderListView listView = (PinnedHeaderListView) findViewById(R.id.pinnedListView); TestSectionedAdapter sectionedAdapter = new TestSectionedAdapter(); listView.setAdapter(sectionedAdapter); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.activity_main, menu); return true; }
效果图如下:
推荐下自己创建的android QQ群:202928390 欢迎大家的加入.
应用能否下线或删除 应用如果是“已上线”状态不可删除和下线(如下图) 应用是“开发中”如何删除 1.【点击登录】管理中心》找到要删除的应用,选择查看》在右上角选择删除操作即可
批量插入使用batchInsert函数实现批量插入,它与insert函数非常像,只是它接受的是一个文档数组作为参数。
ansen_666 有三年android开发经验,开发过加密.短视频.直播app,一直在互联网公司工作,目前就职于上海翼成科技,担任android开发组长。
相关文章
- Vue(27)vue-codemirror实现在线代码编译器「建议收藏」
- postgresql 实现多表关联删除
- [android] 练习PopupWindow实现对话框详解手机开发
- Python实现批量梯度下降算法详解编程语言
- java两种同步机制的实现 synchronized和reentrantlock详解编程语言
- 删除Oracle数据库中的列——SQL实现(oracle删除列sql)
- 使用Redis自动实现定时删除(redis定时删除)
- Linux下轻松实现批量重命名(批量重命名linux)
- 如何设置MySQL实现远程访问?详细解析步骤及注意事项。(mysql远程访问设置)
- MSSQL中如何利用表删除行命令实现快速数据清理(mssql表删除行命令)
- C语言环境下如何实现MySQL数据库的删除(c mysql 删除)
- Oracle 连接连接 2 台电脑的完美实现(2台电脑oracle连接)
- 重新定义二维数组存储Redis实现(二维数组放redis)
- 灵活性提升基于Redis的延迟队列实现(基于redis的延迟队列)
- Redis实现更高效的主键设置(redis设置主键)
- 使用Redis实现订单定时删除(redis订单定时删除)
- Redis实现远程批量删除数据(redis远程批量删除)
- aspx中利用js实现确认删除代码
- 点击图片,AJAX删除后台图片文件的实现代码(asp.net)
- jQuery三击事件实现代码
- python实现删除文件与目录的方法
- PHP实现支持GET,POST,Multipart/form-data的HTTP请求类