Android-自定义控件之ListView下拉刷新的实现

自定义控件学了很久了,发现学了总是忘,于是打算用博客来记录自己学习的知识点。

今天是自定义ListView来实现下拉刷新,这些文章都是借鉴慕课网上的视频来写的.

自定义一个控件,先是看它继承于那个控件,如果我们继承View控件的话,那得让我们写很多关于ListView的功能,这些东西我自己觉得很麻烦,而且也没有那个必要因为我们可以直接继承ListView,在listView的基础上来加一些我们需要的东西。

1.向ListView加Header布局

  private void initView(Context context)
  {
    mLayoutInflater = LayoutInflater.from(context);
    mHeaerView = mLayoutInflater.inflate(R.layout.header_layout, null, false);
    addHeaderView(mHeaerView);
  }

2.隐藏Header布局

private void initView(Context context) {
    mLayoutInflater = LayoutInflater.from(context);
    mHeaerView = mLayoutInflater.inflate(R.layout.header_layout, null, false);
    measureView(mHeaerView);
    mHeaderViewHeight = mHeaerView.getMeasuredHeight();
    setHeaderViewHeightPadding(mHeaderViewHeight);
    Log.i("main", mHeaderViewHeight + "");
    addHeaderView(mHeaerView);
  }
  private void measureView(View view)
  {
    ViewGroup.LayoutParams lp = view.getLayoutParams();
    if(lp == null)
    {
      lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
    }
    //mHeaerView.measure(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
    /**
     * width 和height里面包含的不仅仅有View的宽和高,还有View控件的测量模式
     * 测量模式的产生方式就是如下所示
     */
    int width = ViewGroup.getChildMeasureSpec(0,0,lp.width);
    int height = 0;
    int tempHeight = lp.height;
    if(tempHeight > 0)
    {
      height = MeasureSpec.makeMeasureSpec(tempHeight, MeasureSpec.EXACTLY);
    }
    view.measure(width, height);

  }
  private void setHeaderViewHeightPadding(int padding) {
    mHeaerView.setPadding(mHeaerView.getPaddingLeft(), -padding, mHeaerView.getPaddingRight(), mHeaerView.getPaddingBottom());
    mHeaerView.invalidate();
  }

3.实现ListView的下拉刷新(一)

要想实现ListView的下拉刷新,必须监听ListView是否滑动到最顶端,因此要实现ListView的监听接口OnScrollListener,并且要监听ListView的OnTouch事件。根据滑动的情况来判断刷新的情况。

首先我们在定义了一个成员变量来保存ListView的状态--mState

其次定义了几个静态常量来表示不同的状态

 private final static int NONE = 0; // 无状态
  private final static int DOWN_UPDATE = 1; // 提示下拉可以刷新
  private final static int UPDATE = 2; // 提示松开可以刷新
  private final static int REFLASH = 3; // 更新

最后则是根据不同的滑动来更改mState的状态

@Override
  public boolean onTouchEvent(MotionEvent ev) {

    switch (ev.getAction()) {
      case MotionEvent.ACTION_DOWN: {
        if (mFirstVisibleItem == 0) {
          mIsRemark = true; // mIsRemark只是一个标记,表示当前可见的第一个Item是不是所有的Item中的第一个
          mStartY = (int) ev.getY();
          Log.i("main", "我进来了");
        }
        break;
      }
      case MotionEvent.ACTION_MOVE: {
        onMove(ev);
        tempY = (int) (ev.getY() - mStartY);
        Log.i("main", "tempY = " + tempY);
        break;
      }
      case MotionEvent.ACTION_UP: {

        if(mState == DOWN_UPDATE)
        {
          mState = NONE;
        }
        if(mState == UPDATE)
        {
          mState = REFLASH;
          mListener.reFlash();
          Log.i("main", "我来了");
        }
        Log.i("main", "tempY11 = " + tempY);
        if(tempY <= 0 && mIsRemark)
        {
          Log.i("main", "我进来le");
          mState = NONE;
        }

        change();
        break;
      }
    }

    return super.onTouchEvent(ev);
  }

  private void onMove(MotionEvent ev) {
    if (mIsRemark) {
      if (ev.getY() - mStartY > 0) {
        int dy = (int) (ev.getY() - mStartY);
        if (dy > mHeaderViewHeight + 20) {
          mState = UPDATE;
        } else {
          mState = DOWN_UPDATE;
        }
        setHeaderViewHeightPadding(mHeaderViewHeight - dy);
        change();
      }
      return;
    }
    return;
  }
