在按钮的中心点之间画线,找不到中心

时间:2018-11-03 22:57:02

标签: android android-layout android-constraintlayout

在约束布局中,我有一列6个按钮。它们被链接在一起,顶部按钮被限制在操作栏上,底部按钮被限制在导航栏上方的辅助线上。在该列的左侧,我还有另一个按钮。我在两组按钮之间画了线-参见图片。

enter image description here

这些行来自自定义视图,并已添加到我的xml中。这是我的自定义视图中绘制线条的一些代码。

public void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    int color = ContextCompat.getColor(getContext(), R.color.GradientStart);
    paint.setColor(color);
    paint.setAntiAlias(true);

    canvas.drawLine(pointA.x, pointA.y, pointB.x, pointB.y, paint);    }
public void setPointA(PointF point){
        pointA=point;}
public void setPointB(PointF point){
    pointB=point;}

我的问题是我似乎无法在每个按钮的中心获得起点和终点。按钮要么向上移动,要么线向下移动。

这是按钮的XML。我只添加了顶部和底部以及一些中间按钮。所有中间按钮都具有相同的xml

<com.example.android.cop1803.LayoutCustom 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:id="@+id/mylayoutcustom"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
tools:context="com.example.android.cop1803.MainActivity"
android:fitsSystemWindows="true"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:layout_editor_absoluteY="73dp">
<!---->
<com.example.android.cop1803.MyViewbutton
    android:id="@+id/MainCOPbtn"
    android:layout_width="0dp"
    android:layout_height="0dp"
    android:layout_marginBottom="8dp"
    app:layout_constraintBottom_toBottomOf="@id/guideline2"
    app:layout_constraintDimensionRatio="1:1"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintHorizontal_bias="0.14"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toBottomOf="@id/guideline"
    app:layout_constraintWidth_default="wrap"
    app:layout_constraintWidth_max="@dimen/max"
    app:layout_constraintHeight_max="@dimen/max" 
<com.example.android.cop1803.MyViewbutton>

    android:id="@+id/x21"
    android:layout_width="0dp"
    android:layout_height="0dp"
    android:background="@drawable/copbutton"
    app:layout_constraintBottom_toTopOf="@+id/x22"
    app:layout_constraintDimensionRatio="1:1"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintHorizontal_bias="0.4"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toBottomOf="@id/guideline"
    app:layout_constraintVertical_chainStyle="spread"
    app:layout_constraintWidth_default="wrap"
    app:layout_constraintWidth_max="@dimen/maxsmall"
    app:layout_constraintHeight_max="@dimen/maxsmall"/>

<com.example.android.cop1803.MyViewbutton
    android:id="@+id/x22"
    android:layout_width="0dp"
    android:layout_height="0dp"
    android:background="@drawable/copbutton"
    app:layout_constraintBottom_toTopOf="@+id/x23"
    app:layout_constraintDimensionRatio="1:1"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintHorizontal_bias="0.4"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toBottomOf="@+id/x21"
    app:layout_constraintWidth_default="wrap"
    app:layout_constraintWidth_max="@dimen/maxsmall"/>

<com.example.android.cop1803.MyViewbutton
    android:id="@+id/x23"
    android:layout_width="0dp"
    android:layout_height="0dp"
    android:background="@drawable/copbutton"
    app:layout_constraintBottom_toTopOf="@id/x24"
    app:layout_constraintDimensionRatio="1:1"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintHorizontal_bias="0.4"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toBottomOf="@+id/x22"
    app:layout_constraintWidth_default="wrap"
    app:layout_constraintWidth_max="@dimen/maxsmall"/>

<com.example.android.cop1803.MyViewbutton
    android:id="@+id/x27"
    android:layout_width="0dp"
    android:layout_height="0dp"
    android:background="@drawable/copbutton"
    app:layout_constraintBottom_toBottomOf="@id/guideline2"
    android:layout_marginBottom="8dp"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintHorizontal_bias="0.4"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toBottomOf="@+id/x26"
    app:layout_constraintDimensionRatio="1:1"
    app:layout_constraintWidth_default="wrap"
    app:layout_constraintWidth_max="@dimen/maxsmall"/>

这是我找到中心点的代码

 public void drawLines(List<LineView> mlinesToDraw) {
            int[] viewALocationInWindow = new int[2];
            int[] viewBLocationInWindow = new int[2];

            vBtn1.getLocationInWindow(viewALocationInWindow);
            vBtn2.getLocationInWindow(viewBLocationInWindow);

            int[] viewALocationOnScreen = new int[2];
            int[] viewBLocationOnScreen = new int[2];

            vBtn1.getLocationOnScreen(viewALocationOnScreen);
            vBtn2.getLocationOnScreen(viewBLocationOnScreen);

            float Ax = vBtn1.getX();
            float Ay = vBtn1.getY();
            float Bx = vBtn2.getX();;
            float By = vBtn2.getY();

            final int lineStartX = ((ConstraintLayout.LayoutParams) vBtn1.getLayoutParams()).leftMargin + (vBtn1.getMeasuredWidth() / 2)+vBtn1.getLeft();
            final int lineStartY = ((ConstraintLayout.LayoutParams) vBtn1.getLayoutParams()).topMargin + (vBtn1.getMeasuredHeight() / 2)+vBtn1.getTop();
            final int lineEndX = ((ConstraintLayout.LayoutParams) vBtn2.getLayoutParams()).leftMargin + (vBtn2.getMeasuredWidth() / 2)+vBtn2.getLeft();
            final int lineEndY = ((ConstraintLayout.LayoutParams) vBtn2.getLayoutParams()).topMargin + (vBtn2.getMeasuredHeight() / 2)+vBtn2.getTop();

        pointA=new PointF(lineStartX,  lineStartY);
        pointB=new PointF(lineEndX,lineEndY);
        mLine.get(i).setPointA(pointA);
        mLine.get(i).setPointB(pointB);
    } }

