首页 > 代码库 > 自定义View之可删除item的ListView

自定义View之可删除item的ListView

MainActivity如下:

package com.francis.deletablelistview;

import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.SimpleAdapter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

public class MainActivity extends Activity {
    private MyListView myListView;
    private SimpleAdapter mSimpleAdapter;
    private ArrayList mArrayList;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initList();
    }

    private void initList() {
        myListView = (MyListView) findViewById(R.id.my_list_view);

        mArrayList = new ArrayList<HashMap<String,String>>();
        HashMap<String,String> hashMap = null;
        for (int i = 0; i < 10; i++) {
            hashMap=new HashMap<String, String>();
            hashMap.put("name","Francis"+i);
            mArrayList.add(hashMap);
        }
        mSimpleAdapter = new SimpleAdapter(this,mArrayList,R.layout.my_list_view_item,new String[]{"name"},new int[]{R.id.text_view});
        myListView.setAdapter(mSimpleAdapter);
        myListView.setOnDeleteListener(new MyListView.OnDeleteListener() {
            @Override
            public void onDelete(int index) {
                mArrayList.remove(index);
                mSimpleAdapter.notifyDataSetChanged();
            }
        });
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
}

MyListView 如下:

package com.francis.deletablelistview;

import android.content.Context;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListView;
import android.widget.RelativeLayout;

/**
 * Created by Francis on 14-9-23.
 */
public class MyListView extends ListView implements View.OnTouchListener,GestureDetector.OnGestureListener {
    private GestureDetector mGestureDetector;
    private Boolean isDeleteShown = false;
    private ViewGroup itemLayout;
    private View deleteButton;
    private int selecetedItem;
    private OnDeleteListener mOnDeleteListener;

    public MyListView(Context context, AttributeSet attrs) {
        super(context, attrs);
        // 创建GestureDetector实例用于监听手势
        mGestureDetector = new GestureDetector(getContext(),this);
        // 给MyListView注册touch监听事件
        setOnTouchListener(this);
    }
    public void setOnDeleteListener(OnDeleteListener onDeleteListener) {
        mOnDeleteListener = onDeleteListener;
    }
    //定义一个接口
    public interface  OnDeleteListener {
        void onDelete(int index);
    }

    //------>以下方法为OnGestureListener接口的实现
    // 轻触触摸屏,由MotionEvent ACTION_DOWN触发
    @Override
    public boolean onDown(MotionEvent e) {
        if (!isDeleteShown) {
            // return The position of the item which contains the specified point
            selecetedItem = pointToPosition((int)e.getX(),(int)e.getY());
        }
        return false;
    }
    // 按住或者拖动的状态(和onDown的区别),由MotionEvent ACTION_DOWN触发
    @Override
    public void onShowPress(MotionEvent e) {

    }
    // 触摸后松开,由MotionEvent ACTION_UP触发
    @Override
    public boolean onSingleTapUp(MotionEvent e) {
        return false;
    }
    // 按下触摸屏、并拖动,由一个ACTION_DOWN、多个ACTION_MOVE触发
    @Override
    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
        return false;
    }
    //长按触摸屏,由多个ACION_DOWN触发
    @Override
    public void onLongPress(MotionEvent e) {

    }
    // 按下触摸屏、快速移动后松开,由一个ACTION_DOWN、多个ACTION_MOVE、一个ACTION_UP触发
    // e1: 第一个ACTION_DOWN MotionEvent 并且只有一个
    // e2: 最后一个ACTION_MOVE MotionEvent
    // volocityX: X轴上的移动速度
    // volocityY: Y轴上的移动速度
    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
        if (!isDeleteShown && Math.abs(velocityX) > Math.abs(velocityY)) {
            deleteButton = LayoutInflater.from(getContext()).inflate(R.layout.delete_button,null);
            // 回调MainActivty中的onDelete
            deleteButton.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    itemLayout.removeView(deleteButton);
                    deleteButton = null;
                    isDeleteShown = false;
                    mOnDeleteListener.onDelete(selecetedItem);
                }
            });
            // 在选择的item上添加deleteButton
            itemLayout = (ViewGroup) getChildAt(selecetedItem - getFirstVisiblePosition());
            RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
            params.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
            params.addRule(RelativeLayout.CENTER_VERTICAL);
            itemLayout.addView(deleteButton);
            isDeleteShown = true;
        }
        return false;
    }
    //------>以下方法为OnTouchListener接口的实现
    // onTouch作为中转站,触发OnGestureListener的callback
    // 如果删除按钮已经显示,就将它移除掉。
    // 如果删除按钮没有显示,使用GestureDetector来处理当前手势。
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        if (isDeleteShown) {
            itemLayout.removeView(deleteButton);
            deleteButton = null;
            isDeleteShown = false;
            return false;
        } else {
            return mGestureDetector.onTouchEvent(event);
        }
    }


}
activity_main.xml如下:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    tools:context=".MainActivity">

    <com.francis.deletablelistview.MyListView
        android:id="@+id/my_list_view"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content">

    </com.francis.deletablelistview.MyListView>
</RelativeLayout>

my_list_view_item如下:

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">
    <TextView
        android:id="@+id/text_view"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" />

</LinearLayout>

delete_button如下:

<?xml version="1.0" encoding="utf-8"?>

<Button xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/delete_button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@drawable/delete_button">

</Button>



自定义View之可删除item的ListView