关于在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 ;
}
}
|
以上给大家分享了几种比较常用的方法,服务器之家小编整理出来的,希望对大家有所帮助。