自定义一个带删除按钮的ListView

来源:互联网 发布:淘宝送的优惠券怎么用 编辑:程序博客网 时间:2024/05/21 05:41

OK,回顾一下ListView的内容。
要把数据通过ListView显示到屏幕,那么就要有三个东西,ListView&Adapter&data。

先把全部代码放给大家看吧。
首先是布局文件,分别为Activity.xml布局文件,delete_button.xml布局文件,item_show.xml布局文件。

<?xml version="1.0" encoding="utf-8"?><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:paddingBottom="@dimen/activity_vertical_margin"    android:paddingLeft="@dimen/activity_horizontal_margin"    android:paddingRight="@dimen/activity_horizontal_margin"    android:paddingTop="@dimen/activity_vertical_margin"    tools:context="com.example.listviewdemo.MainActivity">    <com.example.listviewdemo.MyListView        android:layout_width="match_parent"        android:layout_height="match_parent"        android:id="@+id/my_ListView" /></RelativeLayout>
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical">    <Button        android:id="@+id/delete_button"        android:layout_width="match_parent"        android:layout_height="match_parent"        android:text="删除"/></LinearLayout>
<?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:layout_width="match_parent"        android:layout_height="50dp"        android:id="@+id/item_text"        android:layout_centerVertical="true"/></RelativeLayout>

接下来放代码。
首先是activity的代码。

