android 滑动删除的listview(自定义view)

本篇文章算是对郭霖前辈的一篇文章的详述:

一方面是笔者自己尝试从demo中理解了一下自定义view,另一方面是笔者希望通过更详细的注释已经解说,能帮助新手更容易地理解自定义view的使用。

郭霖前辈原文地址:http://blog.csdn.net/guolin_blog/article/details/17357967

 

首先还是展示一下效果:(源码在文章结尾)

 

新手比较难理解的几点:(此处新手不懂可以根据源码来看)

1、onFling()函数,新手可以暂且认为他就是设置滑动效果的函数。

 

onFling(MotionEvent e1, MotionEvent e2, float velocityX,float velocityY)

 

 

onFling函数的参数的解释如下:

e1: 起点

e2: 终点

velocityX: x轴速度

velocityY: y轴速度

 

2、

 

相信大家都可以理解,这个函数是获取listview中的某个item。另外我们可以看到,itemLayout是viewgroup类型的,而之后它获取到的是textview的父布局RelativeLayout。(布局可见my_list_view_item.xml)

为什么不直接给ArrayAdapter设置一个textview而要用一个RelativeLayout来包含呢?因为我们之后需要在这个RelativeLayout中添加一个删除的button。

 

 

代码截图:

 

MainActivity:

 

