• Android自定义控件(三)——有弹性的ListView


    上一次我们试验了有弹性的ScrollView。详情

    这一次,我们来试验有弹性的ScrollView。

    国际惯例,效果图:

    主要代码:

    [java] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. import android.content.Context;  
    2. import android.graphics.Rect;  
    3. import android.util.AttributeSet;  
    4. import android.view.MotionEvent;  
    5. import android.view.animation.Animation;  
    6. import android.view.animation.Animation.AnimationListener;  
    7. import android.view.animation.TranslateAnimation;  
    8. import android.widget.AbsListView;  
    9. import android.widget.ListView;  
    10.   
    11. /** 
    12.  * ElasticScrollView有弹性的ListView 
    13.  */  
    14. public class ElasticListView extends ListView {  
    15.     private float y;  
    16.     private Rect normal = new Rect();  
    17.     private boolean animationFinish = true;  
    18.   
    19.     public ElasticListView(Context context) {  
    20.         super(context);  
    21.         init();  
    22.     }  
    23.   
    24.     public ElasticListView(Context context, AttributeSet attrs) {  
    25.         super(context, attrs);  
    26.         init();  
    27.     }  
    28.   
    29.     protected void onScrollChanged(int l, int t, int oldl, int oldt) {  
    30.   
    31.     }  
    32.   
    33.     boolean overScrolled = false;  
    34.     private void init() {  
    35.         setOnScrollListener(new OnScrollListener() {  
    36.             @Override  
    37.             public void onScrollStateChanged(AbsListView view, int scrollState) {  
    38.             }  
    39.   
    40.             @Override  
    41.             public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {  
    42.                 overScrolled = false;  
    43.             }  
    44.         });  
    45.     }  
    46.       
    47.     @Override  
    48.     protected void onOverScrolled(int scrollX, int scrollY, boolean clampedX, boolean clampedY) {  
    49.         overScrolled = true;  
    50.     }  
    51.   
    52.     @Override  
    53.     public boolean onTouchEvent(MotionEvent ev) {  
    54.         commOnTouchEvent(ev);  
    55.         return super.onTouchEvent(ev);  
    56.     }  
    57.   
    58.     public void commOnTouchEvent(MotionEvent ev) {  
    59.         if (animationFinish) {  
    60.             int action = ev.getAction();  
    61.             switch (action) {  
    62.             case MotionEvent.ACTION_DOWN:  
    63.                 y = ev.getY();  
    64.                 break;  
    65.             case MotionEvent.ACTION_UP:  
    66.                 y = 0;  
    67.                 if (isNeedAnimation()) {  
    68.                     animation();  
    69.                 }  
    70.                 break;  
    71.             case MotionEvent.ACTION_MOVE:  
    72.                 final float preY = y == 0 ? ev.getY() : y;  
    73.                 float nowY = ev.getY();  
    74.                 int deltaY = (int) (preY - nowY);  
    75.   
    76.                 y = nowY;  
    77.                 // 当滚动到最上或者最下时就不会再滚动,这时移动布局  
    78.                 if (isNeedMove(deltaY)) {  
    79.                     if (normal.isEmpty()) {  
    80.                         // 保存正常的布局位置  
    81.                         normal.set(getLeft(), getTop(), getRight(), getBottom());  
    82.                     }  
    83.                     // 移动布局  
    84.                     layout(getLeft(), getTop() - deltaY / 2, getRight(), getBottom() - deltaY / 2);  
    85.                 }  
    86.                 break;  
    87.             default:  
    88.                 break;  
    89.             }  
    90.         }  
    91.     }  
    92.   
    93.     // 开启动画移动  
    94.     public void animation() {  
    95.         // 开启移动动画  
    96.         TranslateAnimation ta = new TranslateAnimation(0, 0, 0, normal.top - getTop());  
    97.         ta.setDuration(200);  
    98.         ta.setAnimationListener(new AnimationListener() {  
    99.             @Override  
    100.             public void onAnimationStart(Animation animation) {  
    101.                 animationFinish = false;  
    102.   
    103.             }  
    104.   
    105.             @Override  
    106.             public void onAnimationRepeat(Animation animation) {  
    107.   
    108.             }  
    109.   
    110.             @Override  
    111.             public void onAnimationEnd(Animation animation) {  
    112.                 clearAnimation();  
    113.                 // 设置回到正常的布局位置  
    114.                 layout(normal.left, normal.top, normal.right, normal.bottom);  
    115.                 normal.setEmpty();  
    116.                 animationFinish = true;  
    117.             }  
    118.         });  
    119.         startAnimation(ta);  
    120.     }  
    121.   
    122.     // 是否需要开启动画  
    123.     public boolean isNeedAnimation() {  
    124.         return !normal.isEmpty();  
    125.     }  
    126.   
    127.     // 是否需要移动布局  
    128.     public boolean isNeedMove(float deltaY) {  
    129.         if (overScrolled && getChildCount() > 0) {  
    130.             if (getLastVisiblePosition() == getCount() - 1 && deltaY > 0) {  
    131.                 return true;  
    132.             }  
    133.             if (getFirstVisiblePosition() == 0 && deltaY < 0) {  
    134.                 return true;  
    135.             }  
    136.         }  
    137.         return false;  
    138.     }  
    139. }  


    测试代码:

    [java] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. public class MainActivity extends Activity {  
    2.     ElasticListView listView;  
    3.     @Override  
    4.     protected void onCreate(Bundle savedInstanceState) {  
    5.         super.onCreate(savedInstanceState);  
    6.         setContentView(R.layout.activity_main);  
    7.           
    8.         listView = (ElasticListView) findViewById(R.id.listview);  
    9.           
    10.         String[] listValues = new String[20];  
    11.         for (int i=0;i<listValues.length;i++) {  
    12.             listValues[i] = "TextView" + i;  
    13.         }  
    14.         listView.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, listValues));  
    15.     }  
    16. }  
    [html] view plaincopy在CODE上查看代码片派生到我的代码片
     
      1. public class MainActivity extends Activity {  
      2.     ElasticListView listView;  
      3.     @Override  
      4.     protected void onCreate(Bundle savedInstanceState) {  
      5.         super.onCreate(savedInstanceState);  
      6.         setContentView(R.layout.activity_main);  
      7.           
      8.         listView = (ElasticListView) findViewById(R.id.listview);  
      9.           
      10.         String[] listValues = new String[20];  
      11.         for (int i=0;i<listValues.length;i++) {  
      12.             listValues[i] = "TextView" + i;  
      13.         }  
      14.         listView.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, listValues));  
      15.     }  
  • 相关阅读:
    关于几种滤波的对比
    学习笔记深入理解Java中的HashMap数据结构
    学习笔记Redis基础常识
    学习笔记Java内存模型
    学习笔记理解GC
    工作中的点点滴滴单例的使用
    工作中的点点滴滴学习一下门面模式
    工作中的点点滴滴接口幂等的问题
    【转载】WCF、WebAPI、WCFREST、WebService之间的区别
    【转载】工具分享——将C#文档注释生成.chm帮助文档
  • 原文地址:https://www.cnblogs.com/Free-Thinker/p/4126088.html
Copyright © 2020-2023  润新知