我在主布局上附加了一个'getViewTreeObserver()。addOnGlobalLayoutListener',因此在绘制线条之前,按钮已经渲染。

非常感谢您能提供找到罪魁祸首的帮助。

1 个答案:

答案 0 :(得分:1)

不清楚您使用的是哪一组坐标。从外观上看,似乎x值正确,但y值已关闭。 (您是在计算屏幕坐标并使用它们绘制吗?这将为您提供正确的x值,但有错误的y值。)检查并确保正确设置了drawLine()的坐标:x的计算将转到x坐标,而y的计算则相同。

也不清楚LayoutCustom中发生了什么,因此可能正在发生某些事情。坐标的任何转换都可能使您失望。

这是一个快速的示例,可以根据您的布局为您提供帮助。我使用View.setForeground()(API 23+)写入画布,但是概念保持不变。

enter image description here

activity_main.xml

<android.support.constraint.ConstraintLayout 
    android:id="@+id/mylayoutcustom"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:clipToPadding="false"
    android:fitsSystemWindows="true">

    <Button
        android:id="@+id/MainCOPbtn"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_marginBottom="8dp"
        app:layout_constraintBottom_toBottomOf="@id/guideline2"
        app:layout_constraintDimensionRatio="1:1"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHeight_max="@dimen/max"
        app:layout_constraintHorizontal_bias="0.14"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/guideline"
        app:layout_constraintWidth_default="wrap"
        app:layout_constraintWidth_max="@dimen/max" />

    <Button
        android:id="@+id/x21"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:background="@android:color/holo_blue_light"
        app:layout_constraintBottom_toTopOf="@+id/x22"
        app:layout_constraintDimensionRatio="1:1"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHeight_max="@dimen/maxsmall"
        app:layout_constraintHorizontal_bias="0.4"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/guideline"
        app:layout_constraintVertical_chainStyle="spread"
        app:layout_constraintWidth_default="wrap"
        app:layout_constraintWidth_max="@dimen/maxsmall" />

    <Button
        android:id="@+id/x22"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:background="@android:color/holo_blue_light"
        app:layout_constraintBottom_toTopOf="@+id/x23"
        app:layout_constraintDimensionRatio="1:1"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.4"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/x21"
        app:layout_constraintWidth_default="wrap"
        app:layout_constraintWidth_max="@dimen/maxsmall" />

    <Button
        android:id="@+id/x23"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:background="@android:color/holo_blue_light"
        app:layout_constraintBottom_toTopOf="@id/x24"
        app:layout_constraintDimensionRatio="1:1"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.4"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/x22"
        app:layout_constraintWidth_default="wrap"
        app:layout_constraintWidth_max="@dimen/maxsmall" />

    <Button
        android:id="@+id/x24"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_marginBottom="8dp"
        android:background="@android:color/holo_blue_light"
        app:layout_constraintBottom_toBottomOf="@id/guideline2"
        app:layout_constraintDimensionRatio="1:1"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.4"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/x23"
        app:layout_constraintWidth_default="wrap"
        app:layout_constraintWidth_max="@dimen/maxsmall" />

    <android.support.constraint.Guideline
        android:id="@+id/guideline"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        app:layout_constraintGuide_begin="16dp" />

    <android.support.constraint.Guideline
        android:id="@+id/guideline2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        app:layout_constraintGuide_begin="382dp" />
</android.support.constraint.ConstraintLayout>

MainActivity.java

public class MainActivity extends AppCompatActivity implements ViewTreeObserver.OnGlobalLayoutListener {
    private ConstraintLayout mLayout;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mLayout = findViewById(R.id.mylayoutcustom);
        findViewById(R.id.mylayoutcustom).getViewTreeObserver()
            .addOnGlobalLayoutListener(this);
    }

    @Override
    public void onGlobalLayout() {
        Button btns[] = new Button[]{
            findViewById(R.id.MainCOPbtn),
            findViewById(R.id.x21),
            findViewById(R.id.x22),
            findViewById(R.id.x23),
            findViewById(R.id.x24)};
        Paint paint = new Paint();
        paint.setColor(Color.RED);
        paint.setStrokeWidth(10);

        mLayout.getViewTreeObserver().removeOnGlobalLayoutListener(this);

        Bitmap bmp = Bitmap.createBitmap(mLayout.getWidth(), mLayout.getHeight(),
                                         Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bmp);
        drawCircle(canvas, btns[0], paint);
        for (int i = 1; i < btns.length; i++) {
            drawLine(canvas, btns[0], btns[i], paint);
        }
        BitmapDrawable d = new BitmapDrawable(getResources(), bmp);
        mLayout.setForeground(d);
    }

    private void drawLine(Canvas canvas, View fromView, View toView, Paint paint) {
        Point from = getCenter(fromView);
        Point to = getCenter(toView);
        canvas.drawCircle(to.x, to.y, 20, paint);
        canvas.drawLine(from.x, from.y, to.x, to.y, paint);
    }

    private void drawCircle(Canvas canvas, View view, Paint paint) {
        Point center = getCenter(view);
        canvas.drawCircle(center.x, center.y, 20, paint);
    }

    Point getCenter(View view) {
        Point pt = new Point();
        pt.x = (int) (view.getX() + view.getWidth() / 2);
        pt.y = (int) (view.getY() + view.getHeight() / 2);
        return pt;
    }
}