/**
 *change方法主要是用来处理不同状态下的事件
 *
 */
  private void change() {
    initChildView();
    RotateAnimation ani = new RotateAnimation(0, 180, RotateAnimation.RELATIVE_TO_SELF, 0.5f, RotateAnimation.RELATIVE_TO_SELF, 0.5f);
    ani.setDuration(500);
    ani.setFillAfter(true);
    RotateAnimation ani1 = new RotateAnimation(180, 0, RotateAnimation.RELATIVE_TO_SELF, 0.5f, RotateAnimation.RELATIVE_TO_SELF, 0.5f);
    ani1.setDuration(500);
    ani1.setFillAfter(true);
    if (mState == UPDATE)
    {
      mProgressBar.setVisibility(View.GONE);
      mImageView.setVisibility(View.VISIBLE);
      mImageView.clearAnimation();
      mImageView.setAnimation(ani);
      mTextViewFlash.setText("松开可以刷新!");
      mTextViewTime.setVisibility(View.VISIBLE);
      mTextViewTime.setText("上次更新的时间:" + mUpdateTime);
    }
    if (mState == DOWN_UPDATE)
    {
      mProgressBar.setVisibility(View.GONE);
      mImageView.setVisibility(View.VISIBLE);
      mTextViewTime.setVisibility(View.VISIBLE);
      mImageView.clearAnimation();
      mImageView.setAnimation(ani1);
      mTextViewFlash.setText("下拉可以刷新");
      mTextViewTime.setText("上次更新的时间:" + mUpdateTime);
    }
    if (mState == REFLASH)
    {
      setHeaderViewHeightPadding(10);
      mProgressBar.setVisibility(View.VISIBLE);
      mImageView.setVisibility(View.GONE);
      mTextViewTime.setVisibility(View.GONE);
      mTextViewFlash.setText("正在刷新...");
      mImageView.clearAnimation();
    }
    if(mState == NONE)
    {
      Log.i("main", "workspace");
      setHeaderViewHeightPadding(mHeaderViewHeight);
      mIsRemark = false;
      mProgressBar.setVisibility(View.GONE);
      mImageView.setVisibility(View.VISIBLE);
      mImageView.setAnimation(ani1);
    }
  }
  private void initChildView()
  {
    if(mTextViewFlash == null)
    {
      mTextViewFlash = (TextView) mHeaerView.findViewById(R.id.id_textView_Flash);
    }
    if(mTextViewTime == null)
    {
      mTextViewTime = (TextView) mHeaerView.findViewById(R.id.id_textView_Time);
    }
    if(mImageView == null)
    {
      mImageView = (ImageView) mHeaerView.findViewById(R.id.id_imagView);
    }
    if(mProgressBar == null)
    {
      mProgressBar = (ProgressBar) mHeaerView.findViewById(R.id.id_progressbar);
    }
  }

4.实现ListView的下拉刷新(二)

经过上面的过程,是可以下拉的,处理不同状态下的事件。还有一个问题就是刷新,也就是加载新的数据。加载刷新的操作肯定必须在UI线程中,因此ListView中必须得有一个回调接口,用来MinaActivity来实现,并且来进行一些操作。

回调接口:

  public void setOnFlashListener(FlashListener listener)
  {
    this.mListener = listener;
  }

  public interface FlashListener
  {
    void reFlash();
  }

