首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在自定义布局类上膨胀xml-Layout的问题

在自定义布局类上膨胀xml-Layout的问题
EN

Stack Overflow用户
提问于 2019-03-24 20:57:04
回答 1查看 811关注 0票数 1

我有一个自定义的ConstraintLayout类(Card.java),它覆盖了onDraw()方法以在他的背景中绘制一个六边形。在前台,我尝试使用三个TextViews来显示三个数字。为此,我在Card的构造函数中膨胀了一个card.xml。将显示TextViews,但位置不正确。它们应该与卡片的宽度和高度相匹配,然后将其自身定位到卡片的左上角和右上角,并将一个定位到卡片的底部。但是它们会做一些事情,比如收缩自己,然后转到左上角。

我尝试将card.xml的根元素更改为"merge“而不是"...ConstraintLayout”,但这并没有改变任何事情。

我还尝试使用指导原则来相对于其宽度来定位TextViews。我尽量防止使用固定的页边距,这样文本总是在正确的位置,当卡片的大小发生变化时也是如此。

Card.java:

代码语言:javascript
复制
public class Card extends ConstraintLayout {

    private int mSize;
    private Path mHexagon;
    private Paint mPaintHexagon;
    private TextView mT1, mT2, mT3;

    public Card(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        inflate(context, R.layout.card, this);
        // Numbers
        mT1 = findViewById(R.id.num1);
        mT2 = findViewById(R.id.num2);
        mT3 = findViewById(R.id.num3);

        // Hexagon
        mSize = Field.getHexSize(); // Size is used to calculate the 
        setPath();
        mPaintHexagon = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPaintHexagon.setColor(0x50888888);
        mPaintHexagon.setStyle(Paint.Style.FILL);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawPath(mHexagon, mPaintHexagon);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int width = 2 * mSize;
        int height = (int) (Math.sqrt(3) * mSize);
        Log.d(TAG, "Measure w:" + width + " h:" + height);
        setMeasuredDimension(width, height);
    }
}

card.xml:

代码语言:javascript
复制
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >

<TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/num2"
        android:textAppearance="@style/TextAppearance.AppCompat.Large"
        android:text="2"
        app:layout_constraintTop_toTopOf="parent"
        android:layout_marginTop="8dp"
        app:layout_constraintStart_toStartOf="parent"
        android:layout_marginStart="8dp"/>

<TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/num1"
        android:textAppearance="@style/TextAppearance.AppCompat.Large"
        android:text="1"
        app:layout_constraintStart_toEndOf="@+id/num2"
        app:layout_constraintEnd_toStartOf="@+id/num3"
        app:layout_constraintBottom_toBottomOf="parent"/>

<TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/num3"
        android:textAppearance="@style/TextAppearance.AppCompat.Large"
        android:text="3"
        app:layout_constraintEnd_toEndOf="parent"
        android:layout_marginEnd="8dp"
        app:layout_constraintTop_toTopOf="parent"
        android:layout_marginTop="8dp"/>

</android.support.constraint.ConstraintLayout>

activity_main.xml:

代码语言:javascript
复制
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    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"
    android:background="@color/colorAccentDark"
    android:padding="5dp">

<de.portugall.markus.takeiteasy.Card
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        android:id="@+id/card"/>

</android.support.constraint.ConstraintLayout>

Screenshot Card in Layout-Debug mode

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-03-25 03:37:47

‘onMeasure()’有一些你没有严格遵守的rules。我已经看到这些规则被打破而不受惩罚,但我认为你被抓住了,但我们会继续前进。

onMeasure()中,您正在设置自定义布局的高度和宽度,但是ConstraintLayout仍然将该布局理解为wrap_content。您需要将布局参数设置为新的高度和宽度。将以下代码添加到onMeasure()的末尾

代码语言:javascript
复制
// Although we have measured the layout, we need to tell ConstraintLayout in the
// LayoutParams that the size is not longer "wrap_content".
ViewGroup.LayoutParams lp = getLayoutParams();
lp.width = width;
lp.height = height;
setLayoutParams(lp);

您遇到的第二个问题是,您正在向ConstraintLayout (自定义布局)添加ConstraintLayout (card.xml),但是您没有设置约束。在Card.java的构造函数中,添加以下内容以设置约束:

代码语言:javascript
复制
ConstraintLayout layout = (ConstraintLayout) inflate(context, R.layout.card, this);

// We have added R.layout.card to a ConstraintLayout (this custom layout), so we need
// to make sure that it is constrained properly.
ConstraintSet cs = new ConstraintSet();
cs.clone(layout);
cs.connect(R.id.layout, ConstraintSet.START, ConstraintSet.PARENT_ID, ConstraintSet.START);
cs.connect(R.id.layout, ConstraintSet.TOP, ConstraintSet.PARENT_ID, ConstraintSet.TOP);
cs.connect(R.id.layout, ConstraintSet.END, ConstraintSet.PARENT_ID, ConstraintSet.END);
cs.connect(R.id.layout, ConstraintSet.BOTTOM, ConstraintSet.PARENT_ID, ConstraintSet.BOTTOM);
cs.applyTo(layout);

您需要将card.xml中布局的高度和宽度更改为0dpmatch_parent永远不适合ConstraintLayout

这是正在发生的事情的图形化描述:

在相关的注释中,您应该考虑using the merge facility,以避免其他人提到的嵌套ConstraintLayouts

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55324011

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档