关于在Android中实现ListView的弹性效果,有很多不同的方法,网上一搜,也有很多,下面贴出在项目中经常用到的两种实现ListView弹性效果的方法(基本上拿来就可以用),供大家参考:
弹性ListView
第一种方法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
|
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); } @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轴上的可移动距离,代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
|
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的弹性效果,这里可以根据手势来进行更多的扩展,代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
|
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 ; } } |
以上给大家分享了几种比较常用的方法,服务器之家小编整理出来的,希望对大家有所帮助。