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


    原文地址:http://blog.csdn.net/a105865708/article/details/17959459

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

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

    国际惯例,效果图:



    主要代码:

      

      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 }

    测试代码:

     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 }
     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 }
  • 相关阅读:
    Linux Shell中的延时函数
    调试core文件(转)
    C++类构造函数初始化列表(转)
    seq简介(转)
    查看内存使用情况(转)
    awk 数组实例(转)
    伪终端(转)
    C++类成员变量的初始化方法(转)
    几个shell命令(转)
    子进程自父进程继承什么或未继承什么(转)
  • 原文地址:https://www.cnblogs.com/liangstudyhome/p/4152228.html
Copyright © 2020-2023  润新知