zoukankan      html  css  js  c++  java
  • Android-自定义仿QQ列表Item滑动

    效果图:

    布局中去指定自定义FrameLayout:

    <!-- 自定义仿QQ列表Item滑动 -->
    <view.custom.shangguigucustomview.MyCustomFrameLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="80dp"
        android:orientation="vertical"
        tools:context=".ShangGuiguTestActivity"
        android:background="@android:color/darker_gray">
    
        <TextView
            android:id="@+id/tv_content"
            android:layout_width="match_parent"
            android:layout_height="80dp"
            android:background="@android:color/white"
            android:textColor="@android:color/black"
            android:textSize="20dp"
            android:text="你有一条消息未读"
            android:gravity="center"
            android:drawableLeft="@mipmap/ic_launcher_round"
            android:paddingRight="40dp"
            />
    
        <TextView
            android:id="@+id/tv_menu"
            android:layout_width="wrap_content"
            android:layout_height="80dp"
            android:background="@android:color/holo_orange_dark"
            android:textColor="#f00000"
            android:textSize="20dp"
            android:text="删除"
            android:gravity="center"
            android:paddingLeft="30dp"
            android:paddingRight="30dp"
            />
    
    </view.custom.shangguigucustomview.MyCustomFrameLayout>

    自定义FrameLayout:

    public class MyCustomFrameLayout extends FrameLayout { // 继承于FrameLayout属于继承ViewGroup,因为它包含了孩子
    
        private static final String TAG = MyCustomFrameLayout.class.getSimpleName();
    
        /**
         * 拿到两个控件的宽和三个的高
         * @param context
         * @param attrs
         */
        private int myHeigth; // 统一的高度
        private int myContentWidth; // 中间内容TextView的宽度
        private int myMenuWidth; // 菜单的宽度
    
        private Scroller scroller;
    
        public MyCustomFrameLayout(@NonNull Context context, @Nullable AttributeSet attrs) {
            super(context, attrs);
    
            scroller = new Scroller(context);
        }
    
        private View tvContent;
        private View tvMenu;
    
        /**
         * 当布局加载完成✅后就会回调此方法
         */
        @Override
        protected void onFinishInflate() {
            super.onFinishInflate();
    
            tvContent = getChildAt(0); // 拿到第一个孩子
            tvMenu = getChildAt(1); // 得到第二个孩子
        }
    
        /**
         * 测量两个孩子的高宽
         * @param widthMeasureSpec
         * @param heightMeasureSpec
         */
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    
            myContentWidth = tvContent.getMeasuredWidth(); // 等价于getMeasuredWidth();因为这个是后去父控件的宽度,父控件和这个孩子控件宽度是一样的
            myHeigth = getMeasuredHeight();
            myMenuWidth = tvMenu.getMeasuredWidth();
        }
    
        /**
         * 为何不让实现者强制重写,应该在FrameLayout中已经重写过了
         * @param changed
         * @param left
         * @param top
         * @param right
         * @param bottom
         */
        @Override
        protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
            super.onLayout(changed, left, top, right, bottom);
    
            // 指定位置
            tvContent.layout(0, 0, myContentWidth, myHeigth);
            tvMenu.layout(myContentWidth, 0 , myContentWidth + myMenuWidth, myHeigth);
        }
    
        private float startX;
        private int x;
    
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            switch (event.getAction()){
                case MotionEvent.ACTION_DOWN:
                    startX =  event.getX();
                    break;
                case MotionEvent.ACTION_UP:
                    float upEnd = event.getX();
                    float thisUp = upEnd;
                    // float myx = getScrollX() - thisUp;
                    if (getScrollX() > myMenuWidth / 2) {
                        // x = myMenuWidth;
    
                        openM();
                    } else {
                        // x = 0;
    
                        closeM();
                    }
                    /*invalidate();
                    scroller.startScroll(getScrollX(), getScrollY(), x, Math.abs(1000));*/
                    // scrollTo(x, getScrollY());
                    break;
                case MotionEvent.ACTION_MOVE:
                    int endX = (int) event.getX();
                    int thisX = (int) (endX - startX);
    
                    int scrollX = getScrollX();
                    Log.i(TAG, ">>>>> scrollX" + scrollX);
    
                    x =  scrollX - thisX;
    
                    // 非法值的屏蔽
                    if (x < 0) {
                        x = 0;
                    } else if (x > myMenuWidth) {
                        x = myMenuWidth;
                    }
    
                    scrollTo(x, getScrollY());
    
                    startX = event.getX();
    
                    break;
                default:
                    break;
            }
            return true;
        }
    
        private void openM() {
            invalidate();
            int dx = myMenuWidth - getScrollX();
            scroller.startScroll(getScrollX(), getScrollY(), dx, Math.abs(1000));
        }
    
        private void closeM() {
            invalidate();
            int dx = 0 - getScrollX();
            scroller.startScroll(getScrollX(), getScrollY(), dx, Math.abs(1000));
        }
    
        @Override
        public void computeScroll() {
            super.computeScroll();
    
            if (scroller.computeScrollOffset()) {
                int currX = scroller.getCurrX();
                scrollTo(currX, 0);
                invalidate();
            }
        }
    }
  • 相关阅读:
    Hadoop学习资料收集
    sed使用详解
    shell编程001
    电影《无法触碰》
    正则表达式
    I/O重定向与管道
    bash基础知识
    用户权限模型
    Linux文件管理常用命令
    根文件系统详解
  • 原文地址:https://www.cnblogs.com/android-deli/p/9661658.html
Copyright © 2011-2022 走看看