Android 使用Scroller来实现item滑动删除

Android 使用Scroller来滑动到指定的位置实现item过度效果,通过scrollBy()方法进行持续滑动。

这里写图片描述

自定义控件实现让自己的view变得绚丽多彩,简单来实现通过滑动item来点击删除。先来定义一个自定View,继承LinearLayout实现OnTouchListener接口,后面通过该接口的方法进行回调。

package map.example.com.scrollerandview;

import android.content.Context;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.Scroller;

/**
 * Created by wg on 2017/10/11.
 */

public class SlidingLinearLayout extends LinearLayout implements View.OnTouchListener {

    //使用Scroller来实现滑动过度效果
    private Scroller mScroller = new Scroller(getContext());

    //记录正在移动中的值
    private int tempX;

    //正在移动的点的值
    private int moveX;

    //控制滑动的方向,第一次从左往右可以进行滑动
    private boolean isLeftMove = true;

    //第一次从右往左不可滑动
    private boolean isRightMove = false;

    //用来存放子view的宽度
    private int[] viewWidths = new int[3];

    //隐藏view的宽度
    private int hideViewWidth;

    //指定滑动距离超过100时松开手判断最终的滑动
    private int distance = 100;

    public SlidingLinearLayout(Context context) {
        super(context);
        init();
    }

    public SlidingLinearLayout(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public SlidingLinearLayout(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        //设置监听器通过回调来调用接口中方法
        setOnTouchListener(this);

    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        //获取每个子view的宽度存入viewWidths数组中
        for (int i = 0; i < getChildCount(); i++) {
            //getChilt(i) 获取第i个view的对象,getMeasuredWidth() 获取测量的宽度
            viewWidths[i] = getChildAt(i).getMeasuredWidth();
        }
        //计算隐藏view的总宽度
        hideViewWidth = viewWidths[1] + viewWidths[2];
    }

    @Override
    public void computeScroll() {
        if (mScroller.computeScrollOffset()) {
            //通过scrollTo移动到给定的位置
            scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
            //重绘执行computeScroll()方法
            postInvalidate();
        }
    }

    public void smoothScrollTo(int destX) {
        int scrollX = getScrollX();
        int deltaX = destX - scrollX;
        //0.5s内移动view内容
        mScroller.startScroll(scrollX, 0, deltaX, 0, 500);
        //重绘执行computeScroll()方法
        invalidate(); 
    }


    @Override
    public boolean onTouch(View v, MotionEvent event) {
        //处理移动
        move(event);
        return true;
    }

    private void move(MotionEvent event) {
        //获取滑动的值,向左滑动scrollX值增大,向右滑动scrollX值减小
        int scrollX = getScrollX();

        switch (event.getAction()) {

            case MotionEvent.ACTION_DOWN: {
                //记录按下的值
                tempX = (int) event.getX();
                break;
            }

            case MotionEvent.ACTION_MOVE: {
                //记录当前正在移动的值
                moveX = (int) event.getX();

                //向左滑动,scrollX的值小于hideViewWidth,最后一个view右边在屏幕最右边
                if (moveX < tempX && scrollX < hideViewWidth) {
                    //通过向左滑动差值进行移动
                    scrollBy(tempX - moveX, 0);

                }

                //向右滑动,使scroll的值大于0,第一个view左边与在屏幕最左边
                if (moveX > tempX && scrollX > 0) { //向右滑动
                    //通过向右滑动差值进行移动
                    scrollBy(tempX - moveX, 0);

                }

                //向右滑动到左边界时,第一个view的左边在屏幕最左边的右边时,则将view左边移动到屏幕的最左边
                if (scrollX < 0) {
                    scrollTo(0, 0);
                }


                //向左滑动到右边界时,第一个view的右边在屏幕最右边的左边时,则将view右边移动到屏幕的最右边
                if (scrollX > hideViewWidth) {
                    scrollTo(hideViewWidth, 0);
                }

                //保留移动点的距离
                tempX = moveX;

                break;
            }

            case MotionEvent.ACTION_UP: {
                // isLeftMove 默认是true
                // isRightMove 默认是false
                //view处于屏幕左边界状态,从右向左滑动,scrollX大于distance时,将滑动view处于右边界状态
                if (scrollX > distance && isLeftMove) {
                    //滑动到右边界状态
                    smoothScrollTo(hideViewWidth);
                    //手势向左滑动无效
                    isLeftMove = false;
                    //手势可以向右滑动
                    isRightMove = true;
                } else if (scrollX < hideViewWidth - distance && isRightMove) { //view处于屏幕右边界状态,从左向右滑动,scrollX小于hideViewWidth - distance时,将滑动view处于左边界状态
                    //滑动到左边界状态
                    smoothScrollTo(0);
                    //手势可以向左滑动
                    isLeftMove = true;
                    //手势向右滑动无效
                    isRightMove = false;
                }

                //处于左边界时,当滑动的scrollX的值小于distance时,则还是处于左边界
                if (scrollX < distance && isLeftMove) {
                    //滑动到左边界
                    smoothScrollTo(0);
                } else if (scrollX > hideViewWidth - distance && isRightMove) {//处于右边界时,当滑动的scrollX的值大于hideViewWidth - distance时,则还是处于右边界
                    //滑动到右边界
                    smoothScrollTo(hideViewWidth);
                }

                break;
            }

            default:
                break;
        }

    }
}

在activity_main使用自定义的SlidingLinearLayout

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="map.example.com.scrollerandview.MainActivity">


    <map.example.com.scrollerandview.SlidingLinearLayout
        android:id="@+id/sliding_linearlayout2"
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:orientation="horizontal">

        <TextView
            android:id="@+id/content_text"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:text="Scroller And View"
            android:background="#8DC3CF"
            android:gravity="center_vertical"
            android:textSize="18dp">

        </TextView>

        <Button
            android:id="@+id/delete_but"
            android:layout_width="100dp"
            android:layout_height="match_parent"
            android:text="Delete"
            android:background="#ff0000"
            android:textColor="#ffffff"
            android:textSize="18dp"
            android:gravity="center"/>

        <Button
            android:id="@+id/istop_but"
            android:layout_width="100dp"
            android:layout_height="match_parent"
            android:text="Istop"
            android:background="#ffff00"
            android:textColor="#ffffff"
            android:textSize="18dp"
            android:gravity="center"/>

    </map.example.com.scrollerandview.SlidingLinearLayout>

</LinearLayout>

在MainActivity中监听delete按钮在onClick方法toast

package map.example.com.scrollerandview;

import android.content.Context;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        final Context mContext = this;
        findViewById(R.id.delete_but).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(mContext,"删除",Toast.LENGTH_SHORT).show();
            }
        });
    }

总结:Scroller实现view缓慢移动到指定位置的内容进行移动,scrollBy()移动内容的位置,不会更改view的实际位置。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值