码迷,mamicode.com
首页 > 其他好文 > 详细

自定义listView添加滑动删除功能

时间:2015-06-23 06:11:07      阅读:139      评论:0      收藏:0      [点我收藏+]

标签:

今天研究了一下android里面的手势,结合昨天学习的自定义View,做了一个自定义的listview,继承自listView,添加了条目的滑动手势操作,滑动后出现一个删除按钮,点击删除按钮,触发一个删除的事件,在事件中进行删除当选行的元素,刷新listview。

一共分为以下几步进行:

1、新建一个按钮的布局文件,用来作为动态添加的按钮:layout_button.xml

<?xml version="1.0" encoding="utf-8"?>
<Button 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:text="删除"
    android:layout_width="wrap_content"  
  android:layout_height="wrap_content" 
    android:id="@+id/btn1"/>

2、定义按钮显示,隐藏的动画效果,简单的缩放动画:

btn_hide.xml:

<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
  android:fromXScale="1.0"   
  android:toXScale="0"   
  android:fromYScale="1.0"   
  android:toYScale="1.0"   
  android:pivotX="100%"  
  android:pivotY="0"  
  android:duration="200"
  />

btn_show.xml:

<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
  android:fromXScale="0"   
  android:toXScale="1.0"   
  android:fromYScale="1.0"   
  android:toYScale="1.0"   
  android:pivotX="100%"  
  android:pivotY="0"  
  android:duration="200"
  />

3、自定义ListView,继承自listView,并实现OnTouchListener,OnGestureListener接口,代码就不一步一步写了,里面我尽可能的注释详细一些:MyListView.java

package com.example.viewtest;

import android.content.Context;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.GestureDetector.OnGestureListener;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;
import android.view.animation.AnimationUtils;
import android.widget.ListView;
import android.widget.RelativeLayout;
  /**      
 * 项目名称:viewTest  
 * 实现功能:  自定义ListView,增加滑动删除功能
 * 类名称:MyListView   
 * 类描述:(该类的主要功能)
 * 创建人:徐纪伟 
 * E-mail: xujiwei558@126.com
 * 创建时间:2014年11月2日 下午3:37:40   
 * 修改人:   
 * 修改时间:   
 * 修改备注:   
 * @version    
 */
public class MyListView extends ListView implements OnTouchListener,OnGestureListener {
  
    /**
     * 手势识别类
     */
    private GestureDetector gestureDetector;
    
    /**
     * 滑动时出现的按钮
     */
    private View btnDelete;
    
    /**
     * listview的每一个item的布局
     */
    private ViewGroup viewGroup;
    /**
     * 选中的项
     */
    private int selectedItem;
    
    /**
     * 是否已经显示删除按钮
     */
    private boolean isDeleteShow;
    
    /**
     * 点击删除按钮时删除每一行的事件监听器
     */
    private OnItemDeleteListener onItemDeleteListener;

    /**
     * 构造函数,初始化手势监听器等
     * @param context
     * @param attrs
     */
    public MyListView(Context context, AttributeSet attrs) {
      super(context, attrs);
      gestureDetector = new GestureDetector(getContext(),this);
      setOnTouchListener(this);
    }
    

    public void setOnItemDeleteListener(OnItemDeleteListener onItemDeleteListener) {
      this.onItemDeleteListener = onItemDeleteListener;
    }



    @Override
    public boolean onTouch(View v, MotionEvent event) {
      //得到当前触摸的条目
      selectedItem = pointToPosition((int)event.getX(), (int)event.getY());
      //如果删除按钮已经显示,那么隐藏按钮,异常按钮在当前位置的绘制
      if (isDeleteShow) {
        btnHide(btnDelete);
        viewGroup.removeView(btnDelete);
        btnDelete = null;
        isDeleteShow = false;
        return false;
      }else{
        //如果按钮没显示,则触发手势事件
        //由此去触发GestureDetector的事件,可以查看其源码得知,onTouchEvent中进行了手势判断,调用onFling
        return gestureDetector.onTouchEvent(event);
      }
      
    }

    @Override
    public boolean onDown(MotionEvent e) {
      //得到当前触摸的条目
      if (!isDeleteShow) {
        selectedItem = pointToPosition((int)e.getX(), (int)e.getY());
      }
      return true;
    }

    @Override
    public void onShowPress(MotionEvent e) {
      
    }

    @Override
    public boolean onSingleTapUp(MotionEvent e) {
      return false;
    }

    @Override
    public boolean onScroll(MotionEvent e1, MotionEvent e2,
        float distanceX, float distanceY) {
      return false;
    }

    @Override
    public void onLongPress(MotionEvent e) {
      
    }

