android 滑動刪除的listview(自定義view)

許佳佳233發表於2016-03-29

本篇文章算是對郭霖前輩的一篇文章的詳述:

一方面是筆者自己嘗試從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:

package com.example.deleteitemlist;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {
    private MyListView myListView;

    private MyAdapter adapter;

    private List<String> contentList = new ArrayList<String>();

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

        //初始化自定的listview中的資訊
        initList();

        myListView = (MyListView) findViewById(R.id.my_list_view);
        //實現onDelete介面
        myListView.setOnDeleteListener(new MyListView.OnDeleteListener() {
            @Override
            public void onDelete(int index) {
                //刪除傳過來的位置的item,並且重新整理adapter
                contentList.remove(index);
                adapter.notifyDataSetChanged();
            }
        });
        adapter = new MyAdapter(this, 0, contentList);
        myListView.setAdapter(adapter);
    }

    private void initList() {
        contentList.add("Content Item 1");
        contentList.add("Content Item 2");
        contentList.add("Content Item 3");
        contentList.add("Content Item 4");
        contentList.add("Content Item 5");
        contentList.add("Content Item 6");
        contentList.add("Content Item 7");
        contentList.add("Content Item 8");
        contentList.add("Content Item 9");
        contentList.add("Content Item 10");
        contentList.add("Content Item 11");
        contentList.add("Content Item 12");
        contentList.add("Content Item 13");
        contentList.add("Content Item 14");
        contentList.add("Content Item 15");
        contentList.add("Content Item 16");
        contentList.add("Content Item 17");
        contentList.add("Content Item 18");
        contentList.add("Content Item 19");
        contentList.add("Content Item 20");
    }
}

MyAdapter:

package com.example.deleteitemlist;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;

import java.util.List;

/**
 * 專案名稱:DeleteItemList
 * 類描述:
 * 建立人:佳佳
 * 建立時間:2016/3/28 11:16
 * 修改人:佳佳
 * 修改時間:2016/3/28 11:16
 * 修改備註:
 */
public class MyAdapter extends ArrayAdapter<String> {

    public MyAdapter(Context context, int textViewResourceId, List<String> objects) {
        super(context, textViewResourceId, objects);
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View view;
        if (convertView == null) {
            view = LayoutInflater.from(getContext()).inflate(R.layout.my_list_view_item, null);
        } else {
            view = convertView;
        }
        TextView textView = (TextView) view.findViewById(R.id.text_view);
        textView.setText(getItem(position));
        return view;
    }

}

MyListView:

package com.example.deleteitemlist;

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;

/**
 * 專案名稱:DeleteItemList
 * 類描述:
 * 建立人:佳佳
 * 建立時間:2016/3/28 11:14
 * 修改人:佳佳
 * 修改時間:2016/3/28 11:14
 * 修改備註:
 */
public class MyListView extends ListView implements View.OnTouchListener,
        GestureDetector.OnGestureListener {

    private GestureDetector gestureDetector;
    //設定OnDeleteListener的介面,在MainActivity使用的時候實現
    private OnDeleteListener listener;

    private View deleteButton;

    private ViewGroup itemLayout;

    private int selectedItem;

    private boolean isDeleteShown;

    public MyListView(Context context, AttributeSet attrs) {
        super(context, attrs);
        gestureDetector = new GestureDetector(getContext(), this);
        setOnTouchListener(this);
    }

    public void setOnDeleteListener(OnDeleteListener l) {
        listener = l;
    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        //如果點選這個自定義的listview的時候已經顯示了一個deleteButton了
        //那麼就讓這個deleteButton消失,並且讓isDeleteShown表示沒有deleteButton顯示
        if (isDeleteShown) {
            itemLayout.removeView(deleteButton);
            deleteButton = null;
            isDeleteShown = false;
            return false;
        } else {
            //如果沒有顯示deleteButton,很可能是第一次開啟這個view
            //就使用GestureDetector來檢測是否觸發了特定的手勢動作
            return gestureDetector.onTouchEvent(event);
        }
    }

    @Override
    public boolean onDown(MotionEvent e) {
        //如果deleteButton已經顯示,那麼通過他的xy的位置來獲取它在listview中的位置
        if (!isDeleteShown) {
            selectedItem = pointToPosition((int) e.getX(), (int) e.getY());
        }
        return false;
    }

    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
                           float velocityY) {
        //如果deleteButton不可見 ,而且X的速度的絕對值大於Y的速度的絕對值的時候(手勢橫向滑動的時候)
        if (!isDeleteShown && Math.abs(velocityX) > Math.abs(velocityY)) {
            deleteButton = LayoutInflater.from(getContext()).inflate(
                    R.layout.delete_button, null);
            deleteButton.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    itemLayout.removeView(deleteButton);
                    deleteButton = null;
                    isDeleteShown = false;
                    listener.onDelete(selectedItem);
                }
            });
            //此處itemLayout獲取到的是textview的父佈局RelativeLayout
            itemLayout = (ViewGroup) getChildAt(selectedItem
                    - getFirstVisiblePosition());
            RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
                    LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
            params.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
            params.addRule(RelativeLayout.CENTER_VERTICAL);
            //設定好了deleteButton的點選效果、佈局,新增這個button
            itemLayout.addView(deleteButton, params);
            //設定isDeleteShown為true,表示deleteButton已經顯示
            isDeleteShown = true;
        }
        return false;
    }

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

    @Override
    public void onShowPress(MotionEvent e) {

    }

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

    @Override
    public void onLongPress(MotionEvent e) {
    }

    //設定OnDeleteListener的介面,在MainActivity使用的時候實現
    public interface OnDeleteListener {

        void onDelete(int index);

    }

}

activity_main:

<?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"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin">

    <com.example.deleteitemlist.MyListView
        android:id="@+id/my_list_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"></com.example.deleteitemlist.MyListView>

</RelativeLayout>


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:text="delete">

</Button>  

my_list_view_item:

<?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/text_view"
        android:layout_width="wrap_content"
        android:layout_height="50dp"
        android:layout_centerVertical="true"
        android:gravity="left|center_vertical"
        android:textColor="#000" />

</RelativeLayout>


原始碼地址:http://download.csdn.net/detail/double2hao/9475061

相關文章