[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. package com.example.deleteitemlist;  
  2.   
  3. import android.os.Bundle;  
  4. import android.support.v7.app.AppCompatActivity;  
  5.   
  6. import java.util.ArrayList;  
  7. import java.util.List;  
  8.   
  9. public class MainActivity extends AppCompatActivity {  
  10.     private MyListView myListView;  
  11.   
  12.     private MyAdapter adapter;  
  13.   
  14.     private List<String> contentList = new ArrayList<String>();  
  15.   
  16.     @Override  
  17.     protected void onCreate(Bundle savedInstanceState) {  
  18.         super.onCreate(savedInstanceState);  
  19.         setContentView(R.layout.activity_main);  
  20.   
  21.         //初始化自定的listview中的信息  
  22.         initList();  
  23.   
  24.         myListView = (MyListView) findViewById(R.id.my_list_view);  
  25.         //实现onDelete接口  
  26.         myListView.setOnDeleteListener(new MyListView.OnDeleteListener() {  
  27.             @Override  
  28.             public void onDelete(int index) {  
  29.                 //删除传过来的位置的item,并且刷新adapter  
  30.                 contentList.remove(index);  
  31.                 adapter.notifyDataSetChanged();  
  32.             }  
  33.         });  
  34.         adapter = new MyAdapter(this, 0, contentList);  
  35.         myListView.setAdapter(adapter);  
  36.     }  
  37.   
  38.     private void initList() {  
  39.         contentList.add("Content Item 1");  
  40.         contentList.add("Content Item 2");  
  41.         contentList.add("Content Item 3");  
  42.         contentList.add("Content Item 4");  
  43.         contentList.add("Content Item 5");  
  44.         contentList.add("Content Item 6");  
  45.         contentList.add("Content Item 7");  
  46.         contentList.add("Content Item 8");  
  47.         contentList.add("Content Item 9");  
  48.         contentList.add("Content Item 10");  
  49.         contentList.add("Content Item 11");  
  50.         contentList.add("Content Item 12");  
  51.         contentList.add("Content Item 13");  
  52.         contentList.add("Content Item 14");  
  53.         contentList.add("Content Item 15");  
  54.         contentList.add("Content Item 16");  
  55.         contentList.add("Content Item 17");  
  56.         contentList.add("Content Item 18");  
  57.         contentList.add("Content Item 19");  
  58.         contentList.add("Content Item 20");  
  59.     }  
  60. }  


MyAdapter:

 

 

[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. package com.example.deleteitemlist;  
  2.   
  3. import android.content.Context;  
  4. import android.view.LayoutInflater;  
  5. import android.view.View;  
  6. import android.view.ViewGroup;  
  7. import android.widget.ArrayAdapter;  
  8. import android.widget.TextView;  
  9.   
  10. import java.util.List;  
  11.   
  12. /** 
  13.  * 项目名称:DeleteItemList 
  14.  * 类描述: 
  15.  * 创建人:佳佳 
  16.  * 创建时间:2016/3/28 11:16 
  17.  * 修改人:佳佳 
  18.  * 修改时间:2016/3/28 11:16 
  19.  * 修改备注: 
  20.  */  
  21. public class MyAdapter extends ArrayAdapter<String> {  
  22.   
  23.     public MyAdapter(Context context, int textViewResourceId, List<String> objects) {  
  24.         super(context, textViewResourceId, objects);  
  25.     }  
  26.   
  27.     @Override  
  28.     public View getView(int position, View convertView, ViewGroup parent) {  
  29.         View view;  
  30.         if (convertView == null) {  
  31.             view = LayoutInflater.from(getContext()).inflate(R.layout.my_list_view_item, null);  
  32.         } else {  
  33.             view = convertView;  
  34.         }  
  35.         TextView textView = (TextView) view.findViewById(R.id.text_view);  
  36.         textView.setText(getItem(position));  
  37.         return view;  
  38.     }  
  39.   
  40. }  


MyListView:

 

 

[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. package com.example.deleteitemlist;  
  2.   
  3. import android.content.Context;  
  4. import android.util.AttributeSet;  
  5. import android.view.GestureDetector;  
  6. import android.view.LayoutInflater;  
  7. import android.view.MotionEvent;  
  8. import android.view.View;  
  9. import android.view.ViewGroup;  
  10. import android.widget.ListView;  
  11. import android.widget.RelativeLayout;  
  12.   
  13. /** 
  14.  * 项目名称:DeleteItemList 
  15.  * 类描述: 
  16.  * 创建人:佳佳 
  17.  * 创建时间:2016/3/28 11:14 
  18.  * 修改人:佳佳 
  19.  * 修改时间:2016/3/28 11:14 
  20.  * 修改备注: 
  21.  */  
  22. public class MyListView extends ListView implements View.OnTouchListener,  
  23.         GestureDetector.OnGestureListener {  
  24.   
  25.     private GestureDetector gestureDetector;  
  26.     //设置OnDeleteListener的接口,在MainActivity使用的时候实现  
  27.     private OnDeleteListener listener;  
  28.   
  29.     private View deleteButton;  
  30.   
  31.     private ViewGroup itemLayout;  
  32.   
  33.     private int selectedItem;  
  34.   
  35.     private boolean isDeleteShown;  
  36.   
  37.     public MyListView(Context context, AttributeSet attrs) {  
  38.         super(context, attrs);  
  39.         gestureDetector = new GestureDetector(getContext(), this);  
  40.         setOnTouchListener(this);  
  41.     }  
  42.   
  43.     public void setOnDeleteListener(OnDeleteListener l) {  
  44.         listener = l;  
  45.     }  
  46.   
  47.     @Override  
  48.     public boolean onTouch(View v, MotionEvent event) {  
  49.         //如果点击这个自定义的listview的时候已经显示了一个deleteButton了  
  50.         //那么就让这个deleteButton消失,并且让isDeleteShown表示没有deleteButton显示  
  51.         if (isDeleteShown) {  
  52.             itemLayout.removeView(deleteButton);  
  53.             deleteButton = null;  
  54.             isDeleteShown = false;  
  55.             return false;  
  56.         } else {  
  57.             //如果没有显示deleteButton,很可能是第一次开启这个view  
  58.             //就使用GestureDetector来检测是否触发了特定的手势动作  
  59.             return gestureDetector.onTouchEvent(event);  
  60.         }  
  61.     }  
  62.   
  63.     @Override  
  64.     public boolean onDown(MotionEvent e) {  
  65.         //如果deleteButton已经显示,那么通过他的xy的位置来获取它在listview中的位置  
  66.         if (!isDeleteShown) {  
  67.             selectedItem = pointToPosition((int) e.getX(), (int) e.getY());  
  68.         }  
  69.         return false;  
  70.     }  
  71.   
  72.     @Override  
  73.     public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,  
  74.                            float velocityY) {  
  75.         //如果deleteButton不可见 ,而且X的速度的绝对值大于Y的速度的绝对值的时候(手势横向滑动的时候)  
  76.         if (!isDeleteShown && Math.abs(velocityX) > Math.abs(velocityY)) {  
  77.             deleteButton = LayoutInflater.from(getContext()).inflate(  
  78.                     R.layout.delete_button, null);  
  79.             deleteButton.setOnClickListener(new OnClickListener() {  
  80.                 @Override  
  81.                 public void onClick(View v) {  
  82.                     itemLayout.removeView(deleteButton);  
  83.                     deleteButton = null;  
  84.                     isDeleteShown = false;  
  85.                     listener.onDelete(selectedItem);  
  86.                 }  
  87.             });  
  88.             //此处itemLayout获取到的是textview的父布局RelativeLayout  
  89.             itemLayout = (ViewGroup) getChildAt(selectedItem  
  90.                     - getFirstVisiblePosition());  
  91.             RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(  
  92.                     LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);  
  93.             params.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);  
  94.             params.addRule(RelativeLayout.CENTER_VERTICAL);  
  95.             //设置好了deleteButton的点击效果、布局,添加这个button  
  96.             itemLayout.addView(deleteButton, params);  
  97.             //设置isDeleteShown为true,表示deleteButton已经显示  
  98.             isDeleteShown = true;  
  99.         }  
  100.         return false;  
  101.     }  
  102.   
  103.     @Override  
  104.     public boolean onSingleTapUp(MotionEvent e) {  
  105.         return false;  
  106.     }  
  107.   
  108.     @Override  
  109.     public void onShowPress(MotionEvent e) {  
  110.   
  111.     }  
  112.   
  113.     @Override  
  114.     public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,  
  115.                             float distanceY) {  
  116.         return false;  
  117.     }  
  118.   
  119.     @Override  
  120.     public void onLongPress(MotionEvent e) {  
  121.     }  
  122.   
  123.     //设置OnDeleteListener的接口,在MainActivity使用的时候实现  
  124.     public interface OnDeleteListener {  
  125.   
  126.         void onDelete(int index);  
  127.   
  128.     }  
  129.   
  130. }  


