生活随笔
收集整理的這篇文章主要介紹了
android listview左滑删除
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
之前,自己使用listview一直是長(zhǎng)按刪除,不過(guò)發(fā)現(xiàn)qq的消息和ios的都是側(cè)滑刪除,覺(jué)得效果很好,于是自己就想做一個(gè)側(cè)滑刪除。在網(wǎng)上找了些資料,有很多不是我理想的側(cè)滑刪除,最后還是找到了一個(gè)不錯(cuò)的,現(xiàn)在記錄一下。
首先是自定義一個(gè)listview,這個(gè)里面需要重寫(xiě)onInterceptTouchEvent和onTouchEvent兩個(gè)代碼,一個(gè)是對(duì)滑動(dòng)進(jìn)行攔截,如果刪除按鈕已經(jīng)顯示,點(diǎn)擊的不是刪除的item,則把按鈕隱藏。另一個(gè)是對(duì)item滑動(dòng)的事件進(jìn)行處理。滑動(dòng)時(shí)item移動(dòng),顯示刪除按鈕。
package com.zviewtech.videonetclient.mydeleteemo
;
import android.content.Context;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.TypedValue;
import android.view.MotionEvent;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.LinearLayout;
import android.widget.ListView;
/**
* Created by JunkChen on 2016/3/29 0029.
*/
public class SideslipListView extends ListView {
private static final String TAG =
"SideslipListView";
private int mScreenWidth;//屏幕的寬度
private boolean isDeleteShow;//刪除組件是否顯示
private ViewGroup mPointChild;//手指按下位置的item組件
private int mDeleteWidth;//刪除組件的寬度
private LinearLayout.LayoutParams mItemLayoutParams;//手指按下時(shí)所在的item的布局參數(shù)
private int mDownX;//手指初次按下的X坐標(biāo)
private int mDownY;//手指初次按下的Y坐標(biāo)
private int mPointPosition;//手指按下位置所在的item位置
private boolean isAllowItemClick;//是否允許item點(diǎn)擊
public SideslipListView(
Context context) {
super(context)
;
init(context)
;
}
public SideslipListView(
Context context
, AttributeSet attrs) {
super(context
, attrs)
;
init(context)
;
}
public SideslipListView(
Context context
, AttributeSet attrs
, int defStyleAttr) {
super(context
, attrs
, defStyleAttr)
;
init(context)
;
}
private void init(
Context context) {
// 獲取屏幕寬度
WindowManager wm = (
WindowManager) context.getSystemService(
Context.
WINDOW_SERVICE)
;
DisplayMetrics dm =
new DisplayMetrics()
;
wm.getDefaultDisplay().getMetrics(
dm)
;
mScreenWidth =
dm.
widthPixels;
Log.
i(
TAG, "***********mScreenWidth: " +
mScreenWidth)
;
}
@Override
public boolean onInterceptTouchEvent(
MotionEvent ev) {
//事件攔截
switch (ev.getAction()) {
case MotionEvent.
ACTION_DOWN: {
isAllowItemClick =
true;
//側(cè)滑刪除
mDownX = (
int) ev.getX()
;
mDownY = (
int) ev.getY()
;
mPointPosition = pointToPosition(
mDownX, mDownY)
;
Log.
i(
TAG, "*******pointToPosition(mDownX, mDownY): " +
mPointPosition)
;
if (
mPointPosition != -
1) {
if (
isDeleteShow) {
ViewGroup tmpViewGroup = (
ViewGroup) getChildAt(
mPointPosition - getFirstVisiblePosition())
;
if (!
mPointChild.equals(
tmpViewGroup)) {turnNormal()
;
}}
//獲取當(dāng)前的item
mPointChild = (
ViewGroup) getChildAt(
mPointPosition - getFirstVisiblePosition())
;
mDeleteWidth =
mPointChild.getChildAt(
1).getLayoutParams().
width;
mItemLayoutParams = (
LinearLayout.LayoutParams)
mPointChild.getChildAt(
0).getLayoutParams()
;
Log.
i(
TAG, "*********mItemLayoutParams.height: " +
mItemLayoutParams.
height +
", mDeleteWidth: " +
mDeleteWidth)
;
mItemLayoutParams.
width =
mScreenWidth;
mPointChild.getChildAt(
0).setLayoutParams(
mItemLayoutParams)
;
}
break;
}
case MotionEvent.
ACTION_MOVE: {
int nowX = (
int) ev.getX()
;
int nowY = (
int) ev.getY()
;
int diffX =
nowX -
mDownX;
Log.
i(
TAG, "******dp2px(4): " + dp2px(
8) +
", dp2px(8): " + dp2px(
8) +
", density: " + getContext().getResources().getDisplayMetrics().
density)
;
if (
Math.
abs(
diffX) > dp2px(
4) ||
Math.
abs(
nowY -
mDownY) > dp2px(
4)) {
return true;//避免子布局中有點(diǎn)擊的控件時(shí)滑動(dòng)無(wú)效
}
break;
}}
return super.onInterceptTouchEvent(ev)
;
}
public float dp2px(
int dp) {
return TypedValue.
applyDimension(
TypedValue.
COMPLEX_UNIT_DIP, dp
,
getContext().getResources().getDisplayMetrics())
;
}
@Override
public boolean onTouchEvent(
MotionEvent ev) {
//事件響應(yīng)
switch (ev.getAction()) {
case MotionEvent.
ACTION_DOWN:performActionDown(ev)
;
break;
case MotionEvent.
ACTION_MOVE:performActionMove(ev)
;
break;
case MotionEvent.
ACTION_UP:performActionUp(ev)
;
break;
}
return super.
onTouchEvent(ev)
;
}
private void performActionDown(
MotionEvent ev) {
mDownX = (
int) ev.getX()
;
mDownY = (
int) ev.getY()
;
if (
isDeleteShow) {
ViewGroup tmpViewGroup = (
ViewGroup) getChildAt(pointToPosition(
mDownX, mDownY) - getFirstVisiblePosition())
;
Log.
i(
TAG, "*********mPointChild.equals(tmpViewGroup): " +
mPointChild.equals(
tmpViewGroup))
;
if (!
mPointChild.equals(
tmpViewGroup)) {turnNormal()
;
}}
//獲取當(dāng)前的item
mPointChild = (
ViewGroup) getChildAt(pointToPosition(
mDownX, mDownY) - getFirstVisiblePosition())
;
mDeleteWidth =
mPointChild.getChildAt(
1).getLayoutParams().
width;//獲取刪除組件的寬度
Log.
i(
TAG, "**********pointToPosition(x,y): " + pointToPosition(
mDownX, mDownY)+
", getFirstVisiblePosition() = " + getFirstVisiblePosition()+
", mDeleteWidth = " +
mDeleteWidth)
;
mItemLayoutParams = (
LinearLayout.LayoutParams)
mPointChild.getChildAt(
0).getLayoutParams()
;
mItemLayoutParams.
width =
mScreenWidth;
mPointChild.getChildAt(
0).setLayoutParams(
mItemLayoutParams)
;
}
private boolean performActionMove(
MotionEvent ev) {
int nowX = (
int) ev.getX()
;
int nowY = (
int) ev.getY()
;
int diffX =
nowX -
mDownX;
if (
Math.
abs(
diffX) >
Math.
abs(
nowY -
mDownY) &&
Math.
abs(
nowY -
mDownY) <
20) {
if (!
isDeleteShow &&
nowX <
mDownX) {
//刪除按鈕未顯示時(shí)向左滑
if (-
diffX >=
mDeleteWidth) {
//如果滑動(dòng)距離大于刪除組件的寬度時(shí)進(jìn)行偏移的最大處理
diffX = -
mDeleteWidth;
}
mItemLayoutParams.
leftMargin =
diffX;
mPointChild.getChildAt(
0).setLayoutParams(
mItemLayoutParams)
;
isAllowItemClick =
false;
}
else if (
isDeleteShow &&
nowX >
mDownX) {
//刪除按鈕顯示時(shí)向右滑
if (
diffX >=
mDeleteWidth) {
diffX =
mDeleteWidth;
}
mItemLayoutParams.
leftMargin =
diffX -
mDeleteWidth;
mPointChild.getChildAt(
0).setLayoutParams(
mItemLayoutParams)
;
isAllowItemClick =
false;
}
return true;
}
return super.
onTouchEvent(ev)
;
}
private void performActionUp(
MotionEvent ev) {
//如果向左滑出超過(guò)隱藏的二分之一就全部顯示
if (-
mItemLayoutParams.
leftMargin >=
mDeleteWidth /
2) {
mItemLayoutParams.
leftMargin = -
mDeleteWidth;
isDeleteShow =
true;
mPointChild.getChildAt(
0).setLayoutParams(
mItemLayoutParams)
;
}
else {turnNormal()
;
}}
/**
* 轉(zhuǎn)換為正常隱藏情況
*/
public void turnNormal() {
mItemLayoutParams.
leftMargin =
0;
mPointChild.getChildAt(
0).setLayoutParams(
mItemLayoutParams)
;
isDeleteShow =
false;
}
/**
* 是否允許Item點(diǎn)擊
*
* @return
*/
public boolean isAllowItemClick() {
return isAllowItemClick;
}
}
這個(gè)listview主要是設(shè)置leftMargin這個(gè)左偏移來(lái)保證按鈕的顯示和隱藏的。activity里調(diào)用的代碼也很簡(jiǎn)單
package com.zviewtech.videonetclient.mydeleteemo
;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.TextView;
import android.widget.Toast;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
private static final String TAG =
"MainActivity";
private SideslipListView mSideslipListView;
/**
* 初始化數(shù)據(jù)
*/
private ArrayList<
String>
mDataList =
new ArrayList<
String>() {{
for (
int i =
0; i <
50; i++) {add(
"ListView item " +
i)
;
}}}
;
@Override
protected void onCreate(
Bundle savedInstanceState) {
super.onCreate(savedInstanceState)
;
setContentView(
R.layout.
activity_main)
;
mSideslipListView = (
SideslipListView) findViewById(
R.id.
sideslipListView)
;
mSideslipListView.setAdapter(
new CustomAdapter())
;//設(shè)置適配器
//設(shè)置item點(diǎn)擊事件
mSideslipListView.setOnItemClickListener(
new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(
AdapterView parent
, View view
, int position
, long id) {
if (
mSideslipListView.isAllowItemClick()) {
Log.
i(
TAG, mDataList.get(position) +
"被點(diǎn)擊了")
;
Toast.
makeText(
MainActivity.
this, mDataList.get(position) +
"被點(diǎn)擊了",
Toast.
LENGTH_SHORT).show()
;
}}})
;
//設(shè)置item長(zhǎng)按事件
mSideslipListView.setOnItemLongClickListener(
new AdapterView.OnItemLongClickListener() {
@Override
public boolean onItemLongClick(
AdapterView parent
, View view
, int position
, long id) {
if (
mSideslipListView.isAllowItemClick()) {
Log.
i(
TAG, mDataList.get(position) +
"被長(zhǎng)按了")
;
Toast.
makeText(
MainActivity.
this, mDataList.get(position) +
"被長(zhǎng)按了",
Toast.
LENGTH_SHORT).show()
;
return true;//返回true表示本次事件被消耗了,若返回
}
return false;
}})
;
}
/**
* 自定義ListView適配器
*/
class CustomAdapter extends BaseAdapter {
@Override
public int getCount() {
return mDataList.size()
;
}
@Override
public Object getItem(
int position) {
return mDataList.get(position)
;
}
@Override
public long getItemId(
int position) {
return position
;
}
@Override
public View getView(
int position
, View convertView
, ViewGroup parent) {
ViewHolder viewHolder;
if (
null == convertView) {convertView =
View.
inflate(
MainActivity.
this, R.layout.
item, null)
;
viewHolder =
new ViewHolder()
;
viewHolder.
textView = (
TextView) convertView.findViewById(
R.id.
textView)
;
viewHolder.
txtv_delete = (
TextView) convertView.findViewById(
R.id.
txtv_delete)
;
convertView.setTag(
viewHolder)
;
}
else {
viewHolder = (
ViewHolder) convertView.getTag()
;
}
viewHolder.
textView.setText(
mDataList.get(position))
;
final int pos = position
;
viewHolder.
txtv_delete.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(
View v) {
Toast.
makeText(
MainActivity.
this, mDataList.get(
pos) +
"被刪除了",
Toast.
LENGTH_SHORT).show()
;
mDataList.remove(
pos)
;
notifyDataSetChanged()
;
mSideslipListView.turnNormal()
;
}})
;
return convertView
;
}}
class ViewHolder {
public TextView textView;
public TextView txtv_delete;
}
}
其實(shí)和普通的listview是一致的,只是在點(diǎn)擊時(shí)判斷滑動(dòng)變量,如果為true,則不響應(yīng)點(diǎn)擊事件。如果為false,則響應(yīng)點(diǎn)擊事件。
listview的item的布居我要顯示出來(lái),因?yàn)檫@和自定義的listview的代碼相關(guān),必須是這樣的,如果修改,則mDeleteWidth = mPointChild.getChildAt(1).getLayoutParams().width;這里也必須做相應(yīng)的修改,getChild()的參數(shù)和刪除按鈕的位置一致
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="wrap_content" >
<LinearLayout android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="8dp">
<TextView
android:id="@+id/textView"
android:layout_width="match_parent"
android:layout_height="48dp"
android:textSize="18sp"
android:text="text">
</TextView>
</LinearLayout>
<!--必須指定寬度-->
<TextView android:id="@+id/txtv_delete" android:layout_width="96dp"
android:layout_height="match_parent"
android:textSize="18sp" android:text="刪除" android:textColor="#eeeeee" android:gravity="center" android:background="#e53935">
</TextView>
</LinearLayout>
listview的滑動(dòng)刪除就完成了。
就這么簡(jiǎn)單。
總結(jié)
以上是生活随笔為你收集整理的android listview左滑删除的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。