public class MainActivity extends Activity {    private MyListView myListView;    private ArrayList<String> itemList;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        myListView = (MyListView) findViewById(R.id.my_ListView);        //new一个ArrayList,方便存储和提取数据。        itemList = new ArrayList<String>();        //制造数据        init();        final MyAdapter myAdapter = new MyAdapter();        myListView.setAdapter(myAdapter);        myListView.setOnDeleteListener(new MyListView.onDeleteListener() {            @Override            public void onDelete(int index) {                //利用返回的itemIndex,移除对应的item。                itemList.remove(index);                //通知对应的视图进行改变                myAdapter.notifyDataSetChanged();            }        });    }    public class MyAdapter extends BaseAdapter {        //listView里面,一行一行的视图。        private View itemView;        @Override        public int getCount() {            return itemList.size();        }        @Override        public Object getItem(int i) {            return null;        }        @Override        public long getItemId(int i) {            return 0;        }        @Override        public View getView(int i, View view, ViewGroup viewGroup) {            if (view == null) {                itemView = View.inflate(MainActivity.this, R.layout.item_show, null);            } else {                itemView = view;            }            TextView itemText = (TextView) itemView.findViewById(R.id.item_text);            itemText.setText(itemList.get(i));            return itemView;        }    }    public void init() {        for (int i = 1; i < 100; i++) {            StringBuilder itemContent = new StringBuilder("内容");            itemContent.append(i);            itemList.add(itemContent.toString());        }    }}

然后到自定义ListView的代码

/** * 自定义一个ListView,实现一些手势功能。 * 实现GestureDetector.OnGestureListener这个手势监听接口 * Created by Administrator on 2016/8/10. */public class MyListView extends ListView implements GestureDetector.OnGestureListener {    //内部接口    private onDeleteListener listener;    //选择的第几个item    private int selectedItemIndex;    //手势检测    private GestureDetector mGestureDetector;    //屏幕内,选择的item的布局。    private RelativeLayout itemLayout;    //删除按钮    private Button deleteButton;    //全局控制删除按钮变量,boolean默认值是false。    private boolean deleteButtonIsVisible;    private ViewGroup deleteButtonLayout;    public MyListView(Context context, AttributeSet attrs) {        super(context, attrs);        //new一个手势检测对象,表明在MyListView这个类注册手势探测        mGestureDetector = new GestureDetector(context, this);    }    /**     * 按下的时候触发事件     *     * @param motionEvent 按下时候触发的事件。     * @return     */    @Override    public boolean onDown(MotionEvent motionEvent) {        //通过pointToPosition获得点选的item        selectedItemIndex = pointToPosition(((int) motionEvent.getX()), ((int) motionEvent.getY()));        //通过getChildAt获得选择的布局。        itemLayout = (RelativeLayout) getChildAt(selectedItemIndex - getFirstVisiblePosition());        return false;    }    @Override    public void onShowPress(MotionEvent motionEvent) {    }    @Override    public boolean onSingleTapUp(MotionEvent motionEvent) {        return false;    }    @Override    public boolean onScroll(MotionEvent motionEvent, MotionEvent motionEvent1, float v, float v1) {        return false;    }    @Override    public void onLongPress(MotionEvent motionEvent) {    }    /**     * 滑动触发事件     *     * @param e1        开始滑动触发的事件     * @param e2        结束滑动触发的事件     * @param velocityX X轴的滑动速度,为矢量,左向右滑,大于零。右向左滑,小于零。     * @param velocityY Y轴的滑动速度,同上。     * @return     */    @Override    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {        /**         *触发条件为:没有删除按钮,并且X轴的滑动速度大于Y轴滑动速度,并且是从右向左滑。         */        if (!deleteButtonIsVisible && Math.abs(velocityX) > Math.abs(velocityY) && velocityX < 0) {            //获取删除按钮View            deleteButtonLayout = (ViewGroup) View.inflate(getContext(), R.layout.delete_button, null);            deleteButton = (Button) deleteButtonLayout.findViewById(R.id.delete_button);            //把删除按钮从原先的布局去除,方便等会被添加到另一个布局中。            deleteButtonLayout.removeView(deleteButton);            //布局参数设定            RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT,                    RelativeLayout.LayoutParams.WRAP_CONTENT);            params.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);            params.addRule(RelativeLayout.CENTER_IN_PARENT);            //把删除按钮添加入选定的滑动item            itemLayout.addView(deleteButton, params);            //由于添加了,更改deleteButtonIsVisible的值。            deleteButtonIsVisible = true;            deleteButton.setOnClickListener(new OnClickListener() {                @Override                public void onClick(View v) {                    //把结果反馈给Acitivity,然后移除对应的数据。                    listener.onDelete(selectedItemIndex);                    itemLayout.removeView(deleteButton);                    deleteButtonIsVisible = false;                }            });        }        //由于由右向左滑动时,改变了deleteButtonIsVisible的值,所以现在是按钮存在的情况下,X轴速度大于Y轴速度,并且是从由左向右滑动,触发。        else if (deleteButtonIsVisible && Math.abs(velocityX) > Math.abs(velocityY) && velocityX > 0) {            itemLayout.removeView(deleteButton);            deleteButtonIsVisible = false;        }        return false;    }    /**     * 事件先传递到这,然后再传递到手势探测的事件里     *     * @param ev 触摸事件     * @return     */    @Override    public boolean onTouchEvent(MotionEvent ev) {    //把触摸事件传递给手势探测器        mGestureDetector.onTouchEvent(ev);        return super.onTouchEvent(ev);    }    //实现一个内部接口,用于把结果反馈回Activity。    public interface onDeleteListener {        void onDelete(int index);    }    /**     * 提供给外部,从外部传递进来一个接口,用于等会的回调     *     * @param listener     */    public void setOnDeleteListener(onDeleteListener listener) {        this.listener = listener;    }}

实现了从右向左滑动,出现删除按钮,从左向右滑动,删除按钮消失,点击删除按钮,则删除item。
效果图
从右向左滑动,出现删除按钮。
这里写图片描述

从左向右滑动,删除按钮消失。
这里写图片描述

点击删除按钮,删除项目。
这里写图片描述

接下来说一下这个方法。getFirstVisiblePosition(),这个方法有什么作用呢?它的作用是得到当前显示在屏幕上的该列表视图的第一项。这个Position跟List内的数据的位置类似,0代表第一行,9代表第十行。下面我们做个简单的测试。

我们在public boolean onDown(MotionEvent motionEvent){......}里加入两个方法。

        System.out.println("selectedItemIndex的意义:"+selectedItemIndex);        System.out.println("getFirstVisiblePosition的意义:"+getFirstVisiblePosition());

然后我们随便在列表的界面点击,会有结果反馈。我们点击内容18好了。

selectedItemIndex的意义:17getFirstVisiblePosition的意义:11

根据点击得到的反馈结果,相信对之前的这句话“当前显示在屏幕上的该列表视图的第一项”也能够理解了。

0 0
原创粉丝点击