zoukankan      html  css  js  c++  java
  • 高级UI-自定义Behavior

    Behavior本身是一个抽象类,可以用于两个view之间的状态监听,也可用于某个view监听CoordinateLayout里面的所有控件滑动状态,实现自定义Behavior则可以实现任意两个view之间的状态变化

    简单使用

    这里我们自定义一个Behavior,继承自CoordinatorLayout.Behavior,实现观察者随着被观察者的位置改变而变动
    需要重写layoutDependsOn()和onDependentViewChanged()两个方法,注意:这里的构造方法必须写上

    public class CustomBehavior extends Behavior<View> {
        public CustomBehavior(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    
        /**
         * 建立监听控件或容器依赖
         *
         * @param parent     父容器
         * @param child      观察者,监听其他
         * @param dependency 被观察者
         * @return
         */
        @Override
        public boolean layoutDependsOn(CoordinatorLayout parent, View child, View dependency) {
            //我们这里监听的是一个TextView
            return dependency instanceof TextView
                    || super.layoutDependsOn(parent, child, dependency);
        }
    
        /**
         * 被监听的View改变时,相应的处理
         *
         * @param parent
         * @param child
         * @param dependency
         * @return
         */
        @Override
        public boolean onDependentViewChanged(CoordinatorLayout parent, View child, View dependency) {
            //获取被监听View的状态改变,这里以位置改变为例
            //偏移量
            int topOffset = dependency.getTop() - child.getTop();
            int width = parent.getContext().getResources().getDisplayMetrics().widthPixels;
            int leftOffset = dependency.getLeft() - (width - child.getRight());
            //平移
            ViewCompat.offsetTopAndBottom(child, topOffset);
            ViewCompat.offsetLeftAndRight(child, -leftOffset);
            return super.onDependentViewChanged(parent, child, dependency);
        }
    }
    

    记住这里依旧需要导入依赖

    implementation 'com.android.support:design:25.4.0'
    

    然后编写主要布局,这里的两个TextView,一个为观察者,一个为被观察者

    <?xml version="1.0" encoding="utf-8"?>
    <android.support.design.widget.CoordinatorLayout 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"
        tools:context=".MainActivity">
    
        <TextView
            android:id="@+id/text_view"
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:layout_gravity="left|top"
            android:background="@android:color/holo_orange_light"
            android:gravity="center"
            android:text="被观察者" />
    
        <TextView
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:layout_gravity="right|top"
            android:background="@android:color/holo_green_light"
            android:gravity="center"
            android:text="观察者"
            app:layout_behavior=".CustomBehavior" />
    
    </android.support.design.widget.CoordinatorLayout>
    

    在活动中实现touch方法,使得被观察者可以被拖动

    public class MainActivity extends AppCompatActivity implements View.OnTouchListener{
    
        private static final String TAG = "MainActivity";
        private TextView textView;
        private int rawX;
        private int rawY;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            textView = (TextView) findViewById(R.id.text_view);
            textView.setOnTouchListener(this);
        }
    
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            switch (v.getId()) {
                case R.id.text_view:
                    switch (event.getAction()) {
                        case MotionEvent.ACTION_DOWN:
                            rawX = (int) event.getRawX();
                            rawY = (int) event.getRawY();
                            break;
                        case MotionEvent.ACTION_MOVE:
                            int x = (int) event.getRawX();
                            int y = (int) event.getRawY();
                            int dx = x - rawX;
                            int dy = y - rawY;
                            int l = textView.getLeft();
                            int r = textView.getRight();
                            int t = textView.getTop();
                            int b = textView.getBottom();
                            textView.layout(l + dx, t + dy, r + dx, b + dy);
                            rawX = (int) event.getRawX();
                            rawY = (int) event.getRawY();
                            break;
                        case MotionEvent.ACTION_UP:
                            break;
                    }
                    break;
            }
            return true;
        }
    }
    

    实现效果如下图
    自定义Behavior-基本实现
    同时可以有多个观察者

    实现滑动状态的监听

    需要重写onStartNestedScroll()onNestedScroll()方法,在观察者上做好标记
    具体可参见《高级UI之FloatingActionButton》一文

  • 相关阅读:
    Leetcode Python笔记
    Jenkins 自动化构建基于svn的vue项目 ,以及uniapp的H5项目
    Jenkins 持续化部署
    java中的各种锁详细介绍
    Maven私有仓库搭建 Nexu3
    Spring Cloud构建微服务架构(一)服务注册与发现
    SpringCloud学习笔记(开篇)
    介绍一款 redis 可视化工具
    java 在线网络考试系统源码 springboot mybaits vue.js 前后分离跨域
    java OA办公系统源码 Springboot Activiti工作流 vue.js 前后分离 集成代码生成器
  • 原文地址:https://www.cnblogs.com/cj5785/p/10664591.html
Copyright © 2011-2022 走看看