android 自定义view(侧拉删除)

开心一刻:

A:嘿 //是什么意思啊?

B:嘿.

A:呃我问你//是什么意思?

B:问吧.

A:我刚才不是问了么?

B:啊?

A:你再看看记录…

B:看完了.

A:……所以//是啥?

B:所以什么?

扫描二维码关注公众号,回复: 8489148 查看本文章

A:你存心耍我呢吧?

B:没有啊你想问什么?

……

不断循环之后,A一气之下和B绝交,自己苦学程序。

N年之后,A终于修成正果,回想起B

,又把聊天记录翻出来看,这时,他突然发现B没有耍他……

而他自己也不知道当年他问B的究竟是什么问题……

简言:

实现一个侧拉删除的效果,仿照qq侧拉删除,进行功能的简单实现。侧拉删除的效果,还是非常常见的,有一个第三方可以直接引用,之前在项目中实现过一次,今天分享给大家,我提供的是一个demo,比较简单的实现,该demo简单,易扩展。

效果展示:

代码展示:(代码里面有注解 详细讲解了功能的实现)

/**
 * Created by Administrator on 2019/2/19 0019.
 * 策划菜单
 */

public class SlideLayout extends FrameLayout {

    private View contentView;
    private View deleteView;

    private int contentWidth;
    private int deleteWidth;
    private int viewHeight;//他们的高相等
    //滚动器
    private Scroller scroller;
    private float endX;
    private float endY;

    public SlideLayout(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        scroller = new Scroller(context);
    }

    /**
     * 当布局文件加载完成的时候回调方法
     */
    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        contentView = getChildAt(0);
        deleteView = getChildAt(1);
    }

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

        contentWidth = contentView.getMeasuredWidth();
        deleteWidth = deleteView.getMeasuredWidth();
        viewHeight = getMeasuredHeight();
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
        //指定菜单的位置 将删除按钮放置最右边 进行隐藏
        deleteView.layout(contentWidth, 0, contentWidth + deleteWidth, viewHeight);
    }

    private float startX;
    private float startY;
    private float downX;//值赋值一次
    private float downY;

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                //按下记录坐标
                downX = startX = event.getX();
                downY = startY = event.getY();
                break;
            case MotionEvent.ACTION_MOVE:
                //记录我们的结束值
                endX = event.getX();
                endY = event.getY();

                //计算偏移量
                float distancexX = endX - startX;
                int toScrollx = (int) (getScrollX() - distancexX);
                //屏蔽非法值
                if (toScrollx < 0) {
                    toScrollx = 0;
                } else if (toScrollx > deleteWidth) {
                    toScrollx = deleteWidth;
                }
                scrollTo(toScrollx, getScrollY());
                startX = event.getX();
                startY = event.getY();
                //在x轴和Y轴滑动的距离
                float dx = Math.abs(endX - downX);
                float dy = Math.abs(endY - downY);
                if (dx > dy && dx >8) {
                    //水平滑动 响应水平拦截 反拦截 事件给slidlayout
                    getParent().requestDisallowInterceptTouchEvent(true);
                }
                break;
            case MotionEvent.ACTION_UP:
                int totalScrollX = getScrollX();//偏移量
                if (totalScrollX < deleteWidth / 2) {
                    //关闭菜单
                    closeMenu();
                } else {
                    //打开菜单
                    openMenu();
                }
                break;
        }
        return true;
    }

    /**
     * 关闭删除菜单
     */
    public void closeMenu() {

        int distanceX = 0 - getScrollX();
        scroller.startScroll(getScrollX(), getScrollY(), distanceX, getScrollY());
        invalidate();//强制刷新
        if(onStateChangeListener != null){
            onStateChangeListener.onClose(this);
        }
    }

    public void openMenu() {

        int distanceX = deleteWidth - getScrollX();
        scroller.startScroll(getScrollX(), getScrollY(), distanceX, getScrollY());
        invalidate();//强制刷新
        if(onStateChangeListener != null){
            onStateChangeListener.onOpen(this);
        }
    }

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

    /**
     * TRUE 拦截孩子的时间 但会执行当前控件的onTouchEvent方法
     * false 不拦截孩子事件 事件继续传递
     * */
    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
      boolean intercept = false;

        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                //按下记录坐标
                downX = startX = ev.getX();
                if(onStateChangeListener != null){
                    onStateChangeListener.onDown(this);
                }
                break;
            case MotionEvent.ACTION_MOVE:
                //记录我们的结束值
                endX = ev.getX();
                endX = ev.getX();

                //计算偏移量
                float distancexX = endX - startX;
                //在x轴和Y轴滑动的距离
                float dx = Math.abs(endX - downX);
                if (dx > 8) {
                   intercept = true;
                }
                break;
            case MotionEvent.ACTION_UP:
                break;
        }

        return intercept;

    }
