Android仿QQ左滑刪除置頂ListView操作
最近閑來(lái)無(wú)事,于是研究了一下qq的左滑刪除效果,嘗試著實(shí)現(xiàn)了一下,先上效果圖:

大致思路原理:
- 通過(guò)設(shè)置margin實(shí)現(xiàn)菜單的顯示與隱藏
- 監(jiān)聽onTouchEvent,處理滑動(dòng)事件
上代碼
import android.content.Context;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.MotionEvent;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.LinearLayout;
import android.widget.ListView;
/**
* Created by MooreLi on 2016/8/8.
*/
public class SlideListView extends ListView {
private String TAG = getClass().getSimpleName();
private int mScreenWidth;
private int mDownX;
private int mDownY;
private int mMenuWidth;
private boolean isMenuShow;
private boolean isMoving;
private int mOperatePosition = -1;
private ViewGroup mPointChild;
private LinearLayout.LayoutParams mLayoutParams;
public SlideListView(Context context) {
super(context);
getScreenWidth(context);
}
public SlideListView(Context context, AttributeSet attrs) {
super(context, attrs);
getScreenWidth(context);
}
public SlideListView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
getScreenWidth(context);
}
private void getScreenWidth(Context context) {
WindowManager manager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics dm = new DisplayMetrics();
manager.getDefaultDisplay().getMetrics(dm);
mScreenWidth = dm.widthPixels;
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
performActionDown(ev);
break;
case MotionEvent.ACTION_MOVE:
performActionMove(ev);
break;
case MotionEvent.ACTION_UP:
performActionUp();
break;
}
return super.onTouchEvent(ev);
}
private void performActionDown(MotionEvent ev) {
mDownX = (int) ev.getX();
mDownY = (int) ev.getY();
//如果點(diǎn)擊的不是同一個(gè)item,則關(guān)掉正在顯示的菜單
int position = pointToPosition(mDownX, mDownY);
if (isMenuShow && position != mOperatePosition) {
turnToNormal();
}
mOperatePosition = position;
mPointChild = (ViewGroup) getChildAt(position - getFirstVisiblePosition());
if (mPointChild != null) {
mMenuWidth = mPointChild.getChildAt(1).getLayoutParams().width;
mLayoutParams = (LinearLayout.LayoutParams) mPointChild.getChildAt(0).getLayoutParams();
mLayoutParams.width = mScreenWidth;
setChildLayoutParams();
}
}
private boolean performActionMove(MotionEvent ev) {
int nowX = (int) ev.getX();
int nowY = (int) ev.getY();
// if (isMoving) {
// if (Math.abs(nowY - mDownY) > 0) {
// Log.e(TAG, "kkkkkkk");
// onInterceptTouchEvent(ev);
// }
// }
if (Math.abs(nowX - mDownX) > 0) {
//左滑 顯示菜單
if (nowX < mDownX) {
if (isMenuShow) {
mLayoutParams.leftMargin = -mMenuWidth;
} else {
//計(jì)算顯示的寬度
int scroll = (nowX - mDownX);
if (-scroll >= mMenuWidth) {
scroll = -mMenuWidth;
}
mLayoutParams.leftMargin = scroll;
}
}
//右滑 如果菜單顯示狀態(tài),則關(guān)閉菜單
if (isMenuShow && nowX > mDownX) {
int scroll = nowX - mDownX;
if (scroll >= mMenuWidth) {
scroll = mMenuWidth;
}
mLayoutParams.leftMargin = scroll - mMenuWidth;
}
setChildLayoutParams();
isMoving = true;
return true;
}
return super.onTouchEvent(ev);
}
private void performActionUp() {
//超過(guò)一半時(shí),顯示菜單,否則隱藏
if (-mLayoutParams.leftMargin >= mMenuWidth / 2) {
mLayoutParams.leftMargin = -mMenuWidth;
setChildLayoutParams();
isMenuShow = true;
} else {
turnToNormal();
}
isMoving = false;
}
private void setChildLayoutParams(){
if(mPointChild != null){
mPointChild.getChildAt(0).setLayoutParams(mLayoutParams);
}
}
/**
* 正常顯示
*/
public void turnToNormal() {
mLayoutParams.leftMargin = 0;
mOperatePosition = -1;
setChildLayoutParams();
isMenuShow = false;
}
}
item的布局要注意,因?yàn)樵谧远xview中寫死的是獲取第一個(gè)子布局為顯示內(nèi)容,所以需要將顯示的樣式寫在一個(gè)容器中,將菜單寫在另一個(gè)容器中,兩個(gè)平行的關(guān)系。
xml文件定義如下:
<?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="wrap_content" android:background="#FFFFFF" android:orientation="horizontal"> <LinearLayout android:layout_width="match_parent" android:layout_height="60dp" android:orientation="horizontal"> <TextView android:id="@+id/main_tv_title" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_marginLeft="10dp" android:gravity="center_vertical" android:textSize="18sp" /> </LinearLayout> <LinearLayout android:layout_width="180dp" android:layout_height="60dp" android:orientation="horizontal"> <TextView android:id="@+id/main_tv_delete" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:background="#FF0000" android:gravity="center" android:text="刪除" android:textColor="#FFFFFF" /> <TextView android:id="@+id/main_tv_top" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:background="#DFCDBF" android:gravity="center" android:text="置頂" android:textColor="#FFFFFF" /> </LinearLayout> </LinearLayout>
最后就是刪除操作與置頂操作,這個(gè)就比較簡(jiǎn)單,給按鈕添加點(diǎn)擊事件即可。我是在adapter中定義實(shí)現(xiàn),記得操作后要將菜單關(guān)掉!
上部分代碼:
holder.tvTitle.setText(mInfos.get(position));
holder.tvDelete.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mInfos.remove(position);
notifyDataSetChanged();
mListView.turnToNormal();
}
});
holder.tvTop.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String temp = mInfos.get(position);
mInfos.remove(position);
mInfos.add(0, temp);
notifyDataSetChanged();
mListView.turnToNormal();
}
});
最后還有一個(gè)遺留問(wèn)題,ListView左右滑動(dòng)的時(shí)候上下也會(huì)滑動(dòng),這個(gè)有待探索與改進(jìn),也希望大家提提意見,幫我改進(jìn)!
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- android實(shí)現(xiàn)簡(jiǎn)單左滑刪除控件
- Android實(shí)現(xiàn)左滑刪除列表功能
- Android使用CardView作為RecyclerView的Item并實(shí)現(xiàn)拖拽和左滑刪除
- Android仿QQ列表左滑刪除操作
- Android使用PullToRefresh完成ListView下拉刷新和左滑刪除功能
- Android ListView實(shí)現(xiàn)仿iPhone實(shí)現(xiàn)左滑刪除按鈕的簡(jiǎn)單實(shí)例
- Android自定義組合控件之自定義下拉刷新和左滑刪除實(shí)例代碼
- Android實(shí)現(xiàn)左滑刪除控件
相關(guān)文章
Android實(shí)現(xiàn)可輸入數(shù)據(jù)的彈出框
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)可輸入數(shù)據(jù)的彈出框,文章提供了兩種方式,示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-01-01
Android編程實(shí)現(xiàn)自定義ImageView圓圖功能的方法
這篇文章主要介紹了Android編程實(shí)現(xiàn)自定義ImageView圓圖功能的方法,結(jié)合實(shí)例形式分析了Android自定義ImageView及實(shí)現(xiàn)圓圖效果的具體步驟與相關(guān)操作技巧,需要的朋友可以參考下2017-08-08
Android 用HttpURLConnection訪問(wèn)網(wǎng)絡(luò)的方法
下面小編就為大家分享一篇Android 用HttpURLConnection訪問(wèn)網(wǎng)絡(luò)的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-01-01
在Android Studio中設(shè)置Button透明度的方法詳解
本文將介紹在Android Studio中如何設(shè)置Button的透明度,首先,我們將展示實(shí)現(xiàn)該功能的整個(gè)流程,并使用表格列出每個(gè)步驟,然后,我們將詳細(xì)說(shuō)明每個(gè)步驟需要做什么,并提供相應(yīng)的代碼和注釋,需要的朋友可以參考下2023-09-09
Android RadioGroup 設(shè)置某一個(gè)選中或者不可選中的方法
下面小編就為大家?guī)?lái)一篇Android RadioGroup 設(shè)置某一個(gè)選中或者不可選中的方法。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-04-04
一文詳解無(wú)痕埋點(diǎn)在Android中的實(shí)現(xiàn)
很多時(shí)候因?yàn)楫a(chǎn)品都會(huì)要獲取用戶的行為,需要客戶端進(jìn)行相關(guān)的埋點(diǎn),下面這篇文章主要給大家介紹了關(guān)于無(wú)痕埋點(diǎn)在Android中實(shí)現(xiàn)的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-02-02
android實(shí)現(xiàn)滾動(dòng)文本效果
這篇文章主要為大家詳細(xì)介紹了android實(shí)現(xiàn)滾動(dòng)文本效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-05-05
android實(shí)現(xiàn)通知欄下載更新app示例
這篇文章主要介紹了android實(shí)現(xiàn)通知欄下載更新app示例,需要的朋友可以參考下2014-03-03
Android 游戲引擎libgdx 資源加載進(jìn)度百分比顯示案例分析
因?yàn)榘咐容^簡(jiǎn)單,所以簡(jiǎn)單用AndroidApplication -> Game -> Stage 搭建框架感興趣的朋友可以參考下2013-01-01
Android應(yīng)用開發(fā)中Fragment與Activity間通信示例講解
這篇文章主要介紹了Android應(yīng)用開發(fā)中Fragment與Activity間通信實(shí)例講解,需要的朋友可以參考下2016-02-02