activity_main:

 

 

[html] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent"  
  5.     android:paddingBottom="@dimen/activity_vertical_margin"  
  6.     android:paddingLeft="@dimen/activity_horizontal_margin"  
  7.     android:paddingRight="@dimen/activity_horizontal_margin"  
  8.     android:paddingTop="@dimen/activity_vertical_margin">  
  9.   
  10.     <com.example.deleteitemlist.MyListView  
  11.         android:id="@+id/my_list_view"  
  12.         android:layout_width="match_parent"  
  13.         android:layout_height="wrap_content"></com.example.deleteitemlist.MyListView>  
  14.   
  15. </RelativeLayout>  

 

 

delete_button:

 

[html] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <Button xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:id="@+id/delete_button"  
  4.     android:layout_width="wrap_content"  
  5.     android:layout_height="wrap_content"  
  6.     android:text="delete">  
  7.   
  8. </Button>    


my_list_view_item:

 

 

[html] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent"  
  5.     >  
  6.   
  7.     <TextView  
  8.         android:id="@+id/text_view"  
  9.         android:layout_width="wrap_content"  
  10.         android:layout_height="50dp"  
  11.         android:layout_centerVertical="true"  
  12.         android:gravity="left|center_vertical"  
  13.         android:textColor="#000" />  
  14.   
  15. </RelativeLayout>  



 

源码地址:http://download.csdn.net/detail/double2hao/9475061

posted @ 2016-12-01 21:30  天涯海角路  阅读(269)  评论(0)    收藏  举报