美文网首页
Android的listview添加头和脚的另一种方式

Android的listview添加头和脚的另一种方式

作者: 神山上人 | 来源:发表于2016-10-02 10:47 被阅读0次

    给listview和recyclerview添加header和footer,我们一般常用的方式,有如下几种:
    xml文件:


    1.自定义listview和recyclerview.添加头和尾
    2.使用第三方框架PullToRefresh进行添加头和尾
    3.使用谷歌最新推出的控件SwipeRefreshLayout,下面我们就来讲解一下怎么使用谷歌最新的特性进行添加头和尾
    该控件有一个缺点:自带功能中没有添加叫布局加载更多的方法.
    上图:


    只需要添加下拉加载更多的话,直接使用原生的控件即可:
    上代码:
    privateListViewlv;
    privateArrayListlist=newArrayList<>();
    privateListviewAdaptermAdapter;
    privateSwipeRefreshLayoutswipe;
    @Override
    protected voidonCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    lv= (ListView) findViewById(R.id.lv_listview);
    swipe= (SwipeRefreshLayout) findViewById(R.id.swipe);
    init();
    //设置下拉刷新的颜色
    swipe.setProgressBackgroundColorSchemeResource(android.R.color.holo_red_light);
    //下拉时触发SwipeRefreshLayout的下拉动画,动画完毕之后就会回调这个方法
    swipe.setOnRefreshListener(newSwipeRefreshLayout.OnRefreshListener() {
    @Override
    public voidonRefresh() {
    //开始刷新,设置当前为刷新状态
    //swipeRefreshLayout.setRefreshing(true);
    //这里是主线程
    //一些比较耗时的操作,比如联网获取数据,需要放到子线程去执行
    //TODO获取数据
    finalRandom random =newRandom();
    newHandler().postDelayed(newRunnable() {
    @Override
    public voidrun() {
    list.add(0,"我是刷新天才"+random.nextInt(100) +"号");
    mAdapter.notifyDataSetChanged();
    Toast.makeText(MainActivity.this,"刷新了一条数据", Toast.LENGTH_SHORT).show();
    //加载完数据设置为不刷新状态,将下拉进度收起来
    swipe.setRefreshing(false);
    }
    },2000);
    }
    });
    }
    /**
    *@authorhy
    @time2016/10/1 17:57
    /
    private voidinit() {
    addData();
    if(list!=null) {
    if(mAdapter==null) {
    mAdapter=newListviewAdapter(this,list);
    lv.setAdapter(mAdapter);
    }else{
    mAdapter.notifyDataSetChanged();
    }
    }
    }
    /

    *@authorhy
    @time2016/10/1 17:57
    /
    public voidaddData() {
    for(inti =1; i <=100; i++) {
    list.add("我是天才"+ i +"号");
    }
    }
    xml布局文件:
    就是一个swipeRefreshLayout里面包裹一个listview即可.
    添加footer,上啦加载更多,自定义该控件.
    /

    *作者:hy on 2016/10/2 00:02
    邮箱: simoncqhy@163.com
    /
    public classSwipeRefreshViewextendsSwipeRefreshLayout {
    privateViewmFooterView;
    //滑动的最小距离
    private intmSlop;
    //获取listview
    privateListViewmListView;
    privateOnLoadListenermOnLoadListener;
    //正在加载状态
    private booleanisLoading;
    publicSwipeRefreshView(Context context) {
    this(context,null);
    }
    publicSwipeRefreshView(Context context, AttributeSet attrs) {
    super(context, attrs);
    mFooterView= View.inflate(context, R.layout.view_footer,null);
    //设置滑动的最小距离,大于该距离才能滑动。
    mSlop= ViewConfiguration.get(context).getScaledTouchSlop();
    }
    @Override
    protected voidonLayout(booleanchanged,intleft,inttop,intright,intbottom) {
    super.onLayout(changed, left, top, right, bottom);
    if(mListView==null) {
    //判断容器有多少个子孩子
    if(getChildCount()>0) {
    //判断第一个孩子是不是ListView
    if(getChildAt(0)instanceofListView) {
    //创建ListView对象
    mListView= (ListView) getChildAt(0);
    //设置ListView的滑动监听
    setListViewOnScroll();
    }
    }
    }
    }
    //设置listview的滑动监听
    private voidsetListViewOnScroll() {
    mListView.setOnScrollListener(newAbsListView.OnScrollListener() {
    @Override
    public voidonScrollStateChanged(AbsListView view,intscrollState) {
    //移动过程中判断时候能下拉加载更多
    if(canLoadMore()) {
    //加载数据
    loadData();
    }
    }
    @Override
    public voidonScroll(AbsListView view,intfirstVisibleItem,intvisibleItemCount,inttotalItemCount) {
    }
    });
    }
    /

    *分发事件的处理
    *@paramev
    @return
    /
    private floatmDownY,mUpY;
    @Override
    public booleandispatchTouchEvent(MotionEvent ev) {
    switch(ev.getAction()) {
    caseMotionEvent.ACTION_DOWN:
    //移动的起点
    mDownY= ev.getY();
    break;
    caseMotionEvent.ACTION_MOVE:
    //移动过程中判断时候能下拉加载更多
    if(canLoadMore()) {
    //加载数据
    loadData();
    }
    break;
    caseMotionEvent.ACTION_UP:
    //移动的终点
    mUpY= getY();
    break;
    }
    return super.dispatchTouchEvent(ev);
    }
    /

    *判断是否能够加载更多
    @return
    /
    private booleancanLoadMore() {
    // 1.是上拉状态
    booleancondition1 = (mDownY-mUpY) >=mSlop;
    if(condition1) {
    System.out.println("是上拉状态");
    }
    // 2.当前页面可见的item是最后一个条目
    booleancondition2 =false;
    if(mListView!=null&&mListView.getAdapter() !=null) {
    condition2 =mListView.getLastVisiblePosition() == (mListView.getAdapter().getCount() -1);
    }
    if(condition2) {
    System.out.println("是最后一个条目");
    }
    // 3.正在加载状态
    booleancondition3 = !isLoading;
    if(condition3) {
    System.out.println("不是正在加载状态");
    }
    returncondition1 && condition2 && condition3;
    }
    /

    处理加载数据的逻辑
    /
    private voidloadData() {
    System.out.println("加载数据...");
    if(mOnLoadListener!=null) {
    //设置加载状态,让布局显示出来
    setLoading(true);
    mOnLoadListener.onLoad();
    }
    }
    /

    *设置加载状态,是否加载传入boolean值进行判断

    @paramloading
    /
    public voidsetLoading(booleanloading) {
    //修改当前的状态
    isLoading= loading;
    if(isLoading) {
    //显示布局
    mListView.addFooterView(mFooterView);
    }else{
    //隐藏布局
    mListView.removeFooterView(mFooterView);
    //重置滑动的坐标
    mDownY=0;
    mUpY=0;
    }
    }
    /

    上拉加载的接口回调
    /
    public interfaceOnLoadListener {
    voidonLoad();
    }
    public voidsetOnLoadListener(OnLoadListener listener) {
    this.mOnLoadListener= listener;
    }
    }
    使用:
    /

    *作者:hy on 2016/10/2 00:16
    邮箱: simoncqhy@163.com
    /
    public classCustomActivityextendsAppCompatActivity {
    privateListmList;
    private intmCount;
    privateStringAdaptermAdapter;
    @Override
    protected voidonCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_custom);
    finalSwipeRefreshView swipeRefreshView = (SwipeRefreshView) findViewById(R.id.srl);
    finalListView listView = (ListView) findViewById(R.id.lv);
    //设置适配器数据
    mList=newArrayList<>();
    for(inti =0; i <30; i++) {
    mList.add("我是天才"+ i +"号");
    mCount++;
    }
    mAdapter=newStringAdapter();
    listView.setAdapter(mAdapter);
    //不能在onCreate中设置,这个表示当前是刷新状态,如果一进来就是刷新状态,SwipeRefreshLayout会屏蔽掉下拉事件
    //swipeRefreshLayout.setRefreshing(true);
    //设置颜色属性的时候一定要注意是引用了资源文件还是直接设置16进制的颜色,因为都是int值容易搞混
    //设置下拉进度的背景颜色,默认就是白色的
    swipeRefreshView.setProgressBackgroundColorSchemeResource(android.R.color.white);
    //设置下拉进度的主题颜色
    swipeRefreshView.setColorSchemeResources(R.color.colorAccent, R.color.colorPrimary, R.color.colorPrimaryDark);
    //下拉时触发SwipeRefreshLayout的下拉动画,动画完毕之后就会回调这个方法
    swipeRefreshView.setOnRefreshListener(newSwipeRefreshLayout.OnRefreshListener() {
    @Override
    public voidonRefresh() {
    //开始刷新,设置当前为刷新状态
    //swipeRefreshLayout.setRefreshing(true);
    //这里是主线程
    //一些比较耗时的操作,比如联网获取数据,需要放到子线程去执行
    //TODO获取数据
    finalRandom random =newRandom();
    newHandler().postDelayed(newRunnable() {
    @Override
    public voidrun() {
    mList.add(0,"我是下拉天才"+random.nextInt(100) +"号");
    mAdapter.notifyDataSetChanged();
    Toast.makeText(CustomActivity.this,"刷新了一条数据", Toast.LENGTH_SHORT).show();
    //加载完数据设置为不刷新状态,将下拉进度收起来
    swipeRefreshView.setRefreshing(false);
    }
    },2000);
    }
    });
    //设置下拉加载更多
    swipeRefreshView.setOnLoadListener(newSwipeRefreshView.OnLoadListener() {
    @Override
    public voidonLoad() {
    newHandler().postDelayed(newRunnable() {
    @Override
    public voidrun() {
    //添加数据
    for(inti =30; i <35; i++) {
    mList.add("我是加载更多天才"+ i+"号");
    //这里要放在里面刷新,放在外面会导致刷新的进度条卡住
    mAdapter.notifyDataSetChanged();
    }
    Toast.makeText(CustomActivity.this,"加载了"+5+"条数据", Toast.LENGTH_SHORT).show();
    //加载完数据设置为不加载状态,将加载进度收起来
    swipeRefreshView.setLoading(false);
    }
    },2000);
    }
    });
    }
    /

    *适配器
    */
    private classStringAdapterextendsBaseAdapter {
    @Override
    public intgetCount() {
    returnmList.size();
    }
    @Override
    publicObject getItem(intposition) {
    returnmList.get(position);
    }
    @Override
    public longgetItemId(intposition) {
    returnposition;
    }
    @Override
    publicView getView(intposition, View convertView, ViewGroup parent) {
    if(convertView ==null) {
    convertView = View.inflate(CustomActivity.this, android.R.layout.simple_list_item_1,null);
    }
    TextView tv = (TextView) convertView;
    tv.setGravity(Gravity.CENTER);
    tv.setPadding(0,20,0,20);
    tv.setText(mList.get(position));
    returnconvertView;
    }
    }
    }
    源码下载地址
    百度云盘:
    http://pan.baidu.com/s/1eRU3mpG

    相关文章

      网友评论

          本文标题:Android的listview添加头和脚的另一种方式

          本文链接:https://www.haomeiwen.com/subject/uzldyttx.html