    /**
     * 滑动删除的主要响应方法。
     */
    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
        float velocityY) {
      //如果删除按钮没有显示,并且手势滑动符合我们的条件
      //此处可以根据需要进行手势滑动的判断,如限制左滑还是右滑,我这里是左滑右滑都可以
      if (!isDeleteShow && Math.abs(velocityX) > Math.abs(velocityY)) {
        //在当前布局上,动态添加我们的删除按钮,设置按钮的各种参数、事件,按钮的点击事件响应我们的删除项监听器
        btnDelete = LayoutInflater.from(getContext()).inflate(R.layout.layout_button, null);
        btnDelete.setOnClickListener(new OnClickListener() {
          
          @Override
          public void onClick(View v) {
            //btnHide(btnDelete);
            viewGroup.removeView(btnDelete);  
            btnDelete = null;  
            isDeleteShow = false;  
                      onItemDeleteListener.onItemDelete(selectedItem);  
          }
        });
        viewGroup = (ViewGroup)getChildAt(selectedItem - getFirstVisiblePosition());
        RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
        layoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);  
        layoutParams.addRule(RelativeLayout.CENTER_VERTICAL);  
        btnDelete.setLayoutParams(layoutParams);
        viewGroup.addView(btnDelete);
        btnShow(btnDelete);
        isDeleteShow = true; 
      }else{
        setOnTouchListener(this);
      }
      
      return false;
    }

    /**
        * @类名称: OnItemDeleteListener
        * @描述: 删除按钮监听器
        * @throws 
        * @author 徐纪伟
        * 2014年11月9日上午11:25:37
     */
    public interface OnItemDeleteListener{
      public void onItemDelete(int selectedItem);
    }
    
    /**
      * @方法名称: btnShow
  * @描述: 按钮显示时的动画
  * @param   @param v 
  * @return void 
  * @throws 
  * @author 徐纪伟
  * 2014年11月9日 上午11:25:12
   */
private void btnShow(View v){
  v.startAnimation(AnimationUtils.loadAnimation(getContext(), R.anim.btn_show));
  }
/**
  * @方法名称: btnHide
  * @描述: 按钮隐藏时的动画
  * @param   @param v 
  * @return void 
  * @throws 
  * @author 徐纪伟
  * 2014年11月9日 上午11:25:23
   */
private void btnHide(View v){
  v.startAnimation(AnimationUtils.loadAnimation(getContext(), R.anim.btn_hide));
  }
  
}

4、使用方法,布局文件,activity,很简单activity_main.xml:

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:id="@+id/main_layout"
  android:layout_width="match_parent"
  android:layout_height="match_parent" >


   <com.example.viewtest.MyListView
     android:id="@+id/my_listview"
     android:layout_width="match_parent"
     android:layout_height="match_parent">
     
   </com.example.viewtest.MyListView>
</RelativeLayout>

listview的每一个item的布局文件,一个textview,item.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="match_parent"
  android:layout_height="match_parent" >

  <TextView
    android:id="@+id/textView1"
    android:layout_width="wrap_content"
    android:layout_height="50dp"
    android:text="TextView" />
  
</RelativeLayout>

activity,初始化listview,adapter的使用就不在介绍,跟普通的一样,唯一不同的就是,要给我们的自定义listview添加我们自定义的删除按钮单击事件,以此来响应我们的删除事件,MainActivity.java:

package com.example.viewtest;

import java.util.LinkedList;
import java.util.List;

import android.content.Context;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

import com.example.viewtest.MyListView.OnItemDeleteListener;

public class MainActivity extends ActionBarActivity {
  
  /**
   * 自定义listview对象
   */
  private MyListView myListview;
  /**
   * listView的数据集合
   */
  private List<String> contentList = new LinkedList<String>();
  /**
   * 自定义数据适配器
   */
  private MyAdapter adapter;
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    //初始化数据
    setData();
    myListview = (MyListView)findViewById(R.id.my_listview);
    adapter = new MyAdapter(this);
    myListview.setAdapter(adapter);
    //添加自定义listview的按钮单击事件,处理删除结果,和普通listview使用的唯一不同之处,
    myListview.setOnItemDeleteListener(new OnItemDeleteListener() {  
      @Override  
      public void onItemDelete(int index) {  
        contentList.remove(index);  
        adapter.notifyDataSetChanged();  
      }  
    });  
  }

  @Override
  public boolean onCreateOptionsMenu(Menu menu) {

    
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
  }

  @Override
  public boolean onOptionsItemSelected(MenuItem item) {
    
    int id = item.getItemId();
    if (id == R.id.action_settings) {
      return true;
    }
    return super.onOptionsItemSelected(item);
  }
  
  /**
      * @类名称: MyAdapter
      * @描述: 自定义数据适配器
      * @throws 
      * @author 徐纪伟
      * 2014年11月9日下午12:20:19
   */
  class MyAdapter extends BaseAdapter{
    
    private Context context;
    public MyAdapter(Context context) {
      this.context = context;
    }

    @Override
    public int getCount() {
      // TODO Auto-generated method stub
      return contentList.size();
    }

    @Override
    public Object getItem(int position) {
      // TODO Auto-generated method stub
      return contentList.get(position);
    }

    @Override
    public long getItemId(int position) {
      // TODO Auto-generated method stub
      return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
      if (convertView == null) {
        convertView = LayoutInflater.from(context).inflate(R.layout.item, null);
      }
      TextView textView = (TextView)convertView.findViewById(R.id.textView1);
      textView.setText(contentList.get(position));
      return convertView;
    }
  }
  
  /**
    * @方法名称: setData
    * @描述: 初始化数据
    * @param	
    * @return void 
    * @throws 
    * @author 徐纪伟
    * 2014年11月9日 下午12:20:32
   */
  private void setData() {  
    
    for (int i = 0; i < 30; i++) {
       contentList.add("Item "+i);  
    }
  }  

}

运行效果:

技术分享

再给button加上selector背景,更好看一些:selector_btn_red.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
    <item android:state_pressed="true" android:drawable="@drawable/btn_style_zero_pressed"></item>
    <item android:state_pressed="false" android:drawable="@drawable/btn_style_zero_normal"></item>

</selector>

资源图片在附件源码中上传。

最终效果:

技术分享

图片显示的位置在自定义listview中可以调整。

自定义listView添加滑动删除功能

标签:

原文地址:http://www.cnblogs.com/exmyth/p/4594359.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!