Android仿联系人列表分组悬浮列表实现,自己定义PinnedHeaderListView实现

业无高卑志当坚,男儿有求安得闲?这篇文章主要讲述Android仿联系人列表分组悬浮列表实现,自己定义PinnedHeaderListView实现相关的知识,希望能为你提供帮助。

效果

Android仿联系人列表分组悬浮列表实现,自己定义PinnedHeaderListView实现

文章图片

(关于gif怎么生成的。我先录手机的屏幕得到mp4文件。然后用这个网址:https://cloudconvert.com/mp4-to-gif 进行的mp4转换gif,使用的时候须要又一次选择gif的大小,不然生成的gif图片太大了)
效果包含下面几个方面
1. 当组的头部从屏幕顶部消失。并且组还有成员在屏幕内的时候。组的头部悬浮在屏幕顶部,并且为红色背景(我设置的组的头部是黄色背景)
2.当下一个组的头部滑到屏幕顶部与红色的悬浮头部挨着的时候。把红色的头部顶走(红色头部随下一个组的头部上滑而上滑,知道消失不见),终于悬浮的头部被替代
3.点击header view,组头部,组内元素,footer view分别响应各自的点击事件
github地址:https://github.com/JimiSmith/PinnedHeaderListView
假设你希望先阅读源代码解析,看这里:http://blog.csdn.net/u010335298/article/details/51178179

思路


1.悬浮header的实现
通过得到当前应该悬浮的头部的view,调用listview的dispatchDraw方法,在Listview头部绘制悬浮头部
@Override protected void dispatchDraw(Canvas canvas) { super.dispatchDraw(canvas); if(currentSectionHeader !=null){ canvas.save(); canvas.translate(0, currentSectionHeaderOffest); canvas.clipRect(0,0,currentSectionHeader.width,currentSectionHeader.height); currentSectionHeader.view.draw(canvas); canvas.restore(); } }



2.悬浮header被顶出屏幕的实现:
【Android仿联系人列表分组悬浮列表实现,自己定义PinnedHeaderListView实现】通过改变变量currentSectionHeaderOffest来改变悬浮header的位置
if(nextIsSectionHeaderView.getTop() > = 0 & & currentSectionHeader!=null & & nextIsSectionHeaderView.getTop() < currentSectionHeader.height){ currentSectionHeaderOffest = nextIsSectionHeaderView.getTop() - currentSectionHeader.height; // < 0的哦 Log.d(TAG,"move current section header view"); } invalidate();



3.得到应该悬浮在顶部的view
遍历全部可见的view,得到第一个是组的头部的view的位置,组号,然后用adapter.getView(…)函数得到这个view
//遍历全部可见的部分找到nextSectionHeader; View nextIsSectionHeaderView = null; for(int i=firstVisibleItem; i< firstVisibleItem + visibleItemCount; i++){ if(mAdapter.isSectionHeader(i)){ nextIsSectionHeaderView= getChildAt(i-firstVisibleItem); nextSectionHeader = new SectionHeader(mAdapter.getView(i,null,this), i,mAdapter.getSectionId(i)); break; } }



4.监听listview的onScroll , 时刻更新数据
@Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { //重置currentSectionHeaderOffest currentSectionHeaderOffest = 0; headerCount = getHeaderViewsCount(); if(mAdapter==null || mAdapter.getCount()< =0 || firstVisibleItem < headerCount){ currentSectionHeader = null; nextSectionHeader = null; return; } firstVisibleItem = firstVisibleItem - headerCount ; //遍历全部可见的部分找到nextSectionHeader; View nextIsSectionHeaderView = null; for(int i=firstVisibleItem; i< firstVisibleItem + visibleItemCount; i++){ if(mAdapter.isSectionHeader(i)){ nextIsSectionHeaderView= getChildAt(i-firstVisibleItem); nextSectionHeader = new SectionHeader(mAdapter.getView(i,null,this), i,mAdapter.getSectionId(i)); break; } } //得到currentSectionHeader //优化。当当前须要展示的和当前展示的不一致时。才new if(currentSectionHeader==null || currentSectionHeader.sectionId != mAdapter.getSectionId(firstVisibleItem)){ currentSectionHeader = new SectionHeader(mAdapter.getSectionHeaderView(mAdapter.getSectionId(firstVisibleItem),null,this), mAdapter.getSectionPosition(mAdapter.getSectionId(firstVisibleItem)),mAdapter.getSectionId(firstVisibleItem)); currentSectionHeader.view.layout(0,0,currentSectionHeader.width,currentSectionHeader.height); //!!!!!一定不能少 } //推断nextSectionHeader的位置,假设距离顶部高度小于currentSectionHeader高度,使currentSectionHeader向上推移动 if(nextIsSectionHeaderView!=null ){if(nextIsSectionHeaderView.getTop() > = 0 & & currentSectionHeader!=null & & nextIsSectionHeaderView.getTop() < currentSectionHeader.height){ currentSectionHeaderOffest = nextIsSectionHeaderView.getTop() - currentSectionHeader.height; // < 0的哦 Log.d(TAG,"move current section header view"); } invalidate(); }}



5.onItemClick的时候。注意header和footer的影响
/********************************************************************************************* * * 实现OnItemClickListener * **********************************************************************************************/ @Override public void onItemClick(AdapterView< ?> parent, View view, int position, long id) { headerCount = getHeaderViewsCount(); if(position < headerCount){ if(mOnItemClickListener!=null){ mOnItemClickListener.onHeaderClick(parent, view, position, id); } return; } if(mAdapter!= null & & position > = headerCount + mAdapter.getCount()){ if(mOnItemClickListener!=null){ mOnItemClickListener.onFooterClick(parent, view, position - headerCount - mAdapter.getCount(), id); } return; } position = position - headerCount; int section = mAdapter.getSectionId(position); int positionInSection = mAdapter.getPositionIdInSection(position); if (mAdapter.isSectionHeader(position)) { if( mOnItemClickListener != null){ mOnItemClickListener.onSectionClick(parent, view, section, id); } } else { if( mOnItemClickListener != null){ mOnItemClickListener.onSectionItemClick(parent, view, section, positionInSection, id); }} }public void setOnMyItemClickListener(MyOnItemClickListener mOnItemClickListener){ this.mOnItemClickListener = mOnItemClickListener; }public interface MyOnItemClickListener {void onSectionItemClick(AdapterView< ?
> adapterView, View view, int section, int position, long id); void onSectionClick(AdapterView< ?> adapterView, View view, int section, long id); void onHeaderClick(AdapterView< ?
> adapterView, View view, int position, long id); void onFooterClick(AdapterView< ?
> adapterView, View view, int position, long id); }



全部源代码:
1.CustomPinnedHeaderListView.java
package com.example.myapp.view; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.util.AttributeSet; import android.util.Log; import android.view.View; import android.view.ViewGroup; import android.widget.AbsListView; import android.widget.AdapterView; import android.widget.HeaderViewListAdapter; import android.widget.ListAdapter; import android.widget.ListView; import com.example.myapp.adapter.CustomPinnedHeaderListViewBaseAdapter; import com.example.myapp.github.pinnedheaderlistview.SectionedBaseAdapter; /** * Created by zyr * DATE: 16-4-12 * Time: 下午7:58 * Email: [email  protected] */ public class CustomPinnedHeaderListView extends ListView implements AbsListView.OnScrollListener , AdapterView.OnItemClickListener{private final static String TAG = "CusPinnedHeaderListView"; private Context mContext; private SectionHeader currentSectionHeader; private SectionHeader nextSectionHeader; private int currentSectionHeaderOffest ; private CustomPinnedHeaderListViewBaseAdapter mAdapter; private int mWidthMode; private int mHeightMode; private MyOnItemClickListener mOnItemClickListener; private int headerCount; //header view counts/********************************************************************************************* * * 构造函数 * **********************************************************************************************/ public CustomPinnedHeaderListView(Context context) { this(context, null); }public CustomPinnedHeaderListView(Context context, AttributeSet attrs) { this(context, attrs, 0); }public CustomPinnedHeaderListView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); mContext = context; setOnScrollListener(this); setOnItemClickListener(this); }@Override public void setAdapter(ListAdapter adapter) { super.setAdapter(adapter); if(adapter instanceof CustomPinnedHeaderListViewBaseAdapter){ mAdapter = (CustomPinnedHeaderListViewBaseAdapter)adapter; } Log.d(TAG, "is my adapter null :" + (mAdapter == null)); }@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); mWidthMode = MeasureSpec.getMode(widthMeasureSpec); mHeightMode = MeasureSpec.getMode(heightMeasureSpec); }/********************************************************************************************* * * 实现OnScrollListener * **********************************************************************************************/@Override public void onScrollStateChanged(AbsListView view, int scrollState) {}@Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { //重置currentSectionHeaderOffest currentSectionHeaderOffest = 0; headerCount = getHeaderViewsCount(); if(mAdapter==null || mAdapter.getCount()< =0 || firstVisibleItem < headerCount){ currentSectionHeader = null; nextSectionHeader = null; return; } firstVisibleItem = firstVisibleItem - headerCount ; //遍历全部可见的部分找到nextSectionHeader; View nextIsSectionHeaderView = null; for(int i=firstVisibleItem; i< firstVisibleItem + visibleItemCount; i++){ if(mAdapter.isSectionHeader(i)){ nextIsSectionHeaderView= getChildAt(i-firstVisibleItem); nextSectionHeader = new SectionHeader(mAdapter.getView(i,null,this), i,mAdapter.getSectionId(i)); break; } } //得到currentSectionHeader //优化,当当前须要展示的和当前展示的不一致时,才new if(currentSectionHeader==null || currentSectionHeader.sectionId != mAdapter.getSectionId(firstVisibleItem)){ currentSectionHeader = new SectionHeader(mAdapter.getSectionHeaderView(mAdapter.getSectionId(firstVisibleItem),null,this), mAdapter.getSectionPosition(mAdapter.getSectionId(firstVisibleItem)),mAdapter.getSectionId(firstVisibleItem)); currentSectionHeader.view.layout(0,0,currentSectionHeader.width,currentSectionHeader.height); //!!!!!一定不能少 } //推断nextSectionHeader的位置,假设距离顶部高度小于currentSectionHeader高度。使currentSectionHeader向上推移动 if(nextIsSectionHeaderView!=null ){if(nextIsSectionHeaderView.getTop() > = 0 & & currentSectionHeader!=null & & nextIsSectionHeaderView.getTop() < currentSectionHeader.height){ currentSectionHeaderOffest = nextIsSectionHeaderView.getTop() - currentSectionHeader.height; // < 0的哦 Log.d(TAG,"move current section header view"); } invalidate(); }}/********************************************************************************************* * * 实现dispatchDraw,最精髓的部分哦 * **********************************************************************************************/@Override protected void dispatchDraw(Canvas canvas) { super.dispatchDraw(canvas); //Log.d(TAG, "is current section header null :" + (currentSectionHeader == null)); if(currentSectionHeader !=null){ canvas.save(); canvas.translate(0, currentSectionHeaderOffest); canvas.clipRect(0, 0, currentSectionHeader.width, currentSectionHeader.height); //Log.d(TAG,"is current section header view null :" + (currentSectionHeader.view==null)); currentSectionHeader.view.draw(canvas); canvas.restore(); } }/********************************************************************************************* * * 实现OnItemClickListener * **********************************************************************************************/ @Override public void onItemClick(AdapterView< ?> parent, View view, int position, long id) { headerCount = getHeaderViewsCount(); if(position < headerCount){ if(mOnItemClickListener!=null){ mOnItemClickListener.onHeaderClick(parent, view, position, id); } return; } if(mAdapter!= null & & position > = headerCount + mAdapter.getCount()){ if(mOnItemClickListener!=null){ mOnItemClickListener.onFooterClick(parent, view, position - headerCount - mAdapter.getCount(), id); } return; } position = position - headerCount; int section = mAdapter.getSectionId(position); int positionInSection = mAdapter.getPositionIdInSection(position); if (mAdapter.isSectionHeader(position)) { if( mOnItemClickListener != null){ mOnItemClickListener.onSectionClick(parent, view, section, id); } } else { if( mOnItemClickListener != null){ mOnItemClickListener.onSectionItemClick(parent, view, section, positionInSection, id); }} }public void setOnMyItemClickListener(MyOnItemClickListener mOnItemClickListener){ this.mOnItemClickListener = mOnItemClickListener; }public interface MyOnItemClickListener {void onSectionItemClick(AdapterView< ?> adapterView, View view, int section, int position, long id); void onSectionClick(AdapterView< ?
> adapterView, View view, int section, long id); void onHeaderClick(AdapterView< ?> adapterView, View view, int position, long id); void onFooterClick(AdapterView< ?
> adapterView, View view, int position, long id); }/********************************************************************************************* * * inner class * **********************************************************************************************/class SectionHeader{ public View view; public int sectionId; public int position; public int height; public int width; public SectionHeader(View view,int position,int sectionId){ this.view = view; this.position = position; this.sectionId = sectionId; int widthMeasureSpec = MeasureSpec.makeMeasureSpec(getMeasuredWidth(), mWidthMode); int heightMeasureSpec; ViewGroup.LayoutParams layoutParams = this.view.getLayoutParams(); if (layoutParams != null & & layoutParams.height > 0) { heightMeasureSpec = MeasureSpec.makeMeasureSpec(layoutParams.height, MeasureSpec.EXACTLY); } else { heightMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); } this.view.measure(widthMeasureSpec,heightMeasureSpec); this.height = this.view.getMeasuredHeight(); this.width = this.view.getMeasuredWidth(); this.view.setBackgroundColor(Color.RED); //Log.d(TAG,"width:" + this.width+ "height:" + this.height); } } }

2.CustomPinnedHeaderListViewBaseAdapter.java
package com.example.myapp.adapter; import android.util.Log; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; /** * Created by zyr * DATE: 16-4-12 * Time: 下午8:02 * Email: [email  protected] */ public abstract class CustomPinnedHeaderListViewBaseAdapter extends BaseAdapter{private final static String TAG = "CusPHLVBaseAdapter"; /********************************************************************************************* * * BaseAdapter , Adapter的接口 * **********************************************************************************************/ @Override public abstract int getCount() ; @Override public abstract Object getItem(int position) ; @Override public abstract long getItemId(int position) ; @Override public View getView(int position, View convertView, ViewGroup parent) { if(isSectionHeader(position)){ Log.d(TAG,"p:" + position + "s:" + getSectionId(position)); return getSectionHeaderView(getSectionId(position) , convertView ,parent); } else{ Log.d(TAG,"p:" + position + "s:" + getSectionId(position) + "pIns" + getPositionIdInSection(position)); return getItemView(getSectionId(position) , getPositionIdInSection(position) , convertView , parent); } }@Override public abstract int getViewTypeCount() ; @Override public abstract int getItemViewType(int position) ; /********************************************************************************************* * * 一些必须实现的抽象放法 * **********************************************************************************************/public abstract boolean isSectionHeader(int position) ; public abstract int getSectionId(int position) ; public abstract int getSectionPosition(int sectionId); public abstract View getSectionHeaderView(int section, View convertView, ViewGroup parent); public abstract int getSectionHeaderViewType(int section) ; public abstract int getPositionIdInSection(int position) ; public abstract Object getItem(int section, int positionInSection); public abstract long getItemId(int section, int positionInSection); public abstract int getSectionCount(); public abstract int getCountInSection(int section); public abstract View getItemView(int section, int positionInSection, View convertView, ViewGroup parent); }

3.CustomPinnedHeaderListViewAdapter.java
package com.example.myapp.adapter; import android.content.Context; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; import com.example.myapp.R; import java.util.ArrayList; import java.util.List; import java.util.Random; /** * Created by zyr * DATE: 16-4-12 * Time: 下午9:05 * Email: [email  protected] */ public class CustomPinnedHeaderListViewAdapter extends CustomPinnedHeaderListViewBaseAdapter {private final static String TAG = "CusPHeaderLvAdapter"; private Context mContext; private List< Section> sections = new ArrayList< > (); private int counts; private int sectionCounts; private Random random; public final static int TYPE_SECTION_HEADER = 1; public final static int TYPE_SECTION_ITEM = 2; public final static int TYPE_SECTION_ITEM_COUNT = 3; //getViewTypeCount() > getItemViewType返回的值/********************************************************************************************* * * 构造函数 * **********************************************************************************************/public CustomPinnedHeaderListViewAdapter(Context context){ this.mContext = context; this.random = new Random(); this.sectionCounts = 10; int position = 0; for(int i=0; i< sectionCounts; i++){ Section section = new Section(); int sectionItemCounts = random.nextInt(10) + 1; section.sectionItemCounts = sectionItemCounts; for(int j=0; j < sectionItemCounts; j++){ Item item; if(j==0){ item = new Item(true,position,i,j,"section :" + i,""); }else { item = new Item(false,position,i,j,"section :" + i,"item :" + j); } section.items.add(item); position++; } section.sectionId = i; section.sectionName = "section :" + i; counts = counts + section.sectionItemCounts; sections.add(section); Log.d(TAG,"----section id:" + section.sectionId + "section counts:" + section.sectionItemCounts); } }@Override public int getCount() { return counts; }@Override public Object getItem(int position) { for(int i=0; i< sections.size(); i++){ Section section = sections.get(i); for(int j=0; j< section.sectionItemCounts; j++){ Item item = section.items.get(j); if(item.position == position){ return item; } } } Log.e(TAG,"!!!!!!!!!!!!!!!" + "no find item when getItem"); return null; }@Override public long getItemId(int position) { return position; }@Override public int getViewTypeCount() { return TYPE_SECTION_ITEM_COUNT; }@Override public int getItemViewType(int position) { for(int i=0; i< sections.size(); i++){ Section section = sections.get(i); for(int j=0; j< section.sectionItemCounts; j++){ Item item = section.items.get(j); if(item.position == position){ if(item.isSectionHeader){ return TYPE_SECTION_HEADER; }else{ return TYPE_SECTION_ITEM; } } } } Log.e(TAG, "!!!!!!!!!!!!!!!" + "no find item when getItemViewType"); return TYPE_SECTION_ITEM; }@Override public boolean isSectionHeader(int position) { for(int i=0; i< sections.size(); i++){ Section section = sections.get(i); for(int j=0; j< section.sectionItemCounts; j++){ Item item = section.items.get(j); if(item.position == position){ if(item.isSectionHeader){ return true; }else{ return false; } } } } Log.e(TAG, "!!!!!!!!!!!!!!!" + "no find item when isSectionHeader"); return false; }@Override public int getSectionId(int position) { for(int i=0; i< sections.size(); i++){ Section section = sections.get(i); for(int j=0; j< section.sectionItemCounts; j++){ Item item = section.items.get(j); if(item.position == position){ return item.sectionId; } } } Log.e(TAG, "!!!!!!!!!!!!!!!" + "no find item when getSectionId"); return -1; }@Override public int getSectionPosition(int sectionId) { for(int i=0; i< sections.size(); i++){ Section section = sections.get(sectionId); for(int j=0; j< section.sectionItemCounts; j++){ if(section.items.get(j).isSectionHeader){ return section.items.get(j).position; } } } Log.e(TAG, "!!!!!!!!!!!!!!!" + "no find item when getSectionPosition"); return -1; }@Override public View getSectionHeaderView(int section, View convertView, ViewGroup parent) { Log.d(TAG,"getSectionHeaderView section:" + section); SectionHeaderViewHolder sectionHeaderViewHolder; if(convertView == null){ convertView = LayoutInflater.from(mContext).inflate(R.layout.custom_pinned_header_lv_section_header_layout,null); sectionHeaderViewHolder = new SectionHeaderViewHolder(convertView); convertView.setTag(sectionHeaderViewHolder); }else{ sectionHeaderViewHolder = (SectionHeaderViewHolder)convertView.getTag(); } Log.d(TAG,"getSectionHeaderView section:" + section); sectionHeaderViewHolder.sectionHeaderName.setText(sections.get(section).sectionName); return convertView; }@Override public int getSectionHeaderViewType(int section) { return 0; }@Override public int getPositionIdInSection(int position) { for(int i=0; i< sections.size(); i++){ Section section = sections.get(i); for(int j=0; j< section.sectionItemCounts; j++){ Item item = section.items.get(j); if(item.position == position){ return item.positionInSection; } } } Log.e(TAG, "!!!!!!!!!!!!!!!" + "no find item when getPositionIdInSection"); return -1; }@Override public Object getItem(int section, int positionInSection) { return sections.get(section).items.get(positionInSection); }@Override public long getItemId(int section, int positionInSection) { return sections.get(section).items.get(positionInSection).position; }@Override public int getSectionCount() { return sectionCounts; }@Override public int getCountInSection(int section) { return sections.get(section).sectionItemCounts; }@Override public View getItemView(int section, int positionInSection, View convertView, ViewGroup parent) { Log.d(TAG,"getItemView section:" + section + "positionInSection :" + positionInSection); ItemViewHolder itemViewHolder; if(convertView == null){ convertView = LayoutInflater.from(mContext).inflate(R.layout.custom_pinned_header_lv_section_item_layout,null); itemViewHolder = new ItemViewHolder(convertView); convertView.setTag(itemViewHolder); }else{ itemViewHolder = (ItemViewHolder)convertView.getTag(); } itemViewHolder.itemName.setText("p:" + sections.get(section).items.get(positionInSection).position + "s:" + section + "" + sections.get(section).items.get(positionInSection).itemName); return convertView; }/********************************************************************************************* * * 内部类 * **********************************************************************************************/ class Item{ public boolean isSectionHeader; public int position; public int sectionId; public int positionInSection; public String sectionName; public String itemName; public Item(boolean isSectionHeader,int position,int sectionId,int positionInSection,String sectionName,String itemName){ this.isSectionHeader = isSectionHeader; this.position = position; this.sectionId = sectionId; this.positionInSection = positionInSection; this.sectionName = sectionName; this.itemName = itemName; } }class Section{ public List< Item> items = new ArrayList< > (); public int sectionId ; public String sectionName ; public int sectionItemCounts ; }class ItemViewHolder{ public TextView itemName; public ItemViewHolder(View view){ itemName = (TextView) view.findViewById(R.id.tv); } }class SectionHeaderViewHolder{ public TextView sectionHeaderName; public SectionHeaderViewHolder(View view){ sectionHeaderName = (TextView) view.findViewById(R.id.tv); } }}

4.CustomPinnedHeaderListViewTestActivity.java
package com.example.myapp.activity; import android.view.LayoutInflater; import android.view.View; import android.widget.AdapterView; import com.example.myapp.R; import com.example.myapp.adapter.CustomPinnedHeaderListViewAdapter; import com.example.myapp.util.Methods; import com.example.myapp.view.CustomPinnedHeaderListView; /** * Created by zyr * DATE: 16-4-13 * Time: 下午2:25 * Email: [email  protected] */ public class CustomPinnedHeaderListViewTestActivity extends BaseActivity{private CustomPinnedHeaderListView listView; private CustomPinnedHeaderListViewAdapter adapter; private View headerView; private View footerView; @Override protected void initView() { listView = (CustomPinnedHeaderListView)findViewById(R.id.lv); headerView = LayoutInflater.from(this).inflate(R.layout.cus_pinned_header_lv_header,null); footerView = LayoutInflater.from(this).inflate(R.layout.cus_pinned_header_lv_footer,null); listView.addHeaderView(headerView); listView.addFooterView(footerView); adapter = new CustomPinnedHeaderListViewAdapter(this); listView.setAdapter(adapter); listView.setOnMyItemClickListener(new CustomPinnedHeaderListView.MyOnItemClickListener() { @Override public void onSectionItemClick(AdapterView< ?> adapterView, View view, int section, int position, long id) { Methods.toast(CustomPinnedHeaderListViewTestActivity.this,"s:" + section + "item:" + position); }@Override public void onSectionClick(AdapterView< ?> adapterView, View view, int section, long id) { Methods.toast(CustomPinnedHeaderListViewTestActivity.this,"s:" + section ); }@Override public void onHeaderClick(AdapterView< ?> adapterView, View view, int position, long id) { Methods.toast(CustomPinnedHeaderListViewTestActivity.this,"header:" + position ); }@Override public void onFooterClick(AdapterView< ?
> adapterView, View view, int position, long id) { Methods.toast(CustomPinnedHeaderListViewTestActivity.this,"footer:" + position); } }); }@Override protected int onSetContainerViewId() { return R.layout.activity_custom_pinned_header_lv; }@Override public void initListener() {}@Override public void onClick(View v) {} }















    推荐阅读