`
tonytony3
  • 浏览: 7935 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

listview 左滑弹出删除按钮,需要折腾一下

阅读更多
基本上关键点在, 1事件, android:longClickable="true" android:descendantFocusability="blocksDescendants" 这个是在item子控件返回true 而使onInterceptTouchEvent 不停有事件来, 2 layout ,的设计,onLayout方法,relativeonLayout好像比较难达到这种拖后还有显示删除按钮 3,一些回调接口,方便toggle



import android.annotation.SuppressLint;

import android.content.Context;

import android.util.AttributeSet;

import android.util.Log;

import android.view.GestureDetector;

import android.view.GestureDetector.SimpleOnGestureListener;

import android.view.MotionEvent;

import android.view.VelocityTracker;

import android.view.View;

import android.view.ViewConfiguration;

import android.widget.LinearLayout;

import android.widget.Scroller;



@SuppressLint("NewApi")

public class SlidingLeftLayout extends LinearLayout {



public SlidingLeftLayout(Context context) {

super(context);

init(context);

}



// public SlidingLeftLayout(Context context, AttributeSet attrs, int

// defStyle) {

// super(context, attrs, defStyle);

// init(context);

// }



public SlidingLeftLayout(Context context, AttributeSet attrs) {

super(context, attrs);

init(context);

}



public SlidingLeftLayout(Context context, AttributeSet attrs, int defStyle) {

super(context, attrs, defStyle);

init(context);

}



public void init(Context context) {

mContext = context;

mScroller = new Scroller(mContext);

ViewConfiguration config = ViewConfiguration.get(context);

mTouchSlop = config.getScaledTouchSlop();

mMinFlingVelocity = config.getScaledMinimumFlingVelocity();

setDescendantFocusability(FOCUS_AFTER_DESCENDANTS);



return;

}



private Context mContext;

private static String TAG = "SlidingLeftRelativeLayout";

private static final boolean DEBUG = true;



private static final int TOUCH_MODE_IDLE = 0;

private static final int TOUCH_MODE_DOWN = 1;

private static final int TOUCH_MODE_DRAGGING = 2;



private int mTouchMode;

private int mTouchSlop;

private VelocityTracker mVelocityTracker;

private int mMinFlingVelocity;

private float mTouchX;

private float mStartX;



private static final int SCREEN_ID_NORMAL = 0;

private static final int SCREEN_ID_LEFT = 1;

private int mCurScreen = SCREEN_ID_NORMAL;



private Scroller mScroller = null;

private int mScrollWidth = 120;



// @Override

// protected void onLayout(boolean changed, int l, int t, int r, int b) {

// super.onLayout(changed, l+mScrollWidth, t+mScrollWidth, r, b);

//

// }



@Override

protected void onLayout(boolean changed, int l, int t, int r, int b) {

super.setOrientation(LinearLayout.HORIZONTAL);

// super.onLayout(changed, l, t, r, b);



int height = getHeight();

int width = getWidth();



int childCount = getChildCount();



for (int i = 0; i < childCount; i++) {

View child = getChildAt(i);

if (child != null && child.getVisibility() != View.GONE) {

if (i == 0) {

child.layout(0, 0, width, height);

} else if (i == 1) {

child.layout(width, 0, width + mScrollWidth, height);

}

}

}



}



// @Override

public boolean onInterceptTouchEvent2(MotionEvent ev) {



final int action = ev.getActionMasked();

if (DEBUG) {

Log.d(TAG, "onInterceptTouchEvent action " + action);

}



if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP) {

if (DEBUG)

Log.d(TAG, "onInterceptTouchEvent ACTION_UP");

if (mTouchMode == TOUCH_MODE_DRAGGING) {

// stopDrag(ev);

}



if (mVelocityTracker != null) {

mVelocityTracker.recycle();

mVelocityTracker = null;

}

if (DEBUG)

Log.d(TAG, "onInterceptTouchEvent return " + false);

return false;

}



// Nothing more to do here if we have decided whether or not we

// are dragging.

if (action != MotionEvent.ACTION_DOWN) {

if (mTouchMode == TOUCH_MODE_DRAGGING) {

if (DEBUG)

Log.v(TAG, "Intercept returning true!");

if (DEBUG)

Log.d(TAG, "onInterceptTouchEvent return " + true);

return true;

}

}



switch (action) {

case MotionEvent.ACTION_MOVE: {

switch (mTouchMode) {

case TOUCH_MODE_IDLE:

break;



case TOUCH_MODE_DOWN: {

final float x = ev.getX();

if (Math.abs(x - mTouchX) > mTouchSlop) {

mTouchMode = TOUCH_MODE_DRAGGING;

getParent().requestDisallowInterceptTouchEvent(true);

mTouchX = x;

if (DEBUG)

Log.d(TAG, "onInterceptTouchEvent return " + true);

return true;

}

break;

}



case TOUCH_MODE_DRAGGING: {

final float x = ev.getX();

final float dx = mTouchX - x;

mStartX = Math.abs(getScrollX());

float newPos = Math.max(0, Math.min(mStartX + dx, mScrollWidth));

if (newPos != mStartX) {

scrollTo((int) newPos, 0);

mTouchX = x;

invalidate();

}

}

}

break;

}



case MotionEvent.ACTION_DOWN: {

// if (mOnSlideListener != null) {

// mOnSlideListener.onSlidingStart(this);

// }

final float x = ev.getX();

mTouchMode = TOUCH_MODE_DOWN;

mTouchX = x;

}

}



if (mVelocityTracker == null) {

mVelocityTracker = VelocityTracker.obtain();

}

mVelocityTracker.addMovement(ev);



if (DEBUG)

Log.d(TAG, "onInterceptTouchEvent return " + (mTouchMode == TOUCH_MODE_DRAGGING));

return mTouchMode == TOUCH_MODE_DRAGGING;



}



public void shrink() {

if (getScrollX() != 0) {

this.smoothScrollTo(0, 0);

// this.scrollTo(0, 0);



}

}



private void smoothScrollTo(int destX, int destY) {

// 缓慢滚动到指定位置

int scrollX = getScrollX();

int delta = destX - scrollX;

mScroller.startScroll(scrollX, 0, delta, 0, Math.abs(delta) * 3);

invalidate();

}



@Override

public void computeScroll() {

if (mScroller.computeScrollOffset()) {

scrollTo(mScroller.getCurrX(), mScroller.getCurrY());

postInvalidate();

}

}



    @Override

    public boolean onInterceptTouchEvent(MotionEvent ev) {

        final int action = ev.getActionMasked();

        if (DEBUG) {

            Log.d(TAG, "onInterceptTouchEvent action " + action);

        }



        if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP) {

            if (DEBUG)

                Log.d(TAG, "onInterceptTouchEvent ACTION_UP");

            if (mTouchMode == TOUCH_MODE_DRAGGING) {

//                stopDrag(ev);

            }



            if (mVelocityTracker != null) {

                mVelocityTracker.recycle();

                mVelocityTracker = null;

            }

            if (DEBUG)

                Log.d(TAG, "onInterceptTouchEvent return " + false);

            return false;

        }



        // Nothing more to do here if we have decided whether or not we

        // are dragging.

        if (action != MotionEvent.ACTION_DOWN) {

            if (mTouchMode == TOUCH_MODE_DRAGGING) {

                if (DEBUG)

                    Log.v(TAG, "Intercept returning true!");

                if (DEBUG)

                    Log.d(TAG, "onInterceptTouchEvent return " + true);

                return true;

            }

        }



        switch (action) {

            case MotionEvent.ACTION_MOVE: {

                switch (mTouchMode) {

                    case TOUCH_MODE_IDLE:

                        break;



                    case TOUCH_MODE_DOWN: {

                        final float x = ev.getX();

                        if (Math.abs(x - mTouchX) > mTouchSlop) {

                            mTouchMode = TOUCH_MODE_DRAGGING;

                            getParent().requestDisallowInterceptTouchEvent(true);

                            mTouchX = x;

                            if (DEBUG)

                                Log.d(TAG, "onInterceptTouchEvent return " + true);

                            return true;

                        }

                        break;

                    }



                    case TOUCH_MODE_DRAGGING: {

                        final float x = ev.getX();

                        final float dx = mTouchX - x;

                        mStartX = Math.abs(getScrollX());

                        float newPos = Math.max(0, Math.min(mStartX + dx, mScrollWidth));

                        if (newPos != mStartX) {

                            scrollTo((int) newPos, 0);

                            mTouchX = x;

                            invalidate();

                        }

                    }

                }

                break;

            }



            case MotionEvent.ACTION_DOWN: {

                if (mOnSlideListener != null) {

//                 mOnSlideListener.onSlideBack();

                    mOnSlideListener.onSlidingStart(this);

                }

                final float x = ev.getX();

                mTouchMode = TOUCH_MODE_DOWN;

                mTouchX = x;

            }

        }



        if (mVelocityTracker == null) {

            mVelocityTracker = VelocityTracker.obtain();

        }

        mVelocityTracker.addMovement(ev);



        if (DEBUG)

            Log.d(TAG, "onInterceptTouchEvent return " + (mTouchMode == TOUCH_MODE_DRAGGING));

        return mTouchMode == TOUCH_MODE_DRAGGING;

    }



    public boolean onTouchEvent(MotionEvent event) {

        if (mVelocityTracker == null) {

            mVelocityTracker = VelocityTracker.obtain();

        }

        mVelocityTracker.addMovement(event);

        final int action = event.getActionMasked();

        if (DEBUG)

            Log.d(TAG, "onTouchEvent action " + action);



        switch (action) {

            case MotionEvent.ACTION_DOWN: {

                final float x = event.getX();

                mTouchMode = TOUCH_MODE_DOWN;

                mTouchX = x;

            }



            case MotionEvent.ACTION_MOVE: {

                switch (mTouchMode) {

                    case TOUCH_MODE_IDLE:

                        break;



                    case TOUCH_MODE_DOWN: {

                        final float x = event.getX();

                        if (Math.abs(x - mTouchX) > mTouchSlop) {

                            mTouchMode = TOUCH_MODE_DRAGGING;

                            getParent().requestDisallowInterceptTouchEvent(true);

                            mTouchX = x;

                            return true;

                        }

                        break;

                    }



                    case TOUCH_MODE_DRAGGING: {

                        final float x = event.getX();

                        final float dx = mTouchX - x;

                        mStartX = Math.abs(getScrollX());

                        float newPos = Math.max(0, Math.min(mStartX + dx, mScrollWidth));

                        Log.d(TAG, "mStartX " + mStartX + " newPos " + newPos);

                        if (newPos != mStartX) {

                            scrollTo((int) newPos, 0);

                            mTouchX = x;

                            invalidate();

                        }

                        return true;

                    }

                }

                break;

            }



            case MotionEvent.ACTION_UP:

            case MotionEvent.ACTION_CANCEL: {

                if (mTouchMode == TOUCH_MODE_DRAGGING) {

//                    stopDrag(event);

                }

                if (mOnSlideListener != null) {

                 mOnSlideListener.onSlideBack();

//                     mOnSlideListener.onSlidingStart(this);

                }

                if (mVelocityTracker != null) {

                    mVelocityTracker.recycle();

                    mVelocityTracker = null;

                }

                break;

            }

        }

        return true;

    }

   

    private OnSlideListener mOnSlideListener;



    public interface OnSlideListener {



        public void onSlideBack();



        public void onSlidingStart(SlidingLeftLayout item);

    }



    public void setSlidingListener(OnSlideListener l) {

        mOnSlideListener = l;

    }

}













import java.io.File;

import java.util.LinkedList;



import org.json.JSONObject;



import android.app.AlertDialog;

import android.content.Context;

import android.content.DialogInterface;

import android.graphics.Bitmap;

import android.view.LayoutInflater;

import android.view.View;

import android.view.View.OnClickListener;

import android.view.ViewGroup;

import android.widget.BaseAdapter;

import android.widget.Button;

import android.widget.ImageView;

import android.widget.RelativeLayout;

import android.widget.TextView;



import com.leo.langtao.bean.FileBean;

import com.leo.langtao.fyrs.R;

import com.leo.langtao.util.BitmapUtil;

import com.leo.langtao.util.JsonUtil;

import com.leo.langtao.util.ViewUtil;

import com.leo.langtao.zxing.view.SlidingLeftLayout;

import com.leo.langtao.zxing.view.SlidingLeftLayout.OnSlideListener;



public class FileAdapter2 extends BaseAdapter implements OnSlideListener{

private Context mContext;

private LinkedList<String> mData;

private String mComer;

private SlidingAdapterInterface mListener;

private SlidingLeftLayout lastSlidingLeftLayout;

private SlidingLeftLayout nowSlidingLeftLayout;



public FileAdapter2(Context ctx, LinkedList<String> data,SlidingAdapterInterface listener) {

mContext = ctx;

mData = data;

mListener = listener;

}



public FileAdapter2(Context ctx, LinkedList<String> data) {

mContext = ctx;

mData = data;

}



public FileAdapter2(Context ctx, LinkedList<String> data, String comer) {

mContext = ctx;

mData = data;

mComer = comer;

}



@Override

public int getCount() {

return mData.size();

}



@Override

public Object getItem(int pos) {

return mData.get(pos);

}



@Override

public long getItemId(int pos) {

return pos;

}



@Override

public View getView(final int pos, View convertView, ViewGroup parent) {

ViewHolder vh = null;

if (convertView == null) {

convertView = LayoutInflater.from(mContext).inflate(

R.layout.item_activity_file_manager_list2, null);

vh = new ViewHolder();

vh.rlo = convertView.findViewById(R.id.rlo);

vh.tvName = ViewUtil.getTextViewById(convertView, R.id.tv_name);

vh.ivIcon = ViewUtil.getImageViewById(convertView, R.id.iv_icon);

vh.btnDel = ViewUtil.getButtonById(convertView, R.id.btn_del_file);

convertView.setTag(vh);

} else {

vh = (ViewHolder) convertView.getTag();

}



final String item = mData.get(pos);

final JSONObject json = JsonUtil.castStringToJson(item);

final FileBean bean = new FileBean(json);

vh.tvName.setText(bean.getName());



if (!bean.isFolder()) {

Bitmap bm = BitmapUtil.getBitmap(bean.getPath(), 50);

vh.ivIcon.setImageBitmap(bm);

}

vh.rlo.setOnClickListener(new View.OnClickListener() {



@Override

public void onClick(View v) {

mListener.onListItemClick(pos);

}

});

 

vh.btnDel.setOnClickListener(new OnClickListener() {



@Override

public void onClick(View v) {



new AlertDialog.Builder(mContext)

.setTitle(R.string.sure_delete)

.setPositiveButton(R.string.IDS_Btn_OK,

new DialogInterface.OnClickListener() {

@Override

public void onClick(DialogInterface dialog,

int which) {

File file = new File(bean.getPath());

if (file != null) {

try {

if (file.isFile()) {

file.delete();

} else if (file.isDirectory()) {



for (File f : file

.listFiles()) {

f.delete();

}

file.delete();

}



} catch (Exception e) {

e.printStackTrace();

}

mData.remove(pos);

notifyDataSetChanged();

}

}

})

.setNegativeButton(R.string.IDS_Btn_Quit,

null).show();



}

});

((SlidingLeftLayout)convertView.findViewById(R.id.slidingLeftLayout)).setSlidingListener(this);

((SlidingLeftLayout)convertView.findViewById(R.id.slidingLeftLayout)).shrink();

return convertView;

}



private class ViewHolder {

TextView tvName;

ImageView ivIcon;

Button btnDel;

View rlo;

}



public interface SlidingAdapterInterface{

void onListItemClick(int pos);

}



@Override

public void onSlideBack() {

if(lastSlidingLeftLayout!=null&&lastSlidingLeftLayout!=nowSlidingLeftLayout)

lastSlidingLeftLayout.shrink();

}



@Override

public void onSlidingStart(SlidingLeftLayout item) {



if(lastSlidingLeftLayout==null){

if(nowSlidingLeftLayout!=null){

lastSlidingLeftLayout = nowSlidingLeftLayout;

}

}else{

lastSlidingLeftLayout = nowSlidingLeftLayout;

}

nowSlidingLeftLayout = 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="wrap_content" >



    <com.leo.langtao.zxing.view.SlidingLeftLayout

        android:id="@+id/slidingLeftLayout"

        android:layout_width="match_parent"

        android:layout_height="50dip" >



        <RelativeLayout

            android:id="@+id/rlo"

            android:layout_width="match_parent"

            android:layout_height="match_parent"

             android:longClickable="true"

            android:descendantFocusability="blocksDescendants" >



            <ImageView

                android:id="@+id/iv_icon"

                android:layout_width="32dip"

                android:layout_height="32dip"

                android:layout_alignParentLeft="true"

                android:layout_centerHorizontal="true"

                android:layout_centerVertical="true"

                android:layout_marginLeft="@dimen/padding_5dip"

                android:layout_marginRight="@dimen/padding_5dip"

                android:background="@drawable/icon_file_item"

                android:focusable="false" />



            <TextView

                android:id="@+id/tv_name"

                android:textSize="15sp"

                android:layout_width="wrap_content"

                android:layout_height="wrap_content"

                android:layout_centerHorizontal="true"

                android:layout_centerVertical="true"

                android:layout_marginLeft="@dimen/margin_8dip"

                android:layout_toRightOf="@+id/iv_icon"

                android:focusable="false"

                android:text="家居1" />

        </RelativeLayout>



        <Button

            android:id="@+id/btn_del_file"

            android:layout_width="32dip"

            android:layout_height="32dip"

            android:layout_alignParentRight="true"

            android:layout_centerHorizontal="true"

            android:layout_centerVertical="true"

            android:layout_marginLeft="@dimen/padding_8dip"

            android:layout_marginRight="@dimen/padding_8dip"

            android:background="@drawable/btn_delete_up"

            android:focusable="false" />

    </com.leo.langtao.zxing.view.SlidingLeftLayout>



</RelativeLayout>
分享到:
评论

相关推荐

    ListView左滑弹出删除按钮完美版

    标题提到的"ListView左滑弹出删除按钮完美版"正是针对这个需求进行的优化,旨在解决在滑动过程中可能出现的显示异常问题。 在标准的ListView中,为了实现左滑删除效果,通常需要自定义Adapter并扩展AbsListView的...

    ListView像左滑动Item显示删除按钮

    总的来说,实现ListView中Item左滑显示删除按钮涉及多个步骤,包括自定义ListView、滑动布局设计、适配器逻辑以及动画效果的添加。使用第三方库可以简化这个过程,但自定义实现可以更好地满足特定需求。在实际开发中...

    模拟微信listview左滑出现删除按钮

    在Android开发中,模拟微信Listview左滑出现删除按钮是一种常见的交互设计,它增强了用户界面的易用性和可操作性。这个功能的核心是利用SwipeRefreshLayout和ListView或RecyclerView结合实现的,接下来我们将深入...

    ListView添加左滑删除控件

    为了增强用户体验和功能,经常需要在ListView中添加一些交互元素,如左滑删除功能。本教程将详细介绍如何在ListView中实现左滑删除控件,并处理状态切换时的保持问题。 一、基本原理 左滑删除功能通常是通过监听...

    listview左滑删除菜单

    "listview左滑删除菜单"是指在ListView的每个Item(列表项)上实现一个可以从左侧滑动出来的删除菜单,这种功能通常被称为Swipe to Delete或者Slide to Remove。在描述中提到的"可单个或者多个菜单"意味着不仅可以为...

    android listview 左滑 删除功能

    综上所述,实现Android ListView的左滑删除功能需要结合自定义Adapter、手势识别、布局设计和动画效果等多个技术点。通过这样的设计,我们可以为用户提供一个直观且易用的界面,增强应用的用户体验。在实际项目中,...

    Android 重写Listview实现左滑删除功能

    要实现左滑删除,我们需要创建一个自定义的ListView Adapter,并在其中嵌入一个可滑动的布局。这个布局通常包含一个主内容视图和一个隐藏的删除按钮。当用户向左滑动ListView的item时,隐藏的删除按钮会被显示出来。...

    android listview 实现左滑删除置顶

    在许多应用中,为了提高用户体验,我们经常需要实现一些高级功能,比如左滑删除和置顶操作。本篇文章将详细介绍如何在Android的ListView中实现这两个特性。 首先,我们要理解ListView的工作原理。ListView通过...

    android studio实现listview的增加,左滑删除

    在本文中,我们将深入探讨如何在Android Studio中实现ListView的动态增加以及左滑删除功能,这将帮助你构建更加用户友好的应用程序。 首先,我们需要创建一个ListView的基础结构。在Android Studio中,打开布局XML...

    ListView的item水平滑动(类QQ的左滑显示删除按钮)

    总结一下,实现“ListView的item水平滑动(类QQ的左滑显示删除按钮)”主要涉及自定义Adapter、滑动事件监听、触摸事件处理、动画效果以及优化措施等知识点。这是一个既实用又有趣的特性,可以显著提升用户的交互体验...

    可左滑删除的listView

    同时,你可能还需要提供一个确认或撤销删除的操作,这可以通过弹出对话框或动画效果来实现。 为了达到类似QQ的效果,你可能还需要考虑以下几点: 1. **平滑动画**:滑动过程应有平滑的动画效果,使用户感觉流畅...

    listview左滑删除下拉刷新上滑加载更多

    通常,我们会为ListView的每一项(ListView的Adapter)添加一个手势监听器,当用户执行左滑操作时,对应的ListView项会显示一个删除按钮或者直接执行删除操作。这需要对Android的触摸事件和动画有深入的理解,以便...

    仿QQ首页ListView左滑置顶删除源码实现

    接着,我们需要对ListView的每个子项(ListView的Adapter中的ViewHolder)添加额外的布局,以显示删除按钮或其他操作元素。这些元素默认是隐藏的,只有在用户左滑时才显示。这可以通过设置View的translationX属性来...

    【android开发】仿QQ中ListView中选项左滑出现删除按钮

    在Android开发中,仿QQ中ListView的左滑删除功能是一项常见的需求,这使得用户能够方便地对列表项进行操作,例如删除。以下是对这个主题的详细解析: 首先,要实现这个功能,我们需要了解ListView的基本原理。...

    模仿QQListView左滑删除置顶Item功能

    在Android开发中,模仿QQListView左滑删除置顶Item的功能是一项常见的需求,它能提供用户友好的交互体验,尤其在消息列表或者任务列表等场景下。这个Demo是针对这一功能的具体实现,旨在帮助开发者理解并掌握相关...

    安卓 带左滑出现删除按钮的ListView

    `带左滑出现删除按钮的ListView` 是一种常见的交互设计,用户可以通过向左滑动列表项来显示一个或多个操作按钮,比如“删除”按钮,提高用户体验。下面将详细解释如何实现这个功能。 首先,我们需要了解ListView的...

    左滑出现删除按钮,点击按钮删除ListView的item条目

    在Android开发中,为了提供用户友好的交互体验,经常需要实现一些特殊的功能,如“左滑显示删除按钮”。这个功能通常被应用于ListView、RecyclerView等可滚动列表视图中,允许用户通过简单的手势来删除列表中的条目...

    listview左滑操作demo

    "listview左滑操作demo"是针对ListView进行的一种常见扩展,它允许用户通过手势从左向右滑动列表项来触发特定的操作,如删除、标记或显示更多信息。这个demo是为了帮助开发者理解和实现这种交互方式。 首先,我们要...

    仿QQ左滑显示删除按钮

    这个功能的核心是利用SwipeRefreshLayout或者自定义布局来实现ListView或者RecyclerView的滑动效果,当用户左滑列表项时,会露出一个包含删除按钮的视图。下面将详细介绍如何实现这一功能。 首先,我们需要了解...

Global site tag (gtag.js) - Google Analytics