[英]Problem with inflating xml-Layout on custom layout class
我有一個自定義的ConstraintLayout類(Card.java),該類重寫onDraw()
方法在其背景中繪制一個六邊形。 在前台,我嘗試使用三個TextViews
顯示三個數字。 為此,我在Card的構造函數中為card.xml
充氣。 顯示的是TextView,但位置不正確。 它們應與卡的寬度和高度匹配,然后將其自身放置在卡的左上角和右上角,並放置在卡的底部。 但是它們會像收縮自身一樣移動到左上角。
我試圖將card.xml的根元素更改為“ merge
”,而不是“ ... ConstraintLayout
”,但這沒有任何改變。
我還嘗試使用准則將TextViews相對於其寬度定位。 我試圖防止使用固定的邊距,因此當卡片大小改變時,文本始終在正確的位置。
Card.java:
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:
<?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:
<?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>
'onMeasure()`有一些您不嚴格遵守的規則 。 我已經看到這些規則不受懲罰地遭到破壞,但是我認為您被抓住了,但是我們會繼續前進。
在onMeasure()
您可以設置自定義布局的高度和寬度,但是ConstraintLayout
仍將布局理解為wrap_content
。 您將需要將布局參數設置為新的高度和寬度。 將以下代碼添加到onMeasure()
的末尾:
// 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
(card.xml)添加到ConstraintLayout
(您的自定義布局)中,但是沒有設置約束。 在Card.java
的構造函數中,添加以下內容來設置約束:
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
布局的高度和寬度更改為0dp
。 match_parent
永遠不適用於ConstraintLayout
。
這是正在發生的情況的圖形描述:
與此相關的是,您應該考慮使用合並工具來避免嵌套ConstraintLayouts
就像其他人提到的那樣。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.