/**
 * 监听SlienLayout状态的改变
 *
 * */
    public  interface  onStateChangeListener{
        void onClose(SlideLayout slideLayout);
        void onDown(SlideLayout slideLayout);
        void onOpen(SlideLayout slideLayout);
    }

    private onStateChangeListener onStateChangeListener;

    public void setOnStateChangeListener(SlideLayout.onStateChangeListener onStateChangeListener) {
        this.onStateChangeListener = onStateChangeListener;
    }
}
public class MainActivity extends AppCompatActivity {

    private ListView lv_main;

    private ArrayList<MyBean> list;

    private SlideLayout slideLayouts;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        list = new ArrayList<>();
        initData();
        //添加数据
        initView();
    }

    private void initData() {
        for (int i = 0 ;i<100;i++){
           list.add(new MyBean("CONTENT"+i));
        }
    }

    private void initView() {
        lv_main = findViewById(R.id.lv_main);
        lv_main.setAdapter( new MyAdapter());
    }

    class MyAdapter extends BaseAdapter{

        @Override
        public int getCount() {
            return list.size();
        }

        @Override
        public Object getItem(int position) {
            return null;
        }

        @Override
        public long getItemId(int position) {
            return 0;
        }

        @Override
        public View getView(final int position, View convertView, ViewGroup parent) {
            ViewHolder viewHolder;
         if(convertView == null){
             convertView = View.inflate(MainActivity.this,R.layout.item_main,null);
             viewHolder= new ViewHolder();
             viewHolder.itemContent = convertView.findViewById(R.id.item_content);
             viewHolder.itemMenu = convertView.findViewById(R.id.item_menu);
             convertView.setTag(viewHolder);
         }else{
             viewHolder= (ViewHolder) convertView.getTag();
         }
            final MyBean myBean = list.get(position);
            viewHolder.itemContent.setText(myBean.getName());
            viewHolder.itemContent.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    MyBean myBean1 = list.get(position);
                    Toast.makeText(MainActivity.this,myBean1.getName(),Toast.LENGTH_SHORT).show();
                }
            });
            viewHolder.itemMenu.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    SlideLayout slideLayout = (SlideLayout) v.getParent();
                    slideLayout.closeMenu();
                    list.remove(myBean);
                   notifyDataSetChanged();
                }
            });
            SlideLayout slideLayout = (SlideLayout) convertView;
            slideLayout.setOnStateChangeListener(new SlideLayout.onStateChangeListener() {
                @Override
                public void onClose(SlideLayout slideLayout) {
                    if(slideLayouts == slideLayout){
                        slideLayouts = null;
                    }
                }

                @Override
                public void onDown(SlideLayout slideLayout) {
                    if(slideLayouts !=null &&slideLayouts != slideLayout){
                        slideLayouts.closeMenu();
                    }
                }

                @Override
                public void onOpen(SlideLayout slideLayout) {
                    slideLayouts = slideLayout;
                }
            });
            return convertView;
        }
    }
    static  class  ViewHolder{
        TextView itemContent;
        TextView itemMenu;
    }
}

这是实现的两个主要类(可在博客中进行观看)

自定义的view的使用

<?xml version="1.0" encoding="utf-8"?>
<com.zzsy.listviewdelete.SlideLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="60dp">
<include
    android:id="@+id/item_content"
    layout="@layout/item_content"/>
    <include
        android:id="@+id/item_menu"
        layout="@layout/item_menu"/>
</com.zzsy.listviewdelete.SlideLayout>

项目地址:

https://download.csdn.net/download/wk_beicai/11635506

发布了96 篇原创文章 · 获赞 370 · 访问量 42万+

猜你喜欢

转载自blog.csdn.net/wk_beicai/article/details/100133701