SoFunction
Updated on 2025-04-07

Android custom elastic ListView control instance code (three methods)

There are many different methods for implementing the elastic effect of ListView in Android. There are also many searches online. The following posts are two methods of implementing the elastic effect of ListView that are often used in projects (basically you can use it) for your reference:

Elastic ListView

The first method:

import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
/**
* 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 = ;
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 (deltaX, deltaY, scrollX, scrollY, scrollRangeX, scrollRangeY, maxOverScrollX, (int)mMaxYOverscrollDistance, isTouchEvent);
}
/**
 * Set the elastic granularity of all ListViews in this App
 * @param ctx
 * @param size
 * @return
 */
public boolean configGlobalMaxOverScrollDistance(Context ctx,int size)
{
try {
final DisplayMetrics metrics = ().getDisplayMetrics();
final float density = ;
int value = (int) (density * size);
mMaxYOverscrollDistance = value;
ViewConfiguration config = (ctx);
Field mOverscrollDistance = ("mOverscrollDistance");
if(!() || !(()))
{
(true);
}
(config,value);
} catch (Exception e) {
();
return false;
}
return true;
}
}

The second type is relatively simple and easy to understand, but it dynamically changes the movable distance of ListView on the Y axis. The code is as follows:

import ; 
import ; 
import ; 
import ; 
/**
 * Elastic ListView. 
 * @author E
 */ 
public class FlexiListView extends ListView{ 
//The Y-axis direction distance can be pulled initiallyprivate static final int MAX_Y_OVERSCROLL_DISTANCE = 100; 
//Context environmentprivate Context mContext; 
//The distance on the Y axis can be pulled up and downprivate 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 = ().getDisplayMetrics(); 
final float 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) { 
//The essence of implementation is that the value of maxOverScrollY is dynamically changed herereturn (deltaX, deltaY, scrollX, scrollY, scrollRangeX, scrollRangeY, maxOverScrollX, mMaxYOverscrollDistance, isTouchEvent); 
} 
}

The third method combines gestures to achieve the elastic effect of ListView. Here you can expand more based on gestures. The code is as follows:

import ; 
import ; 
import ; 
import ; 
import ; 
import ; 
import ; 
import ; 
import ; 
/**
 * ListView with elastic effect.  It mainly implements the parent class dispatchTouchEvent method and the onScroll method in OnGestureListener. 
 * @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); 
 = context; 
} 
public FlexibleListView(Context context, AttributeSet attrs, int defStyle) { 
super(context, attrs, defStyle); 
 = context; 
} 
public FlexibleListView(Context context) { 
super(context); 
 = context; 
} 
GestureDetector lisGestureDetector = new GestureDetector(context, this); 
@Override 
public boolean dispatchTouchEvent(MotionEvent event) { 
int act = (); 
if ((act == MotionEvent.ACTION_UP || act == MotionEvent.ACTION_CANCEL) 
&& outBound) { 
outBound = false; 
// scroll back 
} 
if (!(event)) { 
outBound = false; 
} else { 
outBound = true; 
} 
Rect rect = new Rect(); 
getLocalVisibleRect(rect); 
TranslateAnimation am = new TranslateAnimation( 0, 0, -, 0); 
(300); 
startAnimation(am); 
scrollTo(0, 0); 
return (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) (); 
if (firstView != null&& (outBound || (firstPos == 0 
&& () == 0 && distanceY < 0))) { 
// Record the length of each slide 
distance = firstOut - (int) (); 
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; 
} 
}