高级UI-自定义Behavior

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/cj5785/article/details/89061674

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》一文

猜你喜欢

转载自blog.csdn.net/cj5785/article/details/89061674