在扩充布局时以编程方式使用 "toRightOf"

Using "toRightOf" programatically when inflating a layout

我的 XML 布局如下所示:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/parent"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">
    <TextView
        android:layout_width="40dp"
        android:layout_height="40dp"
        android:layout_weight="0.1"
        android:text="1"/>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/child"
        android:layout_weight="1"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center">

        <!-- Define these into code
        <TextView android:id="@+id/first"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="20sp"
            android:text="1"/>
        <TextView android:id="@+id/second"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_toRightOf="@id/first"
            android:layout_marginLeft="5dp"
            android:textSize="20sp"
            android:text="1"/>-->

    </RelativeLayout>
    <TextView
        android:layout_width="40dp"
        android:layout_height="40dp"
        android:layout_weight="0.1"
        android:text="1"/>
</LinearLayout>

LinearLayout 中的 TextView 不打算更改。 RelativeLayout 也由 TextView 组成,它们彼此对齐 5dp。与父布局不同的是,它们需要在我的 Java activity 中定义。这是我试过的:

private View getGeneratedView(String[] texts) {
    LayoutInflater inflater =
            (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View parentLayout = inflater.inflate(R.layout.parent, null);
    RelativeLayout childLayout = (RelativeLayout) parentLayout.findViewById(R.id.child);

    Integer lastViewId = null;
    for (String text: texts) {
        TextView displayedText = new TextView(this);
        displayedText.setText(text);
        displayedText.setTextSize(20);

        RelativeLayout.LayoutParams params =
                new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT,
                        RelativeLayout.LayoutParams.WRAP_CONTENT);
        if (lastViewId != null) {
            params.addRule(RelativeLayout.RIGHT_OF, lastViewId);
            params.leftMargin = 5;
        }
        displayedText.setLayoutParams(params);

        lastViewId = displayedText.getId();
        childLayout.addView(displayedText);
    }

    return parentLayout;
}

但是上面的代码所做的是将所有 TextView 放在中间,一个放在另一个上面,如下所示:

(参数 texts 原为 new String[] {"1", "1", "1", "1"}

这就是我想要得到的:

谁能指出我做错了什么?

即使您为 texts 中的每个字符串生成一个新的 TextView,您也不会为其生成一个 ID。因此,displayedText.getId() 将始终为 -1 (View.NO_ID),而 lastViewId 将永远为 -1。

要更正代码,您需要为每个生成的 TextView 生成一个新的 ID。使用 API 17+,您可以使用 View.generateViewId() 来执行此操作。

private View getGeneratedView(String[] texts) {
    LayoutInflater inflater =
            (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View parentLayout = inflater.inflate(R.layout.parent, null);
    RelativeLayout childLayout = (RelativeLayout) parentLayout.findViewById(R.id.child);

    Integer lastViewId = null;
    for (String text : texts) {
        TextView displayedText = new TextView(this);
        // Need API 17+ for generateViewId
        displayedText.setId(View.generateViewId());
        displayedText.setText(text);
        displayedText.setTextSize(20);

        RelativeLayout.LayoutParams params =
                new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT,
                        RelativeLayout.LayoutParams.WRAP_CONTENT);
        if (lastViewId != null) {
            params.addRule(RelativeLayout.RIGHT_OF, lastViewId);
            params.leftMargin = 5;
        }
        displayedText.setLayoutParams(params);

        lastViewId = displayedText.getId();
        childLayout.addView(displayedText);
    }

    return parentLayout;
}