关于在Android中实现ListView的弹性效果,有很多不同的方法,网上一搜,也有很多,下面贴出在项目中经常用到的两种实现ListView弹性效果的方法(基本上拿来就可以用),供大家参考:
弹性ListView
第一种方法:
import android.content.Context; import android.content.res.Configuration; import android.util.AttributeSet; import android.util.DisplayMetrics; import android.view.View; import android.view.ViewConfiguration; import android.widget.ListView; import java.lang.reflect.Field; import java.lang.reflect.Modifier; /** * Created by Noah on 2016/1/16. */ public class BounceListView extends ListView { private static final float MAX_Y_OVERSCROLL_DISTANCE = 200; private float mMaxYOverscrollDistance; public BounceListView(Context context) { this(context,null); } public BounceListView(Context context,AttributeSet attrs) { this(context,attrs,0); } public BounceListView(Context context,AttributeSet attrs,int defStyleAttr) { super(context,defStyleAttr); initBounceListView(); } private void initBounceListView(){ final DisplayMetrics metrics = getContext().getResources().getDisplayMetrics(); final float density = metrics.density; mMaxYOverscrollDistance = (int) (density * MAX_Y_OVERSCROLL_DISTANCE); } @Override protected boolean overScrollBy(int deltaX,int deltaY,int scrollX,int scrollY,int scrollRangeX,int scrollRangeY,int maxOverScrollX,int maxOverScrollY,boolean isTouchEvent) { return super.overScrollBy(deltaX,deltaY,scrollX,scrollY,scrollRangeX,scrollRangeY,maxOverScrollX,(int)mMaxYOverscrollDistance,isTouchEvent); } /** * 设置本App所有的ListView弹性粒度 * @param ctx * @param size * @return */ public boolean configGlobalMaxOverScrollDistance(Context ctx,int size) { try { final DisplayMetrics metrics = ctx.getResources().getDisplayMetrics(); final float density = metrics.density; int value = (int) (density * size); mMaxYOverscrollDistance = value; ViewConfiguration config = ViewConfiguration.get(ctx); Field mOverscrollDistance = ViewConfiguration.class.getDeclaredField("mOverscrollDistance"); if(!mOverscrollDistance.isAccessible() || !Modifier.isPublic(mOverscrollDistance.getModifiers())) { mOverscrollDistance.setAccessible(true); } mOverscrollDistance.setInt(config,value); } catch (Exception e) { e.printStackTrace(); return false; } return true; } }
第二种比较简单,好容易理解,只是动态改变了ListView在Y轴上的可移动距离,代码如下:
import android.content.Context; import android.util.AttributeSet; import android.util.DisplayMetrics; import android.widget.ListView; /** * 弹性ListView。 * @author E */ public class FlexiListView extends ListView{ //初始可拉动Y轴方向距离 private static final int MAX_Y_OVERSCROLL_DISTANCE = 100; //上下文环境 private Context mContext; //实际可上下拉动Y轴上的距离 private int mMaxYOverscrollDistance; public FlexiListView(Context context){ super(context); mContext = context; initBounceListView(); } public FlexiListView(Context context,AttributeSet attrs) { super(context,attrs); mContext = context; initBounceListView(); } public FlexiListView(Context context,int defStyle) { super(context,defStyle); mContext = context; initBounceListView(); } private void initBounceListView(){ final DisplayMetrics metrics = mContext.getResources().getDisplayMetrics(); final float density = metrics.density; mMaxYOverscrollDistance = (int) (density * MAX_Y_OVERSCROLL_DISTANCE); } @Override protected boolean overScrollBy(int deltaX,boolean isTouchEvent) { //实现的本质就是在这里动态改变了maxOverScrollY的值 return super.overScrollBy(deltaX,mMaxYOverscrollDistance,isTouchEvent); } }
第三种方法,结合了手势来实现ListView的弹性效果,这里可以根据手势来进行更多的扩展,代码如下:
import android.content.Context; import android.graphics.Rect; import android.util.AttributeSet; import android.view.GestureDetector; import android.view.GestureDetector.OnGestureListener; import android.view.MotionEvent; import android.view.View; import android.view.animation.TranslateAnimation; import android.widget.ListView; /** * 具有弹性效果的ListView。主要是实现父类dispatchTouchEvent方法和OnGestureListener中onScroll方法。 * @author E */ public class FlexibleListView extends ListView implements OnGestureListener{ private Context context = null; private boolean outBound = false; private int distance; private int firstOut; public FlexibleListView(Context context,attrs); this.context = context; } public FlexibleListView(Context context,defStyle); this.context = context; } public FlexibleListView(Context context) { super(context); this.context = context; } GestureDetector lisGestureDetector = new GestureDetector(context,this); @Override public boolean dispatchTouchEvent(MotionEvent event) { int act = event.getAction(); if ((act == MotionEvent.ACTION_UP || act == MotionEvent.ACTION_CANCEL) && outBound) { outBound = false; // scroll back } if (!lisGestureDetector.onTouchEvent(event)) { outBound = false; } else { outBound = true; } Rect rect = new Rect(); getLocalVisibleRect(rect); TranslateAnimation am = new TranslateAnimation( 0,-rect.top,0); am.setDuration(300); startAnimation(am); scrollTo(0,0); return super.dispatchTouchEvent(event); } @Override public boolean onDown(MotionEvent e) { return false; } @Override public void onShowPress(MotionEvent e) { } @Override public boolean onSingleTapUp(MotionEvent e) { return false; } @Override public boolean onScroll(MotionEvent e1,MotionEvent e2,float distanceX,float distanceY) { int firstPos = getFirstVisiblePosition(); int lastPos = getLastVisiblePosition(); int itemCount = getCount(); // outbound Top if (outBound && firstPos != 0 && lastPos != (itemCount - 1)) { scrollTo(0,0); return false; } View firstView = getChildAt(firstPos); if (!outBound) firstOut = (int) e2.getRawY(); if (firstView != null&& (outBound || (firstPos == 0 && firstView.getTop() == 0 && distanceY < 0))) { // Record the length of each slide distance = firstOut - (int) e2.getRawY(); scrollTo(0,distance / 2); return true; } // outbound Bottom return false; } @Override public void onLongPress(MotionEvent e) { } @Override public boolean onFling(MotionEvent e1,float velocityX,float velocityY) { return false; } }
以上给大家分享了几种比较常用的方法,编程小技巧小编整理出来的,希望对大家有所帮助。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。