app开发中下拉刷新是最常接触到的一个功能,也有很多开源的框架,封装的非常棒。前段时间了解了一下VIEwDragHelper,遂用它实现了下拉刷新的功能。
大概和我之前的ViewDragHelper之拖动加载(类似淘宝)这篇代码类似。只是做了相关改动。具体的可以看一下那篇博文了解一下用到的VIEwDragHelper的一些知识点。该界面主要是一个linearLayout,上面的下拉刷新是一个textvIEw(用TV代替),当然这个可以定制,在此只是用一个textvIEw代替,实现简单的功能,下面是一个ListvIEw(用LV代替),当然ListvIEw也是可以定制的,可以使grIDvIEw或者其他你想要的都可以,在此也是只用ListvIEw代替。大概的讲讲吧:
首先,在onLayout中将TV置于屏幕上方,将LV充满屏幕;
上图中蓝色部分是整个手机的屏幕,红色部分是下拉提示TV。TV是置于屏幕之外的是不显示的。
@OverrIDe protected voID onLayout(boolean changed,int l,int t,int r,int b) { if (pullText.gettop() == 0) { vIEwHeight = pullText.getMeasuredHeight(); pullText.layout(l,r,b); myList.layout(l,b); pullText.offsettopAndBottom(-vIEwHeight); } else { pullText.layout(l,pullText.gettop(),pullText.getBottom()); myList.layout(l,myList.gettop(),myList.getBottom()); } }
上面的代码段中,pullText即是TV,myList是LV。这样在下拉LV的时候,TV就会跟着往下走,所以就会出现在屏幕中实现我们想要的效果。
/** * 这是拖拽效果的主要逻辑 */ private class DragHelperCallback extends VIEwDragHelper.Callback { @OverrIDe public voID onVIEwpositionChanged(VIEw changedVIEw,int left,int top,int dx,int dy) { int childindex = 1; if (changedVIEw == myList) { childindex = 2; } onVIEwPosChanged(childindex,top); } @OverrIDe public boolean tryCaptureVIEw(VIEw child,int pointerID) { return true; } @OverrIDe public int getVIEwVerticalDragRange(VIEw child) { return 1; } @OverrIDe public voID onVIEwReleased(VIEw releasedChild,float xvel,float yvel) { refreshOrNot(releasedChild,yvel); } @OverrIDe public int clampVIEwpositionVertical(VIEw child,int dy) { int finaltop = top; if (child == pullText) { if (top > 0) { finaltop = 0; } } else if (child == myList) { if (top < 0) { finaltop = 0; } if(top >= vIEwHeight){ pullText.setText("松开刷新"); }else{ pullText.setText("下拉刷新"); } } return child.gettop() + (finaltop - child.gettop()) / 2; } }
上面的代码段中,主要是在clampVIEwpositionVertical中判断滑动的位置,作用的子vIEw。其他就不多说了,大致和之前的博客相同。主要说说onVIEwReleased吧。在此函数中是在用户手势抬起时响应的,所以我们在此实现下拉后的刷新。我们先定义一个接口,以便在刷新的时候调用。
public interface pulltorefreshNotifIEr { public voID onPull(); }
public voID setpulltorefreshNotifIEr(pulltorefreshNotifIEr pullNotifIEr) { this.pullNotifIEr = pullNotifIEr; }
private voID refreshOrNot(VIEw releasedChild,float yvel) { int finaltop = 0; if (releasedChild == pullText) { // 拖动第一个vIEw松手 if (yvel < -50) { finaltop = 0; } else { finaltop = vIEwHeight; } } else { // 拖动第二个vIEw松手 if (yvel > vIEwHeight - 5 || releasedChild.gettop() >= vIEwHeight) { finaltop = vIEwHeight; if (null != pullNotifIEr) { pullNotifIEr.onPull(); } pullText.setText("正在刷新"); } } if (VDH.smoothSlIDeVIEwTo(myList,finaltop)) { VIEwCompat.postInvalIDateOnAnimation(this); } }
拖动第二个vIEw时,也就是LV时,我们判断一下是否需要刷新,需要刷新则执行onPull();
然后我们来看一下主要的Activity:
package com.maxi.pulltorefreshtest; import androID.annotation.Suppresslint; import androID.app.Activity; import androID.os.Bundle; import androID.os.Handler; import androID.os.Message; import com.maxi.pulltorefreshtest.adapter.ProjectAdapter; import com.maxi.pulltorefreshtest.Widget.MyListVIEw; import com.maxi.pulltorefreshtest.Widget.PullToRefreshGroup; import com.maxi.pulltorefreshtest.Widget.PullToRefreshGroup.pulltorefreshNotifIEr; public class MainActivity extends Activity { private PullToRefreshGroup pullListgroup; private boolean isDown = false; private MyListVIEw myList; private ProjectAdapter pa; @OverrIDe protected voID onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentVIEw(R.layout.activity_main); findVIEw(); init(); } private voID findVIEw() { pullListgroup = (PullToRefreshGroup) findVIEwByID(R.ID.pulltorefresh); myList = pullListgroup.returnMyList(); } private voID init() { pulltorefreshNotifIEr pullNotifIEr = new pulltorefreshNotifIEr() { @OverrIDe public voID onPull() { // Todo auto-generated method stub downLoad(); } }; pullListgroup.setpulltorefreshNotifIEr(pullNotifIEr); pa = new ProjectAdapter(this); myList.setAdapter(pa); pa.notifyDataSetChanged(); } private voID downLoad() { if (!isDown) { isDown = true; new Thread(new Runnable() { @OverrIDe public voID run() { // Todo auto-generated method stub try { Thread.sleep(2000); handler.sendEmptyMessage(1); } catch (InterruptedException e) { // Todo auto-generated catch block e.printstacktrace(); } } }).start(); } } @Suppresslint("HandlerLeak") private Handler handler = new Handler() { @OverrIDe public voID handleMessage(Message msg) { // Todo auto-generated method stub super.handleMessage(msg); switch (msg.what) { case 1: pullListgroup.refreshComplete(); isDown = false; break; default: break; } } }; }
我们在他刷新的时候执行downLoad();刷新数据。为了达到效果可以看出我让线程暂停2s。然后调用refreshComplete();
public voID refreshComplete() { if (VDH.smoothSlIDeVIEwTo(myList,0)) { VIEwCompat.postInvalIDateOnAnimation(this); } }
实现刷新好后让TV继续返回屏幕上方。
上段代码中我们发现MyListVIEw是重写的ListVIEw,主要是处理手势事件的。
package com.maxi.pulltorefreshtest.Widget; import androID.content.Context; import androID.util.AttributeSet; import androID.vIEw.MotionEvent; import androID.vIEw.VIEw; import androID.Widget.ListVIEw; public class MyListVIEw extends ListVIEw { boolean allowDragBottom = true; float downY = 0; boolean needConsumetouch = true; public MyListVIEw(Context context){ super(context); } public MyListVIEw(Context context,AttributeSet attrs) { super(context,attrs); // Todo auto-generated constructor stub } @OverrIDe public boolean dispatchtouchEvent(MotionEvent ev) { if (ev.getAction() == MotionEvent.ACTION_DOWN) { downY = ev.getRawY(); needConsumetouch = true; if (getMyScrollY() == 0) { allowDragBottom = true; } else { allowDragBottom = false; } } else if (ev.getAction() == MotionEvent.ACTION_MOVE) { if (!needConsumetouch) { getParent().requestdisallowIntercepttouchEvent(false); return false; } else if (allowDragBottom) { if (downY - ev.getRawY() < -2) { needConsumetouch = false; getParent().requestdisallowIntercepttouchEvent(false); return false; } } } getParent().requestdisallowIntercepttouchEvent(needConsumetouch); return super.dispatchtouchEvent(ev); } public int getMyScrollY() { VIEw c = getChildAt(0); if (c == null) { return 0; } int firstVisibleposition = getFirstVisibleposition(); int top = c.gettop(); return -top + firstVisibleposition * c.getHeight(); } }
ok。先这样吧。像上拉加载更多,我感觉也可以这么实现。有时间试试吧,大家有时间也可以动动手试试。
好吧。大致就这些,有疑问或建议请留言,共同进步,谢谢!
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程小技巧。
总结以上是内存溢出为你收集整理的Android自定义控件实现下拉刷新效果全部内容,希望文章能够帮你解决Android自定义控件实现下拉刷新效果所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)