zoukankan      html  css  js  c++  java
  • Android 实现ListView的滑动删除效果(转)

    首先,这是转载过来的,里面对于手势以及事件分发部分写的还比较可以

    用过微信的都知道,微信对话列表滑动删除效果是很不错的,这个效果我们也可以有。思路其实很简单,弄个ListView,然后里面的每个item做成一个可以滑动的自定义控件即可。由于ListView是上下滑动而item是左右滑动,因此会有滑动冲突,也许你需要了解下android中点击事件的派发流程,请参考Android源码分析-点击事件派发机制。我的解决思路是这样的:重写ListView的onInterceptTouchEvent方法,在move的时候做判断,如果是左右滑动就返回false,否则返回true;重写SlideView(即自定义item控件)的onTouchEvent方法来处理滑动。整个思路没有问题,滑动冲突也解决了,可是ListView无法得到焦点了,也就是ListView无法处理点击事件了。让我们回想下问题出在哪里:我的理解是这样的,上述处理滑动本身没有问题,但是有一个副作用,就是会让外层View失去焦点且无法处理点击事件。常见的滑动冲突场景,比如launcher内部嵌入ListView却是没有问题的,因为这个时候launcher不需要获得焦点,需要获得焦点的是内部的ListView。因此,上述处理方式对于外部需要获得焦点的情况(比如外部是ListView)就不太适合了。于是我就和ttdevs探讨,发现他采用了另外一种思路,我从来没有想过还可以这样玩。下面介绍他的思路。

    新的思路

    不考虑那么复杂,不采用主流玩法,所有的事件均由外层的ListView做拦截,同时把事件传递给SlideView做滑动,这种实现的确可以达到效果,而且代码很简单,根本不需要处理什么复杂的滑动冲突。

    效果

    下面分别为微信和高仿效果

    代码分析

    先看SlideView是如何实现的

    看layout xml:

    [html] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. <?xml version="1.0" encoding="utf-8"?>
    2. <merge xmlns:android="http://schemas.android.com/apk/res/android"
    3. android:layout_width="match_parent"
    4. android:layout_height="match_parent" >
    5. <LinearLayout
    6. android:id="@+id/view_content"
    7. android:layout_width="match_parent"
    8. android:layout_height="match_parent"
    9. android:orientation="horizontal" >
    10. </LinearLayout>
    11. <RelativeLayout
    12. android:id="@+id/holder"
    13. android:layout_width="120dp"
    14. android:layout_height="match_parent"
    15. android:clickable="true"
    16. android:background="@drawable/holder_bg">
    17. <TextView
    18. android:id="@+id/delete"
    19. android:layout_width="wrap_content"
    20. android:layout_height="wrap_content"
    21. android:drawableLeft="@drawable/del_icon_normal"
    22. android:layout_centerInParent="true"
    23. android:gravity="center"
    24. android:textColor="@color/floralwhite"
    25. android:text="删除" />
    26. </RelativeLayout>
    27. </merge>
    [html] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. <?xml version="1.0" encoding="utf-8"?>  
    2. <merge xmlns:android="http://schemas.android.com/apk/res/android"  
    3.     android:layout_width="match_parent"  
    4.     android:layout_height="match_parent" >  
    5.   
    6.     <LinearLayout  
    7.         android:id="@+id/view_content"  
    8.         android:layout_width="match_parent"  
    9.         android:layout_height="match_parent"  
    10.         android:orientation="horizontal" >  
    11.     </LinearLayout>  
    12.   
    13.     <RelativeLayout  
    14.         android:id="@+id/holder"  
    15.         android:layout_width="120dp"  
    16.         android:layout_height="match_parent"  
    17.         android:clickable="true"  
    18.         android:background="@drawable/holder_bg">  
    19.   
    20.         <TextView  
    21.             android:id="@+id/delete"  
    22.             android:layout_width="wrap_content"  
    23.             android:layout_height="wrap_content"  
    24.             android:drawableLeft="@drawable/del_icon_normal"  
    25.             android:layout_centerInParent="true"  
    26.             android:gravity="center"  
    27.             android:textColor="@color/floralwhite"  
    28.             android:text="删除" />  
    29.     </RelativeLayout>  
    30.   
    31. </merge>  

    上述xml文件中,所有的view都会被放在view_content中,而holder是放置诸如删除按钮之类的东西,我们的SlideView会加载这个布局。

    再看SlideView.java:

    [java] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. /**
    2. * SlideView 继承自LinearLayout
    3. */
    4. public class SlideView extends LinearLayout {
    5. private static final String TAG = "SlideView";
    6. private Context mContext;
    7. // 用来放置所有view的容器
    8. private LinearLayout mViewContent;
    9. // 用来放置内置view的容器,比如删除 按钮
    10. private RelativeLayout mHolder;
    11. // 弹性滑动对象,提供弹性滑动效果
    12. private Scroller mScroller;
    13. // 滑动回调接口,用来向上层通知滑动事件
    14. private OnSlideListener mOnSlideListener;
    15. // 内置容器的宽度 单位:dp
    16. private int mHolderWidth = 120;
    17. // 分别记录上次滑动的坐标
    18. private int mLastX = 0;
    19. private int mLastY = 0;
    20. // 用来控制滑动角度,仅当角度a满足如下条件才进行滑动:tan a = deltaX / deltaY > 2
    21. private static final int TAN = 2;
    22. public interface OnSlideListener {
    23. // SlideView的三种状态:开始滑动,打开,关闭
    24. public static final int SLIDE_STATUS_OFF = 0;
    25. public static final int SLIDE_STATUS_START_SCROLL = 1;
    26. public static final int SLIDE_STATUS_ON = 2;
    27. /**
    28. * @param view
    29. * current SlideView
    30. * @param status
    31. * SLIDE_STATUS_ON, SLIDE_STATUS_OFF or
    32. * SLIDE_STATUS_START_SCROLL
    33. */
    34. public void onSlide(View view, int status);
    35. }
    36. public SlideView(Context context) {
    37. super(context);
    38. initView();
    39. }
    40. public SlideView(Context context, AttributeSet attrs) {
    41. super(context, attrs);
    42. initView();
    43. }
    44. private void initView() {
    45. mContext = getContext();
    46. // 初始化弹性滑动对象
    47. mScroller = new Scroller(mContext);
    48. // 设置其方向为横向
    49. setOrientation(LinearLayout.HORIZONTAL);
    50. // 将slide_view_merge加载进来
    51. View.inflate(mContext, R.layout.slide_view_merge, this);
    52. mViewContent = (LinearLayout) findViewById(R.id.view_content);
    53. mHolderWidth = Math.round(TypedValue.applyDimension(
    54. TypedValue.COMPLEX_UNIT_DIP, mHolderWidth, getResources()
    55. .getDisplayMetrics()));
    56. }
    57. // 设置按钮的内容,也可以设置图标啥的,我没写
    58. public void setButtonText(CharSequence text) {
    59. ((TextView) findViewById(R.id.delete)).setText(text);
    60. }
    61. // 将view加入到ViewContent中
    62. public void setContentView(View view) {
    63. mViewContent.addView(view);
    64. }
    65. // 设置滑动回调
    66. public void setOnSlideListener(OnSlideListener onSlideListener) {
    67. mOnSlideListener = onSlideListener;
    68. }
    69. // 将当前状态置为关闭
    70. public void shrink() {
    71. if (getScrollX() != 0) {
    72. this.smoothScrollTo(00);
    73. }
    74. }
    75. // 根据MotionEvent来进行滑动,这个方法的作用相当于onTouchEvent
    76. // 如果你不需要处理滑动冲突,可以直接重命名,照样能正常工作
    77. public void onRequireTouchEvent(MotionEvent event) {
    78. int x = (int) event.getX();
    79. int y = (int) event.getY();
    80. int scrollX = getScrollX();
    81. Log.d(TAG, "x=" + x + " y=" + y);
    82. switch (event.getAction()) {
    83. case MotionEvent.ACTION_DOWN: {
    84. if (!mScroller.isFinished()) {
    85. mScroller.abortAnimation();
    86. }
    87. if (mOnSlideListener != null) {
    88. mOnSlideListener.onSlide(this,
    89. OnSlideListener.SLIDE_STATUS_START_SCROLL);
    90. }
    91. break;
    92. }
    93. case MotionEvent.ACTION_MOVE: {
    94. int deltaX = x - mLastX;
    95. int deltaY = y - mLastY;
    96. if (Math.abs(deltaX) < Math.abs(deltaY) * TAN) {
    97. // 滑动不满足条件,不做横向滑动
    98. break;
    99. }
    100. // 计算滑动终点是否合法,防止滑动越界
    101. int newScrollX = scrollX - deltaX;
    102. if (deltaX != 0) {
    103. if (newScrollX < 0) {
    104. newScrollX = 0;
    105. else if (newScrollX > mHolderWidth) {
    106. newScrollX = mHolderWidth;
    107. }
    108. this.scrollTo(newScrollX, 0);
    109. }
    110. break;
    111. }
    112. case MotionEvent.ACTION_UP: {
    113. int newScrollX = 0;
    114. // 这里做了下判断,当松开手的时候,会自动向两边滑动,具体向哪边滑,要看当前所处的位置
    115. if (scrollX - mHolderWidth * 0.75 > 0) {
    116. newScrollX = mHolderWidth;
    117. }
    118. // 慢慢滑向终点
    119. this.smoothScrollTo(newScrollX, 0);
    120. // 通知上层滑动事件
    121. if (mOnSlideListener != null) {
    122. mOnSlideListener.onSlide(this,
    123. newScrollX == 0 ? OnSlideListener.SLIDE_STATUS_OFF
    124. : OnSlideListener.SLIDE_STATUS_ON);
    125. }
    126. break;
    127. }
    128. default:
    129. break;
    130. }
    131. mLastX = x;
    132. mLastY = y;
    133. }
    134. private void smoothScrollTo(int destX, int destY) {
    135. // 缓慢滚动到指定位置
    136. int scrollX = getScrollX();
    137. int delta = destX - scrollX;
    138. // 以三倍时长滑向destX,效果就是慢慢滑动
    139. mScroller.startScroll(scrollX, 0, delta, 0, Math.abs(delta) * 3);
    140. invalidate();
    141. }
    142. @Override
    143. public void computeScroll() {
    144. if (mScroller.computeScrollOffset()) {
    145. scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
    146. postInvalidate();
    147. }
    148. }
    149. }
    [java] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. /** 
    2.  * SlideView 继承自LinearLayout 
    3.  */  
    4. public class SlideView extends LinearLayout {  
    5.   
    6.     private static final String TAG = "SlideView";  
    7.   
    8.     private Context mContext;  
    9.   
    10.     // 用来放置所有view的容器  
    11.     private LinearLayout mViewContent;  
    12.   
    13.     // 用来放置内置view的容器,比如删除 按钮  
    14.     private RelativeLayout mHolder;  
    15.   
    16.     // 弹性滑动对象,提供弹性滑动效果  
    17.     private Scroller mScroller;  
    18.   
    19.     // 滑动回调接口,用来向上层通知滑动事件  
    20.     private OnSlideListener mOnSlideListener;  
    21.   
    22.     // 内置容器的宽度 单位:dp  
    23.     private int mHolderWidth = 120;  
    24.   
    25.     // 分别记录上次滑动的坐标  
    26.     private int mLastX = 0;  
    27.     private int mLastY = 0;  
    28.   
    29.     // 用来控制滑动角度,仅当角度a满足如下条件才进行滑动:tan a = deltaX / deltaY > 2  
    30.     private static final int TAN = 2;  
    31.   
    32.     public interface OnSlideListener {  
    33.         // SlideView的三种状态:开始滑动,打开,关闭  
    34.         public static final int SLIDE_STATUS_OFF = 0;  
    35.         public static final int SLIDE_STATUS_START_SCROLL = 1;  
    36.         public static final int SLIDE_STATUS_ON = 2;  
    37.   
    38.         /** 
    39.          * @param view 
    40.          *            current SlideView 
    41.          * @param status 
    42.          *            SLIDE_STATUS_ON, SLIDE_STATUS_OFF or 
    43.          *            SLIDE_STATUS_START_SCROLL 
    44.          */  
    45.         public void onSlide(View view, int status);  
    46.     }  
    47.   
    48.     public SlideView(Context context) {  
    49.         super(context);  
    50.         initView();  
    51.     }  
    52.   
    53.     public SlideView(Context context, AttributeSet attrs) {  
    54.         super(context, attrs);  
    55.         initView();  
    56.     }  
    57.   
    58.     private void initView() {  
    59.         mContext = getContext();  
    60.         // 初始化弹性滑动对象  
    61.         mScroller = new Scroller(mContext);  
    62.         // 设置其方向为横向  
    63.         setOrientation(LinearLayout.HORIZONTAL);  
    64.         // 将slide_view_merge加载进来  
    65.         View.inflate(mContext, R.layout.slide_view_merge, this);  
    66.         mViewContent = (LinearLayout) findViewById(R.id.view_content);  
    67.         mHolderWidth = Math.round(TypedValue.applyDimension(  
    68.                 TypedValue.COMPLEX_UNIT_DIP, mHolderWidth, getResources()  
    69.                         .getDisplayMetrics()));  
    70.     }  
    71.   
    72.     // 设置按钮的内容,也可以设置图标啥的,我没写  
    73.     public void setButtonText(CharSequence text) {  
    74.         ((TextView) findViewById(R.id.delete)).setText(text);  
    75.     }  
    76.   
    77.     // 将view加入到ViewContent中  
    78.     public void setContentView(View view) {  
    79.         mViewContent.addView(view);  
    80.     }  
    81.   
    82.     // 设置滑动回调  
    83.     public void setOnSlideListener(OnSlideListener onSlideListener) {  
    84.         mOnSlideListener = onSlideListener;  
    85.     }  
    86.   
    87.     // 将当前状态置为关闭  
    88.     public void shrink() {  
    89.         if (getScrollX() != 0) {  
    90.             this.smoothScrollTo(00);  
    91.         }  
    92.     }  
    93.   
    94.     // 根据MotionEvent来进行滑动,这个方法的作用相当于onTouchEvent  
    95.     // 如果你不需要处理滑动冲突,可以直接重命名,照样能正常工作  
    96.     public void onRequireTouchEvent(MotionEvent event) {  
    97.         int x = (int) event.getX();  
    98.         int y = (int) event.getY();  
    99.         int scrollX = getScrollX();  
    100.         Log.d(TAG, "x=" + x + "  y=" + y);  
    101.   
    102.         switch (event.getAction()) {  
    103.         case MotionEvent.ACTION_DOWN: {  
    104.             if (!mScroller.isFinished()) {  
    105.                 mScroller.abortAnimation();  
    106.             }  
    107.             if (mOnSlideListener != null) {  
    108.                 mOnSlideListener.onSlide(this,  
    109.                         OnSlideListener.SLIDE_STATUS_START_SCROLL);  
    110.             }  
    111.             break;  
    112.         }  
    113.         case MotionEvent.ACTION_MOVE: {  
    114.             int deltaX = x - mLastX;  
    115.             int deltaY = y - mLastY;  
    116.             if (Math.abs(deltaX) < Math.abs(deltaY) * TAN) {  
    117.                 // 滑动不满足条件,不做横向滑动  
    118.                 break;  
    119.             }  
    120.   
    121.             // 计算滑动终点是否合法,防止滑动越界  
    122.             int newScrollX = scrollX - deltaX;  
    123.             if (deltaX != 0) {  
    124.                 if (newScrollX < 0) {  
    125.                     newScrollX = 0;  
    126.                 } else if (newScrollX > mHolderWidth) {  
    127.                     newScrollX = mHolderWidth;  
    128.                 }  
    129.                 this.scrollTo(newScrollX, 0);  
    130.             }  
    131.             break;  
    132.         }  
    133.         case MotionEvent.ACTION_UP: {  
    134.             int newScrollX = 0;  
    135.             // 这里做了下判断,当松开手的时候,会自动向两边滑动,具体向哪边滑,要看当前所处的位置  
    136.             if (scrollX - mHolderWidth * 0.75 > 0) {  
    137.                 newScrollX = mHolderWidth;  
    138.             }  
    139.             // 慢慢滑向终点  
    140.             this.smoothScrollTo(newScrollX, 0);  
    141.             // 通知上层滑动事件  
    142.             if (mOnSlideListener != null) {  
    143.                 mOnSlideListener.onSlide(this,  
    144.                         newScrollX == 0 ? OnSlideListener.SLIDE_STATUS_OFF  
    145.                                 : OnSlideListener.SLIDE_STATUS_ON);  
    146.             }  
    147.             break;  
    148.         }  
    149.         default:  
    150.             break;  
    151.         }  
    152.   
    153.         mLastX = x;  
    154.         mLastY = y;  
    155.     }  
    156.   
    157.     private void smoothScrollTo(int destX, int destY) {  
    158.         // 缓慢滚动到指定位置  
    159.         int scrollX = getScrollX();  
    160.         int delta = destX - scrollX;  
    161.         // 以三倍时长滑向destX,效果就是慢慢滑动  
    162.         mScroller.startScroll(scrollX, 0, delta, 0, Math.abs(delta) * 3);  
    163.         invalidate();  
    164.     }  
    165.   
    166.     @Override  
    167.     public void computeScroll() {  
    168.         if (mScroller.computeScrollOffset()) {  
    169.             scrollTo(mScroller.getCurrX(), mScroller.getCurrY());  
    170.             postInvalidate();  
    171.         }  
    172.     }  
    173.   
    174. }  

    上述代码做了很详细的说明,这就是滑动控件的完整代码,大家要明白的是:你所添加的view都是加在SlideView的子View : view_content中的,而不是直接加在SlideView中,只有这样我们才方便做滑动效果。

    接着看ListView的代码:核心就是下面这一个方法,将点击事件发送给SlideView处理。

    [java] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. @Override
    2. public boolean onTouchEvent(MotionEvent event) {
    3. switch (event.getAction()) {
    4. case MotionEvent.ACTION_DOWN: {
    5. int x = (int) event.getX();
    6. int y = (int) event.getY();
    7. //我们想知道当前点击了哪一行
    8. int position = pointToPosition(x, y);
    9. Log.e(TAG, "postion=" + position);
    10. if (position != INVALID_POSITION) {
    11. //得到当前点击行的数据从而取出当前行的item。
    12. //可能有人怀疑,为什么要这么干?为什么不用getChildAt(position)?
    13. //因为ListView会进行缓存,如果你不这么干,有些行的view你是得不到的。
    14. MessageItem data = (MessageItem) getItemAtPosition(position);
    15. mFocusedItemView = data.slideView;
    16. Log.e(TAG, "FocusedItemView=" + mFocusedItemView);
    17. }
    18. }
    19. default:
    20. break;
    21. }
    22. //向当前点击的view发送滑动事件请求,其实就是向SlideView发请求
    23. if (mFocusedItemView != null) {
    24. mFocusedItemView.onRequireTouchEvent(event);
    25. }
    26. return super.onTouchEvent(event);
    27. }
    [java] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. @Override  
    2. public boolean onTouchEvent(MotionEvent event) {  
    3.     switch (event.getAction()) {  
    4.     case MotionEvent.ACTION_DOWN: {  
    5.         int x = (int) event.getX();  
    6.         int y = (int) event.getY();  
    7.         //我们想知道当前点击了哪一行  
    8.         int position = pointToPosition(x, y);  
    9.         Log.e(TAG, "postion=" + position);  
    10.         if (position != INVALID_POSITION) {  
    11.             //得到当前点击行的数据从而取出当前行的item。  
    12.             //可能有人怀疑,为什么要这么干?为什么不用getChildAt(position)?  
    13.             //因为ListView会进行缓存,如果你不这么干,有些行的view你是得不到的。  
    14.             MessageItem data = (MessageItem) getItemAtPosition(position);  
    15.             mFocusedItemView = data.slideView;  
    16.             Log.e(TAG, "FocusedItemView=" + mFocusedItemView);  
    17.         }  
    18.     }  
    19.     default:  
    20.         break;  
    21.     }  
    22.   
    23.     //向当前点击的view发送滑动事件请求,其实就是向SlideView发请求  
    24.     if (mFocusedItemView != null) {  
    25.         mFocusedItemView.onRequireTouchEvent(event);  
    26.     }  
    27.   
    28.     return super.onTouchEvent(event);  
    29. }  

    最后看Activity的代码:

    [java] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. public class MainActivity extends Activity implements OnItemClickListener,
    2. OnClickListener, OnSlideListener {
    3. private static final String TAG = "MainActivity";
    4. private ListViewCompat mListView;
    5. private List<MessageItem> mMessageItems = new ArrayList<MainActivity.MessageItem>();
    6. private SlideAdapter mSlideAdapter;
    7. // 上次处于打开状态的SlideView
    8. private SlideView mLastSlideViewWithStatusOn;
    9. @Override
    10. protected void onCreate(Bundle savedInstanceState) {
    11. super.onCreate(savedInstanceState);
    12. setContentView(R.layout.activity_main);
    13. initView();
    14. }
    15. private void initView() {
    16. mListView = (ListViewCompat) findViewById(R.id.list);
    17. for (int i = 0; i < 20; i++) {
    18. MessageItem item = new MessageItem();
    19. if (i % 3 == 0) {
    20. item.iconRes = R.drawable.default_qq_avatar;
    21. item.title = "腾讯新闻";
    22. item.msg = "青岛爆炸满月:大量鱼虾死亡";
    23. item.time = "晚上18:18";
    24. else {
    25. item.iconRes = R.drawable.wechat_icon;
    26. item.title = "微信团队";
    27. item.msg = "欢迎你使用微信";
    28. item.time = "12月18日";
    29. }
    30. mMessageItems.add(item);
    31. }
    32. mSlideAdapter = new SlideAdapter();
    33. mListView.setAdapter(mSlideAdapter);
    34. mListView.setOnItemClickListener(this);
    35. }
    36. private class SlideAdapter extends BaseAdapter {
    37. private LayoutInflater mInflater;
    38. SlideAdapter() {
    39. super();
    40. mInflater = getLayoutInflater();
    41. }
    42. @Override
    43. public int getCount() {
    44. return mMessageItems.size();
    45. }
    46. @Override
    47. public Object getItem(int position) {
    48. return mMessageItems.get(position);
    49. }
    50. @Override
    51. public long getItemId(int position) {
    52. return position;
    53. }
    54. @Override
    55. public View getView(int position, View convertView, ViewGroup parent) {
    56. ViewHolder holder;
    57. SlideView slideView = (SlideView) convertView;
    58. if (slideView == null) {
    59. // 这里是我们的item
    60. View itemView = mInflater.inflate(R.layout.list_item, null);
    61. slideView = new SlideView(MainActivity.this);
    62. // 这里把item加入到slideView
    63. slideView.setContentView(itemView);
    64. // 下面是做一些数据缓存
    65. holder = new ViewHolder(slideView);
    66. slideView.setOnSlideListener(MainActivity.this);
    67. slideView.setTag(holder);
    68. else {
    69. holder = (ViewHolder) slideView.getTag();
    70. }
    71. MessageItem item = mMessageItems.get(position);
    72. item.slideView = slideView;
    73. item.slideView.shrink();
    74. holder.icon.setImageResource(item.iconRes);
    75. holder.title.setText(item.title);
    76. holder.msg.setText(item.msg);
    77. holder.time.setText(item.time);
    78. holder.deleteHolder.setOnClickListener(MainActivity.this);
    79. return slideView;
    80. }
    81. }
    82. public class MessageItem {
    83. public int iconRes;
    84. public String title;
    85. public String msg;
    86. public String time;
    87. public SlideView slideView;
    88. }
    89. private static class ViewHolder {
    90. public ImageView icon;
    91. public TextView title;
    92. public TextView msg;
    93. public TextView time;
    94. public ViewGroup deleteHolder;
    95. ViewHolder(View view) {
    96. icon = (ImageView) view.findViewById(R.id.icon);
    97. title = (TextView) view.findViewById(R.id.title);
    98. msg = (TextView) view.findViewById(R.id.msg);
    99. time = (TextView) view.findViewById(R.id.time);
    100. deleteHolder = (ViewGroup) view.findViewById(R.id.holder);
    101. }
    102. }
    103. @Override
    104. public void onItemClick(AdapterView<?> parent, View view, int position,
    105. long id) {
    106. // 这里处理ListItem的点击事件
    107. Log.e(TAG, "onItemClick position=" + position);
    108. }
    109. @Override
    110. public void onSlide(View view, int status) {
    111. // 如果当前存在已经打开的SlideView,那么将其关闭
    112. if (mLastSlideViewWithStatusOn != null
    113. && mLastSlideViewWithStatusOn != view) {
    114. mLastSlideViewWithStatusOn.shrink();
    115. }
    116. // 记录本次处于打开状态的view
    117. if (status == SLIDE_STATUS_ON) {
    118. mLastSlideViewWithStatusOn = (SlideView) view;
    119. }
    120. }
    121. @Override
    122. public void onClick(View v) {
    123. // 这里处理删除按钮的点击事件,可以删除对话
    124. if (v.getId() == R.id.holder) {
    125. int position = mListView.getPositionForView(v);
    126. if (position != ListView.INVALID_POSITION) {
    127. mMessageItems.remove(position);
    128. mSlideAdapter.notifyDataSetChanged();
    129. }
    130. Log.e(TAG, "onClick v=" + v);
    131. }
    132. }
    133. }
    [java] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. public class MainActivity extends Activity implements OnItemClickListener,  
    2.         OnClickListener, OnSlideListener {  
    3.   
    4.     private static final String TAG = "MainActivity";  
    5.   
    6.     private ListViewCompat mListView;  
    7.   
    8.     private List<MessageItem> mMessageItems = new ArrayList<MainActivity.MessageItem>();  
    9.   
    10.     private SlideAdapter mSlideAdapter;  
    11.   
    12.     // 上次处于打开状态的SlideView  
    13.     private SlideView mLastSlideViewWithStatusOn;  
    14.   
    15.     @Override  
    16.     protected void onCreate(Bundle savedInstanceState) {  
    17.         super.onCreate(savedInstanceState);  
    18.         setContentView(R.layout.activity_main);  
    19.         initView();  
    20.     }  
    21.   
    22.     private void initView() {  
    23.         mListView = (ListViewCompat) findViewById(R.id.list);  
    24.   
    25.         for (int i = 0; i < 20; i++) {  
    26.             MessageItem item = new MessageItem();  
    27.             if (i % 3 == 0) {  
    28.                 item.iconRes = R.drawable.default_qq_avatar;  
    29.                 item.title = "腾讯新闻";  
    30.                 item.msg = "青岛爆炸满月:大量鱼虾死亡";  
    31.                 item.time = "晚上18:18";  
    32.             } else {  
    33.                 item.iconRes = R.drawable.wechat_icon;  
    34.                 item.title = "微信团队";  
    35.                 item.msg = "欢迎你使用微信";  
    36.                 item.time = "12月18日";  
    37.             }  
    38.             mMessageItems.add(item);  
    39.         }  
    40.         mSlideAdapter = new SlideAdapter();  
    41.         mListView.setAdapter(mSlideAdapter);  
    42.         mListView.setOnItemClickListener(this);  
    43.     }  
    44.   
    45.     private class SlideAdapter extends BaseAdapter {  
    46.   
    47.         private LayoutInflater mInflater;  
    48.   
    49.         SlideAdapter() {  
    50.             super();  
    51.             mInflater = getLayoutInflater();  
    52.         }  
    53.   
    54.         @Override  
    55.         public int getCount() {  
    56.             return mMessageItems.size();  
    57.         }  
    58.   
    59.         @Override  
    60.         public Object getItem(int position) {  
    61.             return mMessageItems.get(position);  
    62.         }  
    63.   
    64.         @Override  
    65.         public long getItemId(int position) {  
    66.             return position;  
    67.         }  
    68.   
    69.         @Override  
    70.         public View getView(int position, View convertView, ViewGroup parent) {  
    71.             ViewHolder holder;  
    72.             SlideView slideView = (SlideView) convertView;  
    73.             if (slideView == null) {  
    74.                 // 这里是我们的item  
    75.                 View itemView = mInflater.inflate(R.layout.list_item, null);  
    76.   
    77.                 slideView = new SlideView(MainActivity.this);  
    78.                 // 这里把item加入到slideView  
    79.                 slideView.setContentView(itemView);  
    80.                 // 下面是做一些数据缓存  
    81.                 holder = new ViewHolder(slideView);  
    82.                 slideView.setOnSlideListener(MainActivity.this);  
    83.                 slideView.setTag(holder);  
    84.             } else {  
    85.                 holder = (ViewHolder) slideView.getTag();  
    86.             }  
    87.             MessageItem item = mMessageItems.get(position);  
    88.             item.slideView = slideView;  
    89.             item.slideView.shrink();  
    90.   
    91.             holder.icon.setImageResource(item.iconRes);  
    92.             holder.title.setText(item.title);  
    93.             holder.msg.setText(item.msg);  
    94.             holder.time.setText(item.time);  
    95.             holder.deleteHolder.setOnClickListener(MainActivity.this);  
    96.   
    97.             return slideView;  
    98.         }  
    99.   
    100.     }  
    101.   
    102.     public class MessageItem {  
    103.         public int iconRes;  
    104.         public String title;  
    105.         public String msg;  
    106.         public String time;  
    107.         public SlideView slideView;  
    108.     }  
    109.   
    110.     private static class ViewHolder {  
    111.         public ImageView icon;  
    112.         public TextView title;  
    113.         public TextView msg;  
    114.         public TextView time;  
    115.         public ViewGroup deleteHolder;  
    116.   
    117.         ViewHolder(View view) {  
    118.             icon = (ImageView) view.findViewById(R.id.icon);  
    119.             title = (TextView) view.findViewById(R.id.title);  
    120.             msg = (TextView) view.findViewById(R.id.msg);  
    121.             time = (TextView) view.findViewById(R.id.time);  
    122.             deleteHolder = (ViewGroup) view.findViewById(R.id.holder);  
    123.         }  
    124.     }  
    125.   
    126.     @Override  
    127.     public void onItemClick(AdapterView<?> parent, View view, int position,  
    128.             long id) {  
    129.         // 这里处理ListItem的点击事件  
    130.         Log.e(TAG, "onItemClick position=" + position);  
    131.     }  
    132.   
    133.     @Override  
    134.     public void onSlide(View view, int status) {  
    135.         // 如果当前存在已经打开的SlideView,那么将其关闭  
    136.         if (mLastSlideViewWithStatusOn != null  
    137.                 && mLastSlideViewWithStatusOn != view) {  
    138.             mLastSlideViewWithStatusOn.shrink();  
    139.         }  
    140.         // 记录本次处于打开状态的view  
    141.         if (status == SLIDE_STATUS_ON) {  
    142.             mLastSlideViewWithStatusOn = (SlideView) view;  
    143.         }  
    144.     }  
    145.   
    146.     @Override  
    147.     public void onClick(View v) {  
    148.         // 这里处理删除按钮的点击事件,可以删除对话  
    149.         if (v.getId() == R.id.holder) {  
    150.             int position = mListView.getPositionForView(v);  
    151.             if (position != ListView.INVALID_POSITION) {  
    152.                 mMessageItems.remove(position);  
    153.                 mSlideAdapter.notifyDataSetChanged();  
    154.             }  
    155.             Log.e(TAG, "onClick v=" + v);  
    156.         }  
    157.     }  
    158. }  

    代码我都特意写了注释,就不多说了。

  • 相关阅读:
    LINUX 环境变量总结
    make的自动变量和预定义变量
    函数调用约定和堆栈
    如何查看linux命令源代码
    shell脚本中特定符合变量的含义
    【转载】Redhat5和6 YUM源配置的区别
    用路径分析法来编写测试用例
    linux ip 设置
    Mysql 的存储引擎,myisam和innodb的区别。
    一些编译php时的configure 参数
  • 原文地址:https://www.cnblogs.com/weixiao870428/p/3524055.html
Copyright © 2011-2022 走看看