Android 自定义弹性ListView控件实例代码(三种方法)

时间:2021-05-21

关于在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, attrs, defStyleAttr);initBounceListView();}private void initBounceListView(){final DisplayMetrics metrics = getContext().getResources().getDisplayMetrics();final float density = metrics.density;mMaxYOverscrollDistance = (int) (density * MAX_Y_OVERSCROLL_DISTANCE);}@Overrideprotected 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, AttributeSet attrs, int defStyle) { super(context, attrs, 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, int deltaY, int scrollX, int scrollY, int scrollRangeX, int scrollRangeY, int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) { //实现的本质就是在这里动态改变了maxOverScrollY的值 return super.overScrollBy(deltaX, deltaY, scrollX, scrollY, scrollRangeX, scrollRangeY, maxOverScrollX, 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, AttributeSet attrs) { super(context, attrs); this.context = context; } public FlexibleListView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, 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, 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, MotionEvent e2, float velocityX, float velocityY) { return false; } }

以上给大家分享了几种比较常用的方法,小编整理出来的,希望对大家有所帮助。

声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。

相关文章