Android中ListView下拉刷新的实现方法

Android中ListView下拉刷新的实现方法,第1张

概述ListView中的下拉刷新是非常常见的,也是经常使用的,看到有很多同学想要,那我就整理一下,供大家参考。那我就不解释,直接上代码了。

ListVIEw中的下拉刷新是非常常见的,也是经常使用的,看到有很多同学想要,那我就整理一下,供大家参考。那我就不解释,直接上代码了。


这里需要自己重写一下ListVIEw,重写代码如下:

package net.loonggg.ListvIEw;  import java.util.Date;  import androID.content.Context; import androID.util.AttributeSet; import androID.vIEw.LayoutInflater; import androID.vIEw.MotionEvent; import androID.vIEw.VIEw; import androID.vIEw.VIEwGroup; import androID.vIEw.animation.linearInterpolator; import androID.vIEw.animation.RotateAnimation; import androID.Widget.AbsListVIEw; import androID.Widget.AbsListVIEw.OnScrollListener; import androID.Widget.ImageVIEw; import androID.Widget.linearLayout; import androID.Widget.ListVIEw; import androID.Widget.Progressbar; import androID.Widget.TextVIEw;  public class MyListVIEw extends ListVIEw implements OnScrollListener {   private final static int RELEASE_To_REFRESH = 0;// 下拉过程的状态值  private final static int PulL_To_REFRESH = 1; // 从下拉返回到不刷新的状态值  private final static int REFRESHING = 2;// 正在刷新的状态值  private final static int DONE = 3;  private final static int LOADING = 4;   // 实际的padding的距离与界面上偏移距离的比例  private final static int RATIO = 3;  private LayoutInflater inflater;   // ListVIEw头部下拉刷新的布局  private linearLayout headerVIEw;  private TextVIEw lvheaderTipsTv;  private TextVIEw lvheaderLastUpdatedTv;  private ImageVIEw lvheaderArrowIv;  private Progressbar lvheaderProgressbar;   // 定义头部下拉刷新的布局的高度  private int headerContentHeight;   private RotateAnimation animation;  private RotateAnimation reverseAnimation;   private int startY;  private int state;  private boolean isBack;   // 用于保证startY的值在一个完整的touch事件中只被记录一次  private boolean isRecored;   private OnRefreshListener refreshListener;   private boolean isRefreshable;   public MyListVIEw(Context context) {   super(context);   init(context);  }   public MyListVIEw(Context context,AttributeSet attrs) {   super(context,attrs);   init(context);  }   private voID init(Context context) {   setCachecolorHint(context.getResources().getcolor(R.color.transparent));   inflater = LayoutInflater.from(context);   headerVIEw = (linearLayout) inflater.inflate(R.layout.lv_header,null);   lvheaderTipsTv = (TextVIEw) headerVIEw     .findVIEwByID(R.ID.lvheaderTipsTv);   lvheaderLastUpdatedTv = (TextVIEw) headerVIEw     .findVIEwByID(R.ID.lvheaderLastUpdatedTv);    lvheaderArrowIv = (ImageVIEw) headerVIEw     .findVIEwByID(R.ID.lvheaderArrowIv);   // 设置下拉刷新图标的最小高度和宽度   lvheaderArrowIv.setMinimumWIDth(70);   lvheaderArrowIv.setMinimumHeight(50);    lvheaderProgressbar = (Progressbar) headerVIEw     .findVIEwByID(R.ID.lvheaderProgressbar);   measureVIEw(headerVIEw);   headerContentHeight = headerVIEw.getMeasuredHeight();   // 设置内边距,正好距离顶部为一个负的整个布局的高度,正好把头部隐藏   headerVIEw.setpadding(0,-1 * headerContentHeight,0);   // 重绘一下   headerVIEw.invalIDate();   // 将下拉刷新的布局加入ListVIEw的顶部   addheaderVIEw(headerVIEw,null,false);   // 设置滚动监听事件   setonScrollListener(this);    // 设置旋转动画事件   animation = new RotateAnimation(0,-180,RotateAnimation.relative_TO_SELF,0.5f,0.5f);   animation.setInterpolator(new linearInterpolator());   animation.setDuration(250);   animation.setFillAfter(true);    reverseAnimation = new RotateAnimation(-180,0.5f);   reverseAnimation.setInterpolator(new linearInterpolator());   reverseAnimation.setDuration(200);   reverseAnimation.setFillAfter(true);    // 一开始的状态就是下拉刷新完的状态,所以为DONE   state = DONE;   // 是否正在刷新   isRefreshable = false;  }   @OverrIDe  public voID onScrollStateChanged(AbsListVIEw vIEw,int scrollState) {   }   @OverrIDe  public voID onScroll(AbsListVIEw vIEw,int firstVisibleItem,int visibleItemCount,int totalitemCount) {     if (firstVisibleItem == 0) {      isRefreshable = true;      } else {      isRefreshable = false;      }    }   @OverrIDe  public boolean ontouchEvent(MotionEvent ev) {   if (isRefreshable) {    switch (ev.getAction()) {    case MotionEvent.ACTION_DOWN:     if (!isRecored) {      isRecored = true;      startY = (int) ev.getY();// 手指按下时记录当前位置     }     break;    case MotionEvent.ACTION_UP:     if (state != REFRESHING && state != LOADING) {      if (state == PulL_To_REFRESH) {       state = DONE;       changeheaderVIEwByState();      }      if (state == RELEASE_To_REFRESH) {       state = REFRESHING;       changeheaderVIEwByState();       onLvRefresh();      }     }     isRecored = false;     isBack = false;      break;     case MotionEvent.ACTION_MOVE:     int tempY = (int) ev.getY();     if (!isRecored) {      isRecored = true;      startY = tempY;     }     if (state != REFRESHING && isRecored && state != LOADING) {      // 保证在设置padding的过程中,当前的位置一直是在head,否则如果当列表超出屏幕的话,当在上推的时候,列表会同时进行滚动      // 可以松手去刷新了      if (state == RELEASE_To_REFRESH) {       setSelection(0);       // 往上推了,推到了屏幕足够掩盖head的程度,但是还没有推到全部掩盖的地步       if (((tempY - startY) / RATIO < headerContentHeight)// 由松开刷新状态转变到下拉刷新状态         && (tempY - startY) > 0) {        state = PulL_To_REFRESH;        changeheaderVIEwByState();       }       // 一下子推到顶了       else if (tempY - startY <= 0) {// 由松开刷新状态转变到done状态        state = DONE;        changeheaderVIEwByState();       }      }      // 还没有到达显示松开刷新的时候,DONE或者是PulL_To_REFRESH状态      if (state == PulL_To_REFRESH) {       setSelection(0);       // 下拉到可以进入RELEASE_TO_REFRESH的状态       if ((tempY - startY) / RATIO >= headerContentHeight) {// 由done或者下拉刷新状态转变到松开刷新        state = RELEASE_To_REFRESH;        isBack = true;        changeheaderVIEwByState();       }       // 上推到顶了       else if (tempY - startY <= 0) {// 由DOne或者下拉刷新状态转变到done状态        state = DONE;        changeheaderVIEwByState();       }      }      // done状态下      if (state == DONE) {       if (tempY - startY > 0) {        state = PulL_To_REFRESH;        changeheaderVIEwByState();       }      }      // 更新headVIEw的size      if (state == PulL_To_REFRESH) {       headerVIEw.setpadding(0,-1 * headerContentHeight         + (tempY - startY) / RATIO,0);       }      // 更新headVIEw的paddingtop      if (state == RELEASE_To_REFRESH) {       headerVIEw.setpadding(0,(tempY - startY) / RATIO         - headerContentHeight,0);      }      }     break;     default:     break;    }   }   return super.ontouchEvent(ev);  }   // 当状态改变时候,调用该方法,以更新界面  private voID changeheaderVIEwByState() {   switch (state) {   case RELEASE_To_REFRESH:    lvheaderArrowIv.setVisibility(VIEw.VISIBLE);    lvheaderProgressbar.setVisibility(VIEw.GONE);    lvheaderTipsTv.setVisibility(VIEw.VISIBLE);    lvheaderLastUpdatedTv.setVisibility(VIEw.VISIBLE);     lvheaderArrowIv.clearanimation();// 清除动画    lvheaderArrowIv.startAnimation(animation);// 开始动画效果     lvheaderTipsTv.setText("松开刷新");    break;   case PulL_To_REFRESH:    lvheaderProgressbar.setVisibility(VIEw.GONE);    lvheaderTipsTv.setVisibility(VIEw.VISIBLE);    lvheaderLastUpdatedTv.setVisibility(VIEw.VISIBLE);    lvheaderArrowIv.clearanimation();    lvheaderArrowIv.setVisibility(VIEw.VISIBLE);    // 是由RELEASE_To_REFRESH状态转变来的    if (isBack) {     isBack = false;     lvheaderArrowIv.clearanimation();     lvheaderArrowIv.startAnimation(reverseAnimation);      lvheaderTipsTv.setText("下拉刷新");    } else {     lvheaderTipsTv.setText("下拉刷新");    }    break;    case REFRESHING:     headerVIEw.setpadding(0,0);     lvheaderProgressbar.setVisibility(VIEw.VISIBLE);    lvheaderArrowIv.clearanimation();    lvheaderArrowIv.setVisibility(VIEw.GONE);    lvheaderTipsTv.setText("正在刷新...");    lvheaderLastUpdatedTv.setVisibility(VIEw.VISIBLE);    break;   case DONE:    headerVIEw.setpadding(0,0);     lvheaderProgressbar.setVisibility(VIEw.GONE);    lvheaderArrowIv.clearanimation();    lvheaderArrowIv.setimageResource(R.drawable.arrow);    lvheaderTipsTv.setText("下拉刷新");    lvheaderLastUpdatedTv.setVisibility(VIEw.VISIBLE);    break;   }  }   // 此方法直接照搬自网络上的一个下拉刷新的demo,此处是“估计”headVIEw的wIDth以及height  private voID measureVIEw(VIEw child) {   VIEwGroup.LayoutParams params = child.getLayoutParams();   if (params == null) {    params = new VIEwGroup.LayoutParams(      VIEwGroup.LayoutParams.FILL_PARENT,VIEwGroup.LayoutParams.WRAP_CONTENT);   }   int chilDWIDthSpec = VIEwGroup.getChildMeasureSpec(0,0 + 0,params.wIDth);   int lpHeight = params.height;   int childHeightSpec;   if (lpHeight > 0) {    childHeightSpec = MeasureSpec.makeMeasureSpec(lpHeight,MeasureSpec.EXACTLY);   } else {    childHeightSpec = MeasureSpec.makeMeasureSpec(0,MeasureSpec.UnspecIFIED);   }   child.measure(chilDWIDthSpec,childHeightSpec);  }   public voID setonRefreshListener(OnRefreshListener refreshListener) {   this.refreshListener = refreshListener;   isRefreshable = true;  }   public interface OnRefreshListener {   public voID onRefresh();  }   public voID onRefreshComplete() {   state = DONE;   lvheaderLastUpdatedTv.setText("最近更新:" + new Date().tolocaleString());   changeheaderVIEwByState();  }   private voID onLvRefresh() {   if (refreshListener != null) {    refreshListener.onRefresh();   }  }   public voID setAdapter(LvAdapter adapter) {   lvheaderLastUpdatedTv.setText("最近更新:" + new Date().tolocaleString());   super.setAdapter(adapter);  }  } 

重写完ListVIEw之后,在布局文件中是这么使用的,头部下拉刷新的布局文件lv_header.xml代码如下:

<?xml version="1.0" enCoding="utf-8"?> <!-- ListVIEw的头部 --> <linearLayout xmlns:androID="http://schemas.androID.com/apk/res/androID"  androID:layout_wIDth="fill_parent"  androID:layout_height="wrap_content"  androID:background="#000000" >   <!-- 内容 -->   <relativeLayout   androID:ID="@+ID/head_contentLayout"   androID:layout_wIDth="fill_parent"   androID:layout_height="wrap_content"   androID:paddingleft="30dp" >    <!-- 箭头图像、进度条 -->    <FrameLayout    androID:layout_wIDth="wrap_content"    androID:layout_height="wrap_content"    androID:layout_alignParentleft="true"    androID:layout_centerVertical="true" >     <!-- 箭头 -->     <ImageVIEw     androID:ID="@+ID/lvheaderArrowIv"     androID:layout_wIDth="wrap_content"     androID:layout_height="wrap_content"     androID:layout_gravity="center"     androID:src="@drawable/arrow" />     <!-- 进度条 -->     <Progressbar     androID:ID="@+ID/lvheaderProgressbar"          androID:layout_wIDth="wrap_content"     androID:layout_height="wrap_content"     androID:layout_gravity="center"     androID:visibility="gone" />   </FrameLayout>    <!-- 提示、最近更新 -->    <linearLayout    androID:layout_wIDth="wrap_content"    androID:layout_height="wrap_content"    androID:layout_centerHorizontal="true"    androID:gravity="center_horizontal"    androID:orIEntation="vertical" >     <!-- 提示 -->     <TextVIEw     androID:ID="@+ID/lvheaderTipsTv"     androID:layout_wIDth="wrap_content"     androID:layout_height="wrap_content"     androID:text="下拉刷新"     androID:textcolor="@color/white"     androID:textSize="20sp" />     <!-- 最近更新 -->     <TextVIEw     androID:ID="@+ID/lvheaderLastUpdatedTv"     androID:layout_wIDth="wrap_content"     androID:layout_height="wrap_content"     androID:text="上次更新"     androID:textcolor="@color/gold"     androID:textSize="10sp" />   </linearLayout>  </relativeLayout>  </linearLayout> 

在Main.xml中进行设置,代码如下:

<?xml version="1.0" enCoding="utf-8"?> <linearLayout xmlns:androID="http://schemas.androID.com/apk/res/androID"  androID:layout_wIDth="fill_parent"  androID:layout_height="fill_parent"  androID:background="#000000"  androID:orIEntation="vertical" >   <net.loonggg.ListvIEw.MyListVIEw   androID:ID="@+ID/lv"   androID:layout_wIDth="fill_parent"   androID:layout_height="fill_parent" />  </linearLayout> 

然后就是在MainActivity中实现,代码如下:

package net.loonggg.ListvIEw;  import java.util.ArrayList; import java.util.List;  import net.loonggg.ListvIEw.MyListVIEw.OnRefreshListener; import androID.app.Activity; import androID.os.AsyncTask; import androID.os.Bundle; import androID.vIEw.VIEw;  public class MainActivity extends Activity {  private List<String> List;  private MyListVIEw lv;  private LvAdapter adapter;   @OverrIDe  protected voID onCreate(Bundle savedInstanceState) {   super.onCreate(savedInstanceState);   setContentVIEw(R.layout.activity_main);   lv = (MyListVIEw) findVIEwByID(R.ID.lv);   List = new ArrayList<String>();   List.add("loonggg");   List.add("我们都是开发者");   List.add("我们都是开发者");   List.add("我们都是开发者");   List.add("我们都是开发者");   List.add("我们都是开发者");   List.add("我们都是开发者");   List.add("我们都是开发者");   List.add("我们都是开发者");   List.add("我们都是开发者");   List.add("我们都是开发者");   List.add("我们都是开发者");   List.add("我们都是开发者");   List.add("我们都是开发者");   List.add("我们都是开发者");   List.add("我们都是开发者");   List.add("我们都是开发者");   adapter = new LvAdapter(List,this);   lv.setAdapter(adapter);    lv.setonRefreshListener(new OnRefreshListener() {     @OverrIDe    public voID onRefresh() {     new AsyncTask<VoID,VoID,VoID>() {      protected VoID doInBackground(VoID... params) {       try {        Thread.sleep(1000);       } catch (Exception e) {        e.printstacktrace();       }       List.add("刷新后添加的内容");       return null;      }       @OverrIDe      protected voID onPostExecute(VoID result) {       adapter.notifyDataSetChanged();       lv.onRefreshComplete();      }     }.execute(null,null);    }   });  } } 

这里还需要为ListVIEw设置一下Adapter,自定义的Adapter如下:

package net.loonggg.ListvIEw;  import java.util.List;  import androID.content.Context; import androID.vIEw.VIEw; import androID.vIEw.VIEwGroup; import androID.Widget.BaseAdapter; import androID.Widget.TextVIEw;  public class LvAdapter extends BaseAdapter {  private List<String> List;  private Context context;   public LvAdapter(List<String> List,Context context) {   this.List = List;   this.context = context;  }   @OverrIDe  public int getCount() {   return List.size();  }   @OverrIDe  public Object getItem(int position) {   return List.get(position);  }   @OverrIDe  public long getItemID(int position) {   return position;  }   @OverrIDe  public VIEw getVIEw(int position,VIEw convertVIEw,VIEwGroup parent) {   TextVIEw tv = new TextVIEw(context.getApplicationContext());   tv.setText(List.get(position));   return tv;  }  } 

如果想针对AndroID ListVIEw进行深入研究的同学,可以参考专题《Android listview使用方法汇总》。

到这里就完了,代码中的解释非常详细,具体的我就不多说了,也不解释了,自己看看并研究吧!

总结

以上是内存溢出为你收集整理的Android中ListView下拉刷新的实现方法全部内容,希望文章能够帮你解决Android中ListView下拉刷新的实现方法所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1141594.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-31
下一篇 2022-05-31

发表评论

登录后才能评论

评论列表(0条)

保存