Android View滚动、拉伸到顶/底部弹性回弹复位

《Android View滚动、拉伸到顶/底部弹性回弹复位》

我在上一篇文章介绍了如何实现一个Android ListView拉到顶/底部后,像橡皮筋一样弹性回弹复位(《Android ListView拉到顶/底部,像橡皮筋一样弹性回弹复位》,文章链接地址:http://blog.csdn.net/zhangphil/article/details/47311155 )。事实上,Android凡是由ScrollView包裹的控件,均可实现滚动到顶/底部,弹性回弹复位的交互设计效果。关键点是重写Android原生ScrollView的overScrollBy()方法。
现给出实现代码和步骤:
(1)首先需要写一个View继承自ScrollView,然后重写关键的方法:overScrollBy()。假设该view就叫做ZhangPhilScrollView:

[java]  view plain copy
  1. package zhangphil.view;  
  2.   
  3. import android.annotation.SuppressLint;  
  4. import android.content.Context;  
  5. import android.util.AttributeSet;  
  6. import android.util.DisplayMetrics;  
  7. import android.widget.ScrollView;  
  8.   
  9. public class ZhangPhilScrollView extends ScrollView{  
  10.   
  11.     // 这个值控制可以把ScrollView包裹的控件拉出偏离顶部或底部的距离。  
  12.     private static final int MAX_OVERSCROLL_Y = 200;  
  13.   
  14.     private Context mContext;  
  15.     private int newMaxOverScrollY;  
  16.   
  17.     public ZhangPhilScrollView(Context context) {  
  18.         super(context);  
  19.           
  20.         init(context);  
  21.     }  
  22.   
  23.     public ZhangPhilScrollView(Context context, AttributeSet attrs) {  
  24.         super(context, attrs);  
  25.           
  26.         init(context);  
  27.     }  
  28.   
  29.     /* 
  30.      * public ZhangPhilListView(Context context, AttributeSet attrs, int 
  31.      * defStyle) { super(context, attrs, defStyle); this.mContext = context; 
  32.      * init(); } 
  33.      */  
  34.   
  35.     @SuppressLint("NewApi")  
  36.     private void init(Context context) {  
  37.           
  38.         this.mContext = context;  
  39.           
  40.         DisplayMetrics metrics = mContext.getResources().getDisplayMetrics();  
  41.         float density = metrics.density;  
  42.         newMaxOverScrollY = (int) (density * MAX_OVERSCROLL_Y);  
  43.           
  44.         //false:隐藏ScrollView的滚动条。  
  45.         this.setVerticalScrollBarEnabled(false);  
  46.           
  47.         //不管装载的控件填充的数据是否满屏,都允许橡皮筋一样的弹性回弹。  
  48.         this.setOverScrollMode(ScrollView.OVER_SCROLL_ALWAYS);  
  49.     }  
  50.   
  51.     // 最关键的地方。  
  52.     //支持到SDK8需要增加@SuppressLint("NewApi")。  
  53.     @SuppressLint("NewApi")  
  54.     @Override  
  55.     protected boolean overScrollBy(int deltaX, int deltaY, int scrollX,  
  56.             int scrollY, int scrollRangeX, int scrollRangeY,  
  57.             int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) {  
  58.         return super.overScrollBy(deltaX, deltaY, scrollX, scrollY,  
  59.                 scrollRangeX, scrollRangeY, maxOverScrollX, newMaxOverScrollY,  
  60.                 isTouchEvent);  
  61.     }  
  62. }  
[java]  view plain copy
  1. package zhangphil.view;  
  2.   
  3. import android.annotation.SuppressLint;  
  4. import android.content.Context;  
  5. import android.util.AttributeSet;  
  6. import android.util.DisplayMetrics;  
  7. import android.widget.ScrollView;  
  8.   
  9. public class ZhangPhilScrollView extends ScrollView{  
  10.   
  11.     // 这个值控制可以把ScrollView包裹的控件拉出偏离顶部或底部的距离。  
  12.     private static final int MAX_OVERSCROLL_Y = 200;  
  13.   
  14.     private Context mContext;  
  15.     private int newMaxOverScrollY;  
  16.   
  17.     public ZhangPhilScrollView(Context context) {  
  18.         super(context);  
  19.           
  20.         init(context);  
  21.     }  
  22.   
  23.     public ZhangPhilScrollView(Context context, AttributeSet attrs) {  
  24.         super(context, attrs);  
  25.           
  26.         init(context);  
  27.     }  
  28.   
  29.     /* 
  30.      * public ZhangPhilListView(Context context, AttributeSet attrs, int 
  31.      * defStyle) { super(context, attrs, defStyle); this.mContext = context; 
  32.      * init(); } 
  33.      */  
  34.   
  35.     @SuppressLint("NewApi")  
  36.     private void init(Context context) {  
  37.           
  38.         this.mContext = context;  
  39.           
  40.         DisplayMetrics metrics = mContext.getResources().getDisplayMetrics();  
  41.         float density = metrics.density;  
  42.         newMaxOverScrollY = (int) (density * MAX_OVERSCROLL_Y);  
  43.           
  44.         //false:隐藏ScrollView的滚动条。  
  45.         this.setVerticalScrollBarEnabled(false);  
  46.           
  47.         //不管装载的控件填充的数据是否满屏,都允许橡皮筋一样的弹性回弹。  
  48.         this.setOverScrollMode(ScrollView.OVER_SCROLL_ALWAYS);  
  49.     }  
  50.   
  51.     // 最关键的地方。  
  52.     //支持到SDK8需要增加@SuppressLint("NewApi")。  
  53.     @SuppressLint("NewApi")  
  54.     @Override  
  55.     protected boolean overScrollBy(int deltaX, int deltaY, int scrollX,  
  56.             int scrollY, int scrollRangeX, int scrollRangeY,  
  57.             int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) {  
  58.         return super.overScrollBy(deltaX, deltaY, scrollX, scrollY,  
  59.                 scrollRangeX, scrollRangeY, maxOverScrollX, newMaxOverScrollY,  
  60.                 isTouchEvent);  
  61.     }  
  62. }  


(2)然后在布局文件代码中像使用Android原生的ScrollView一样使用ZhangPhilScrollView包裹需要实现弹性回弹交互设计的组件,在我的这个例子中,出于简单的目的,假设ZhangPhilScrollView包裹的只是一个TextView:

[html]  view plain copy
  1. <zhangphil.view.ZhangPhilScrollView xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     android:layout_width="match_parent"  
  3.     android:layout_height="match_parent" >  
  4.   
  5.     <TextView  
  6.         android:id="@+id/text"  
  7.         android:layout_width="match_parent"  
  8.         android:layout_height="wrap_content" />  
  9.   
  10. </zhangphil.view.ZhangPhilScrollView>  
[html]  view plain copy
  1. <zhangphil.view.ZhangPhilScrollView xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     android:layout_width="match_parent"  
  3.     android:layout_height="match_parent" >  
  4.   
  5.     <TextView  
  6.         android:id="@+id/text"  
  7.         android:layout_width="match_parent"  
  8.         android:layout_height="wrap_content" />  
  9.   
  10. </zhangphil.view.ZhangPhilScrollView>  


测试:

[java]  view plain copy
  1. package zhangphil.view;  
  2.   
  3. import zhangphil.view.R;  
  4. import android.support.v7.app.ActionBarActivity;  
  5. import android.widget.TextView;  
  6. import android.graphics.Color;  
  7. import android.os.Bundle;  
  8.   
  9. public class MainActivity extends ActionBarActivity {  
  10.   
  11.     @Override  
  12.     protected void onCreate(Bundle savedInstanceState) {  
  13.         super.onCreate(savedInstanceState);  
  14.         setContentView(R.layout.activity_main);  
  15.   
  16.         TextView text = (TextView) findViewById(R.id.text);  
  17.   
  18.         // 测试数据集。  
  19.         String s = "";  
  20.         for (int i = 0; i < 10; i++) {  
  21.             s += i + "\n";  
  22.         }  
  23.   
  24.         text.setText(s);  
  25.   
  26.         // 设置TextView的背景颜色,更容易观察出弹性回弹效果。  
  27.         text.setBackgroundColor(Color.RED);  
  28.     }  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值