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

关于在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); } @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轴上的可移动距离,代码如下:

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; } }

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

时间: 2024-11-28 16:15:35

Android 自定义弹性ListView控件实例代码(三种方法)的相关文章

Jquery获得控件值的三种方法

 本篇文章主要是对Jquery获得控件值的三种方法进行了详细的总结介绍,需要的朋友可以过来参考下,希望对大家有所帮助 一 Jquery获得服务器控件值的方法 由于ASP.NET网页运行后,服务器控件会随机生成客户端id,jquery获取时候不太好操作,google了下,总结有以下3种方法:   服务器控件代码:<asp:TextBox ID="txtUserID" runat="server"></asp:TextBox>    1. $(&

Android实现滑动选择控件实例代码

前言 最近做了个滑动选择的小控件,拿出来给大家分享一下,先上图 运行效果 实现步骤 这里分解为3个动作:Down.Move.Up来进行分析,博主文采不好,大家直接看流程图吧!! 代码分析 前置知识 1.这个地方使用的是RecyclerView的代码,使用RecyclerView只能使用LinearLayoutManager,ListView的运行效果稍微要比RecyclerView差一些 //这里使用dispatchTouchEvent,因为onTouchEvent容易被OnTouchListe

浅谈Android开发中ListView控件性能的一些优化方法

ListView优化一直是一个老生常谈的问题,不管是面试还是平常的开发中,ListView永远不会被忽略掉,那么这篇文章我们来看看如何最大化的优化ListView的性能. 1.在adapter中的getView方法中尽量少使用逻辑 2.尽最大可能避免GC 3.滑动的时候不加载图片 4.将ListView的scrollingCache和animateCache设置为false 5.item的布局层级越少越好 6.使用ViewHolder 下面就具体来看一些 1.在adapter中的getView方

Android设置控件阴影的三种方法

本文实例为大家分享了Android设置控件阴影的方法,供大家参考,具体内容如下 第一种方式:elevation View的大小位置都是通过x,y确定的,而现在有了z轴的概念,而这个z值就是View的高度(elevation),而高度决定了阴影(shadow)的大小. View Elevation(视图高度) View的z值由两部分组成,elevation和translationZ(它们都是Android L新引入的属性). eleavation是静态的成员,translationZ是用来做动画.

android获取屏幕宽高与获取控件宽高(三种方法)

1.获取屏幕宽高 方法1: int screenWidth = getWindowManager().getDefaultDisplay().getWidth(); // 屏幕宽(像素,如:480px) int screenHeight = getWindowManager().getDefaultDisplay().getHeight(); // 屏幕高(像素,如:800p) Log.e(TAG + " getDefaultDisplay", "screenWidth=&q

Jquery获得控件值的三种方法总结_jquery

一 Jquery获得服务器控件值的方法由于ASP.NET网页运行后,服务器控件会随机生成客户端id,jquery获取时候不太好操作,google了下,总结有以下3种方法: 服务器控件代码:<asp:TextBox ID="txtUserID" runat="server"></asp:TextBox> 1. $("#<%=txtUserID.ClientID%>").val(); 2. $("inpu

Android 底部导航控件实例代码_Android

一.先给大家展示下最终效果 通过以上可以看到,图一是简单的使用,图二.图三中为结合ViewPager共同使用,而且都可以随ViewPager的滑动渐变色,不同点是图二为选中非选中两张图片,图三的选中非选中是一张图片只是做了颜色变化. 二. 需求 我们希望做可以做成这样的,可以在xml布局中引入控件并绑定数据,在代码中设置监听回调,并且配置使用要非常简单! 三.需求分析 根据我们多年做不明确需求项目的经验,以上需求还算明确.那么我们可以采用在LinearLayout添加子View控件,这个子Vie

Android 底部导航控件实例代码

一.先给大家展示下最终效果 通过以上可以看到,图一是简单的使用,图二.图三中为结合ViewPager共同使用,而且都可以随ViewPager的滑动渐变色,不同点是图二为选中非选中两张图片,图三的选中非选中是一张图片只是做了颜色变化. 二. 需求 我们希望做可以做成这样的,可以在xml布局中引入控件并绑定数据,在代码中设置监听回调,并且配置使用要非常简单! 三.需求分析 根据我们多年做不明确需求项目的经验,以上需求还算明确.那么我们可以采用在LinearLayout添加子View控件,这个子Vie

Android自定义水波纹动画Layout实例代码_Android

话不多说,我们先来看看效果: Hi前辈搜索预览 这一张是<Hi前辈>的搜索预览图,你可以在这里下载这个APP查看更多效果: http://www.wandoujia.com/apps/com.superlity.hiqianbei LSearchView 这是一个MD风格的搜索框,集成了ripple动画以及search时的loading,使用很简单,如果你也需要这样的搜索控件不妨来试试:https://github.com/onlynight/LSearchView RippleEverywh