回调接口的调用:

        if(mState == UPDATE)
        {
          mState = REFLASH;
          mListener.reFlash();
          Log.i("main", "我来了");
        }

MainActivity中回调接口的实现和接口方法的实现:

mListView.setOnFlashListener(new FlashListView.FlashListener() {
      @Override
      public void reFlash() {
        Handler handler = new Handler();
        handler.postDelayed(new Runnable() {
          @Override
          public void run() {
            addDatas();
            loadDatas();
            mListView.reFalshComplete();
          }
        }, 5000);
      }
    });

  

 private void addDatas()
  {
    int i = mDatas.size();
    for(int j = i; j < i + 10; j++)
    {
      mDatas.add(new Bean("Title" + j, "Content" + j, R.mipmap.ic_launcher));
    }
    myAdapter.dataChange(mDatas);
  }
  private void loadDatas()
  {
    mListView.setAdapter(myAdapter);
  }

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Android中ListView下拉刷新的实现代码

    Android中ListView下拉刷新 实现效果图: ListView中的下拉刷新是非常常见的,也是经常使用的,看到有很多同学想要,那我就整理一下,供大家参考.那我就不解释,直接上代码了. 这里需要自己重写一下ListView,重写代码如下: package net.loonggg.listview; import java.util.Date; import android.content.Context; import android.util.AttributeSet; import a

  • Android中Listview下拉刷新和上拉加载更多的多种实现方案

    listview经常结合下来刷新和上拉加载更多使用,本文总结了三种常用到的方案分别作出说明. 方案一:添加头布局和脚布局 android系统为listview提供了addfootview和addheadview两个API.这样可以直接自定义一个View,以添加视图的形式实现下来刷新和上拉加载. 实现步骤    1.创建一个类继承ListView:class PullToRefreshListView extends ListView: 2.在构造方法中添加HeadView:addHeaderVi

  • Android ListView实现上拉加载下拉刷新和滑动删除功能

    最近项目需要用到可以滑动删除并且带有上拉加载下拉刷新的Listview,查阅了一些资料,大多都是在SwipeMenuListView的基础上去添加头部和底部View,来扩展上拉加载和下拉刷新的功能,不过需要手动的去绘制UI及处理一些动画效果.用起来也不是特别方便.刚好项目中用到PulltorefreshLibrary库,就尝试着扩展了一个PullToRefreshSwipeMenuListView类来实现需求.先看一下效果: 实现步骤 一.组合Pulltorefresh与SwipeMenuLis

  • Android使用ListView实现下拉刷新及上拉显示更多的方法

    本文实例讲述了Android使用ListView实现下拉刷新及上拉显示更多的方法.分享给大家供大家参考,具体如下: 今天得需求是做listview+上下拉动在header和footer显示progressdialog,但不影响用户操作 直接上代码,我已经加上注释了,自己看. package com.stay.main; import java.net.HttpURLConnection; import java.util.ArrayList; import java.util.HashMap;

  • Android自定义listview布局实现上拉加载下拉刷新功能

    listview实现上拉加载以及下拉刷新的方式有很多.下面是我写的一种自定义的布局,复用性也比较的强.首先就是继承的listview的自定义view.   AutoListView.Java: package com.example.mic.testdemo.view; import android.annotation.TargetApi; import android.content.Context; import android.os.Build; import android.os.Bu

  • Android自定义渐变式炫酷ListView下拉刷新动画

    本文实例为大家分享了自定义渐变式炫酷动画的ListView下拉刷新,供大家参考,具体内容如下 主要要点 listview刷新过程中主要有三个步骤当前:状态为下拉刷新,当前状态为下拉刷新,当前状态为放开刷新,当前状态为正在刷新:主要思路为三个步骤分别对应三个自定义的view:即ibuRefreshFirstStepView,ibuRefreshSecondStepView,ibuRefreshThirdStepView. 效果图 ibuRefreshFirstStepView代码,例如: priv

  • Android自定义控件开发实战之实现ListView下拉刷新实例代码

    这篇博客为大家介绍一个android常见的功能--ListView下拉刷新: 首先下拉未松手时候手机显示这样的界面: 下面的代码是自定的扎样的控件: <span style="font-family: comic sans ms,sans-serif; font-size: 16px;">package com.dhsr.smartID.view; import android.content.Context; import android.util.AttributeSe

  • Android程序开发之Listview下拉刷新上拉(滑动分页)加载更多

    最近做的类似于微博的项目中,有个Android功能要使用到listview的向下拉刷新来刷新最新消息,向上拉刷新(滑动分页)来加载更多. 新浪微博就是使用这种方式的典型. 当用户从网络上读取微博的时候,如果一下子全部加载用户未读的微博这将耗费比较长的时间,造成不好的用户体验,同时一屏的内容也不足以显示如此多的内容.这时候,我们就需要用到另一个功能,那就是listview的分页了,其实这个分页可以做成客户端的分页,也可以做成服务器端的分页(点击加载时,从服务器对应的加载第N页就好了!!!).通过分

  • Android中ListView下拉刷新的实现方法实例分析

    本文实例讲述了Android中ListView下拉刷新的实现方法.分享给大家供大家参考,具体如下: ListView中的下拉刷新是非常常见的,也是经常使用的,看到有很多同学想要,那我就整理一下,供大家参考.那我就不解释,直接上代码了. 这里需要自己重写一下ListView,重写代码如下: package net.loonggg.listview; import java.util.Date; import android.content.Context; import android.util.

  • Android ListView下拉刷新上拉自动加载更多DEMO示例

    代码下载地址已经更新.因为代码很久没更新,已经很落伍了,建议大家使用RecyclerView实现. 参考项目: https://github.com/bingoogolapple/BGARefreshLayout-Android https://github.com/baoyongzhang/android-PullRefreshLayout 下拉刷新,Android中非常普遍的功能.为了方便便重写的ListView来实现下拉刷新,同时添加了上拉自动加载更多的功能.设计最初是参考开源中国的And

  • Android使用PullToRefresh完成ListView下拉刷新和左滑删除功能

    ListView下刷新刷功能相信从事Android开发的猿友们并不陌生,包括现在Google亲儿子SwipeRefreshLayout实现效果在一些APP上也能看见(不过个人不喜欢官方的刷新效果).本文就带领一些刚入门android的朋友或者一起爱分享的朋友来简单的实现ListView的下拉刷新和左滑删除效果. 一.本文主要内容: 使用PullToRefresh完成ListView下拉.上拉刷新: 扩展PullToRefresh完美的实现ListView左滑删除效果: 注意:本文中的PullTo

  • android使用PullToRefresh框架实现ListView下拉刷新上拉加载更多

    本文实例为大家分享了Android实现ListView下拉刷新上拉加载更多的具体代码,供大家参考,具体内容如下 其实谷歌官方目前已经推出ListView下拉刷新框架SwipeRefreshLayout,想了解的朋友可以点击 android使用SwipeRefreshLayout实现ListView下拉刷新上拉加载了解一下: 大家不难发现当你使用SwipeRefreshLayout下拉的时候布局文件不会跟着手势往下滑,而且想要更改这个缺陷好像非常不容易. 虽然SwipeRefreshLayout非

  • android使用SwipeRefreshLayout实现ListView下拉刷新上拉加载

    本文实例为大家分享了android实现ListView下拉刷新上拉加载的具体代码,供大家参考,具体内容如下 这次使用的是系统的SwipeRefreshLayout实现下拉刷新,和设置ListView的滑动监听判断是否滑动到最底部然后加载更多: 这个要比PullToRefreshListView简单很多,想PullToRefreshListView实现下拉刷新上拉加载的可以看这篇博客: android使用PullToRefresh框架实现ListView下拉刷新上拉加载更多 至于使用哪一种大家可以

随机推荐