android 侧拉删除-仿qq侧拉删除(自定义view)

先看下效果

 

首先把这个自定义view放到项目下


import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Interpolator;
import android.widget.Scroller;


/**
 * Created by DU on 2018/11/20.
 */

public class SwipeView extends ViewGroup{

    private int downX, moveX, moved;
    private Scroller scroller = new Scroller(getContext());
    private boolean haveShowRight = false;
    public static SwipeView swipeMenu;


    public SwipeView(Context context) {
        super(context);
    }


    public SwipeView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public SwipeView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        if (swipeMenu != null) {
            swipeMenu.closeMenus();
            swipeMenu = null;
        }

    }

    //缓慢滚动到指定位置
    private void smoothScrollTo(int destX, int destY) {
        int scrollX = getScrollX();
        int delta = destX - scrollX;
        //1000ms内滑动destX,效果就是慢慢滑动
        scroller.startScroll(scrollX, 0, delta, 0, 100);
        invalidate();
    }

    public void closeMenus() {
        smoothScrollTo(0, 0);
        haveShowRight = false;
    }

    public static void closeMenu() {
        swipeMenu.closeMenus();
    }

    @Override
    public void computeScroll() {
        if (scroller.computeScrollOffset()) {
            scrollTo(scroller.getCurrX(), scroller.getCurrY());
            postInvalidate();
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        if (!scroller.isFinished()) {
            return false;
        }
        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                downX = (int) ev.getRawX();
                break;
            case MotionEvent.ACTION_MOVE:
                if (swipeMenu != null && swipeMenu == this && haveShowRight) {
                    closeMenu();
                    return true;
                }
                moveX = (int) ev.getRawX();

                moved = moveX - downX;

                if (haveShowRight) {
                    moved -= getChildAt(1).getMeasuredWidth();
                }
                scrollTo(-moved, 0);
                if (getScrollX() <= 0) {
                    scrollTo(0, 0);
                } else if (getScrollX() >= getChildAt(1).getMeasuredWidth()) {
                    scrollTo(getChildAt(1).getMeasuredWidth(), 0);
                }
                break;
            case MotionEvent.ACTION_CANCEL:
            case MotionEvent.ACTION_UP:
                if (swipeMenu != null) {
                    closeMenu();
                }
                if (getScrollX() >= getChildAt(1).getMeasuredWidth() / 2) {
                    haveShowRight = true;
                    swipeMenu = this;
                    smoothScrollTo(getChildAt(1).getMeasuredWidth(), 0);
                } else {
                    haveShowRight = false;
                    smoothScrollTo(0, 0);
                }

                break;

        }
        return true;
    }

    @Override
    public LayoutParams generateLayoutParams(AttributeSet attrs) {
        return new MarginLayoutParams(getContext(), attrs);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        measureChildren(widthMeasureSpec, heightMeasureSpec);

        int width = MeasureSpec.getSize(widthMeasureSpec);
        View child = getChildAt(0);
        int margin =
                ((MarginLayoutParams) child.getLayoutParams()).topMargin +
                        ((MarginLayoutParams) child.getLayoutParams()).bottomMargin;
        setMeasuredDimension(width, getChildAt(0).getMeasuredHeight() + margin);
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        int cCount = getChildCount();
        for (int i = 0; i < cCount; i++) {
            View child = getChildAt(i);
            if (i == 0) {
                child.layout(l, t, r, b);
            } else if (i == 1) {
                child.layout(r, t, r + child.getMeasuredWidth(), b);
            }
        }
    }

}

然后再在xml里面定义 (listviewitem要用的xml里面)

最外层一定要用FrameLayout

SwipeView里面分为两部分一部分是列表item要用的布局,第二部分是要隐藏在屏幕外面的删除按钮,我这里用的就是一个按钮标识删除,当然大家也可以用Linearlayout或者Relativelayout来表示更多想侧拉出来的效果

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <com.example.administrator.standardOA.view.SwipeView
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">

            <TextView
                android:id="@+id/cOmmtv"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_gravity="center_vertical"
                android:layout_weight="8"
                android:padding="@dimen/dp_5"
                android:textSize="@dimen/sp_20" />

            <View
                android:layout_width="match_parent"
                android:layout_height="@dimen/dp_1"
                android:layout_marginBottom="@dimen/dp_2"
                android:layout_marginLeft="@dimen/dp_10"
                android:layout_marginRight="@dimen/dp_10"
                android:layout_marginTop="@dimen/dp_1"
                android:background="#EFEFEF" />
        </LinearLayout>
        //这里就是隐藏到屏幕外边的删除按钮
        <Button
            android:id="@+id/tv_usb_delete"
            android:layout_width="@dimen/dp_50"
            android:layout_height="wrap_content"
            android:background="@drawable/bg_cancel"
            android:gravity="center"
            android:padding="@dimen/dp_5"
            android:text="删除"
            android:textColor="@color/white"
            android:textSize="@dimen/sp_20" />

    </com.example.administrator.standardOA.view.SwipeView>


</FrameLayout>

然后adapter里面正常使用

然后要在合适的地方上关闭已经打开的viewgroup


    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        ViewHolder viewHolder;
        if (convertView == null) {
            viewHolder = new ViewHolder();
            convertView = View.inflate(context, R.layout.celaitem, null);
            viewHolder.cOmmontv = convertView.findViewById(R.id.cOmmtv);
            viewHolder.tv_usb_delete = convertView.findViewById(R.id.tv_usb_delete);
            convertView.setTag(viewHolder);
        } else {
            viewHolder = (ViewHolder) convertView.getTag();
        }
        viewHolder.cOmmontv.setText(list.get(position).getCommonSentence());
        viewHolder.tv_usb_delete.setGravity(Gravity.CENTER);
        //删除按钮的点击事件
        viewHolder.tv_usb_delete.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(final View v) {
              
                 list.remove(position);        
                  //关闭删除按钮
                 SwipeView.closeMenu();
                 notifyDataSetChanged();

            }
        });


        return convertView;
    }

ok到这里就可以去看效果啦,activity的xml还有listview设置数据的代码没有列出来,可以根据自己需求使用哦,recyclerview也可用哦

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值