美文网首页自定义控件
Android - 自定义极坐标布局的那个人肯定没学过 Cons

Android - 自定义极坐标布局的那个人肯定没学过 Cons

作者: 拾识物者 | 来源:发表于2019-04-19 01:12 被阅读95次

极坐标系相对于笛卡尔坐标系,使用角度和半径来指定点的位置。通过三角函数公式,两者可以互相转换,本质上并没有区别。

那么使用极坐标布局的意义在哪里呢?既然是使用角度和半径的,如果基于角度和半径可以方便地做出一些效果,那就能提高开发的效率,使代码更加简洁。

ConstraintLayout 中对极坐标的支持非常直接,ConstraintLayout 的核心思维就是靠关系,在极坐标布局中,就是作为圆心的 View 与其他 View 之间通过半径和角度产生的关系。

使用方法

作为圆心的 View 不用设置任何极坐标相关属性。除非它相对于另一个圆心以极坐标布局。

围绕这个圆心的其他 View 需要设置 3 个 LayoutParams 属性:

  • layout_constraintCircle 指定圆心 View 的 id
  • layout_constraintCircleAngle 指定角度,单位是度°。官方文档中说是 0 - 360 度,实际上可以设置大于 360 度的值。0 度的方向是竖直向上,顺时针角度增大,和钟表的数字刻度一样。用 ConstraintLayout 画个表盘很方便有木有。
  • layout_constraintCircleRadius 指定半径,dimension。

代码示例

<Button
    android:id="@+id/button_center"
    android:layout_width="80dp"
    android:layout_height="80dp"
    android:layout_marginTop="8dp"
    android:layout_marginEnd="8dp"
    android:layout_marginBottom="8dp"
    android:text="Center"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent" />

<ImageView
    android:id="@+id/imageView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="#900000"
    app:layout_constraintCircle="@id/button_center"
    app:layout_constraintCircleAngle="0"
    app:layout_constraintCircleRadius="100dp"
    app:srcCompat="@android:drawable/ic_menu_camera" />

做个动画

属性动画,转个圈圈。

private void animate() {
    // 代码里角度可以用负值。
    PropertyValuesHolder holderAngle = PropertyValuesHolder.ofFloat("angle", 0, -90, -180, -270);
    PropertyValuesHolder holderRadius = PropertyValuesHolder.ofInt("radius", 0, 100, 200, 300);
    ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(circleAdapter, holderAngle, holderRadius);
    animator.setDuration(2000);
    animator.start();
}
// 没有属性可以直接设置角度和半径,自定义一个对象来 adapt 这两个属性。
private static class CircleAdapter {
    private View view;
    public CircleAdapter(View view) {
        this.view = view;
    }
    public float getAngle() {
        ViewGroup.LayoutParams lp = view.getLayoutParams();
        if (lp instanceof ConstraintLayout.LayoutParams) {
            return ((ConstraintLayout.LayoutParams) lp).circleAngle;
        }
        return 0;
    }
    public void setAngle(float angle) {
        ViewGroup.LayoutParams lp = view.getLayoutParams();
        if (lp instanceof ConstraintLayout.LayoutParams) {
            ((ConstraintLayout.LayoutParams) lp).circleAngle = angle;
            view.requestLayout();
        }
    }
    public int getRadius() {
        ViewGroup.LayoutParams lp = view.getLayoutParams();
        if (lp instanceof ConstraintLayout.LayoutParams) {
            return ((ConstraintLayout.LayoutParams) lp).circleRadius;
        }
        return 0;
    }
    public void setRadius(int radius) {
        ViewGroup.LayoutParams lp = view.getLayoutParams();
        if (lp instanceof ConstraintLayout.LayoutParams) {
            ((ConstraintLayout.LayoutParams) lp).circleRadius = radius;
            view.requestLayout();
        }
    }
}
画质有点渣……

题图:Pixabay License

相关文章

网友评论

    本文标题:Android - 自定义极坐标布局的那个人肯定没学过 Cons

    本文链接:https://www.haomeiwen.com/subject/yzxfgqtx.html