Android 自定义弹性ListView控件实例代码(三种方法)
关于在Android中实现ListView的弹性效果,有很多不同的方法,网上一搜,也有很多,下面贴出在项目中经常用到的两种实现ListView弹性效果的方法(基本上拿来就可以用),供大家参考:
弹性ListView
第一种方法:
importandroid.content.Context;
importandroid.content.res.Configuration;
importandroid.util.AttributeSet;
importandroid.util.DisplayMetrics;
importandroid.view.View;
importandroid.view.ViewConfiguration;
importandroid.widget.ListView;
importjava.lang.reflect.Field;
importjava.lang.reflect.Modifier;
/**
*CreatedbyNoahon2016/1/16.
*/
publicclassBounceListViewextendsListView{
privatestaticfinalfloatMAX_Y_OVERSCROLL_DISTANCE=200;
privatefloatmMaxYOverscrollDistance;
publicBounceListView(Contextcontext){
this(context,null);
}
publicBounceListView(Contextcontext,AttributeSetattrs){
this(context,attrs,0);
}
publicBounceListView(Contextcontext,AttributeSetattrs,intdefStyleAttr){
super(context,attrs,defStyleAttr);
initBounceListView();
}
privatevoidinitBounceListView(){
finalDisplayMetricsmetrics=getContext().getResources().getDisplayMetrics();
finalfloatdensity=metrics.density;
mMaxYOverscrollDistance=(int)(density*MAX_Y_OVERSCROLL_DISTANCE);
}
@Override
protectedbooleanoverScrollBy(intdeltaX,intdeltaY,intscrollX,intscrollY,intscrollRangeX,intscrollRangeY,intmaxOverScrollX,intmaxOverScrollY,booleanisTouchEvent){
returnsuper.overScrollBy(deltaX,deltaY,scrollX,scrollY,scrollRangeX,scrollRangeY,maxOverScrollX,(int)mMaxYOverscrollDistance,isTouchEvent);
}
/**
*设置本App所有的ListView弹性粒度
*@paramctx
*@paramsize
*@return
*/
publicbooleanconfigGlobalMaxOverScrollDistance(Contextctx,intsize)
{
try{
finalDisplayMetricsmetrics=ctx.getResources().getDisplayMetrics();
finalfloatdensity=metrics.density;
intvalue=(int)(density*size);
mMaxYOverscrollDistance=value;
ViewConfigurationconfig=ViewConfiguration.get(ctx);
FieldmOverscrollDistance=ViewConfiguration.class.getDeclaredField("mOverscrollDistance");
if(!mOverscrollDistance.isAccessible()||!Modifier.isPublic(mOverscrollDistance.getModifiers()))
{
mOverscrollDistance.setAccessible(true);
}
mOverscrollDistance.setInt(config,value);
}catch(Exceptione){
e.printStackTrace();
returnfalse;
}
returntrue;
}
}
第二种比较简单,好容易理解,只是动态改变了ListView在Y轴上的可移动距离,代码如下:
importandroid.content.Context;
importandroid.util.AttributeSet;
importandroid.util.DisplayMetrics;
importandroid.widget.ListView;
/**
*弹性ListView。
*@authorE
*/
publicclassFlexiListViewextendsListView{
//初始可拉动Y轴方向距离
privatestaticfinalintMAX_Y_OVERSCROLL_DISTANCE=100;
//上下文环境
privateContextmContext;
//实际可上下拉动Y轴上的距离
privateintmMaxYOverscrollDistance;
publicFlexiListView(Contextcontext){
super(context);
mContext=context;
initBounceListView();
}
publicFlexiListView(Contextcontext,AttributeSetattrs){
super(context,attrs);
mContext=context;
initBounceListView();
}
publicFlexiListView(Contextcontext,AttributeSetattrs,intdefStyle){
super(context,attrs,defStyle);
mContext=context;
initBounceListView();
}
privatevoidinitBounceListView(){
finalDisplayMetricsmetrics=mContext.getResources().getDisplayMetrics();
finalfloatdensity=metrics.density;
mMaxYOverscrollDistance=(int)(density*MAX_Y_OVERSCROLL_DISTANCE);
}
@Override
protectedbooleanoverScrollBy(intdeltaX,intdeltaY,intscrollX,intscrollY,intscrollRangeX,
intscrollRangeY,intmaxOverScrollX,intmaxOverScrollY,booleanisTouchEvent){
//实现的本质就是在这里动态改变了maxOverScrollY的值
returnsuper.overScrollBy(deltaX,deltaY,scrollX,scrollY,scrollRangeX,scrollRangeY,maxOverScrollX,mMaxYOverscrollDistance,isTouchEvent);
}
}
第三种方法,结合了手势来实现ListView的弹性效果,这里可以根据手势来进行更多的扩展,代码如下:
importandroid.content.Context;
importandroid.graphics.Rect;
importandroid.util.AttributeSet;
importandroid.view.GestureDetector;
importandroid.view.GestureDetector.OnGestureListener;
importandroid.view.MotionEvent;
importandroid.view.View;
importandroid.view.animation.TranslateAnimation;
importandroid.widget.ListView;
/**
*具有弹性效果的ListView。主要是实现父类dispatchTouchEvent方法和OnGestureListener中onScroll方法。
*@authorE
*/
publicclassFlexibleListViewextendsListViewimplementsOnGestureListener{
privateContextcontext=null;
privatebooleanoutBound=false;
privateintdistance;
privateintfirstOut;
publicFlexibleListView(Contextcontext,AttributeSetattrs){
super(context,attrs);
this.context=context;
}
publicFlexibleListView(Contextcontext,AttributeSetattrs,intdefStyle){
super(context,attrs,defStyle);
this.context=context;
}
publicFlexibleListView(Contextcontext){
super(context);
this.context=context;
}
GestureDetectorlisGestureDetector=newGestureDetector(context,this);
@Override
publicbooleandispatchTouchEvent(MotionEventevent){
intact=event.getAction();
if((act==MotionEvent.ACTION_UP||act==MotionEvent.ACTION_CANCEL)
&&outBound){
outBound=false;
//scrollback
}
if(!lisGestureDetector.onTouchEvent(event)){
outBound=false;
}else{
outBound=true;
}
Rectrect=newRect();
getLocalVisibleRect(rect);
TranslateAnimationam=newTranslateAnimation(0,0,-rect.top,0);
am.setDuration(300);
startAnimation(am);
scrollTo(0,0);
returnsuper.dispatchTouchEvent(event);
}
@Override
publicbooleanonDown(MotionEvente){
returnfalse;
}
@Override
publicvoidonShowPress(MotionEvente){
}
@Override
publicbooleanonSingleTapUp(MotionEvente){
returnfalse;
}
@Override
publicbooleanonScroll(MotionEvente1,MotionEvente2,floatdistanceX,
floatdistanceY){
intfirstPos=getFirstVisiblePosition();
intlastPos=getLastVisiblePosition();
intitemCount=getCount();
//outboundTop
if(outBound&&firstPos!=0&&lastPos!=(itemCount-1)){
scrollTo(0,0);
returnfalse;
}
ViewfirstView=getChildAt(firstPos);
if(!outBound)
firstOut=(int)e2.getRawY();
if(firstView!=null&&(outBound||(firstPos==0
&&firstView.getTop()==0&&distanceY<0))){
//Recordthelengthofeachslide
distance=firstOut-(int)e2.getRawY();
scrollTo(0,distance/2);
returntrue;
}
//outboundBottom
returnfalse;
}
@Override
publicvoidonLongPress(MotionEvente){
}
@Override
publicbooleanonFling(MotionEvente1,MotionEvente2,floatvelocityX,
floatvelocityY){
returnfalse;
}
}
以上给大家分享了几种比较常用的方法,毛票票小编整理出来的,希望对大家有所帮助。