设置包含布局的子元素的属性

Posted

技术标签:

【中文标题】设置包含布局的子元素的属性【英文标题】:Setting attribute of child element of included layout 【发布时间】:2012-02-19 06:17:08 【问题描述】:

我有一个描述主要活动布局的 main.xml 文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_
    android:layout_
    android:orientation="vertical" >

    <include layout="@layout/mylayout" />
    <include layout="@layout/mylayout" />
    <include layout="@layout/mylayout" />
    <include layout="@layout/mylayout" />
    <include layout="@layout/mylayout" />
    <include layout="@layout/mylayout" />

</LinearLayout>

及其包含的布局xml文件(mylayout.xml):

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/mylayout"
    android:layout_
    android:layout_
    android:orientation="vertical" >

    <TextView
        android:id="@+id/textView"
        android:layout_
        android:layout_
        android:text="hello world" />

    <Button
        android:id="@+id/button"
        android:layout_
        android:layout_ />

</LinearLayout>

我只想在我的主布局中包含 5 次“mylayout”,但不是看到 5 次“hello world”,而是希望 TextView 包含自定义文本。

有没有办法通过在 include 元素上设置一些属性来覆盖子 TextView 的文本?实现这一目标的最佳方法是什么?

【问题讨论】:

这似乎是一个应该修复的严重限制。我刚刚提交了bug report。 【参考方案1】:

不,除了使用 &lt;include&gt; 指令的布局参数之外,没有其他方法可以将参数传递给包含的布局。

您可以通过编程方式扩展布局并将它们添加到您的视图中。在主布局中为容器添加一个 id:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/container"
    android:layout_
    android:layout_
    android:orientation="vertical" />

然后在您的活动中:

ViewGroup container = (ViewGroup)findViewById(R.id.container);
for (int i = 0; i < 6; i++) 
    View myLayout = getLayoutInflater.inflate(R.layout.mylayout, null);
    TextView tv = myLayout.findViewById(R.id.textView);
    tv.setText("my layout " + i);
    container.addView(myLayout); // you can pass extra layout params here too

【讨论】:

不要忘记将 dataBinding 元素添加到 app 模块 android ... dataBinding enabled = true 中的 build.gradle 文件中【参考方案2】:

如果启用数据绑定是可能的:

reuse_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
    <data>
       <variable name="text" type="String"/>
    </data>
    <LinearLayout 
        android:id="@+id/mylayout"
        android:layout_
        android:layout_
        android:orientation="vertical" >

        <TextView
            android:id="@+id/textView"
            android:layout_
            android:layout_
            android:text="@text" />

        <Button
            android:id="@+id/button"
            android:layout_
            android:layout_ />

    </LinearLayout>
</layout>

当您调用 reuse_layout.xml 时只需添加 app:text 属性

<layout="@layout/reuse_layout" app:text="some tex" />

【讨论】:

在哪里定义了 app:text,因为我收到此错误:“错误:(461) 解析 XML 时出错:未绑定前缀”,当我编译时它抱怨 app:text 属性。谢谢! 在布局“reuse_layout.xml”中你可以定义变量。当您尝试 prase 数据使用前缀 app: 然后后跟变量的名称。我猜您尝试使用@string 发送字符串,对吗?在这种情况下,请使用app:text="@@string/your_string_key" 谢谢,我想我只是缺少一些东西,因为即使上面的代码按原样复制,我也会遇到这个错误。 我收到此错误:“错误:(461) 解析 XML 时出错:未绑定前缀” 您需要在根元素 (layout) 中使用 xmlns:app="http://schemas.android.com/apk/res-auto" 才能使用 app: 前缀。然后,您需要将文字字符串放在数据绑定表达式中以使其被拾取,例如,app:text="@&amp;quot;some text&amp;quot;"。见***.com/a/58176538/686385。【参考方案3】:

https://developer.android.com/training/improving-layouts/reusing-layouts.html

您可以设置每个包含的 android:id 属性。这将 id 赋予被包含的布局的根元素。

通过 id 获取该视图,然后找到要更改文本的子视图。

【讨论】:

我还在用手机接电话,所以很难打字。 我正在尝试查看是否有办法在布局 XML 中而不是在代码中执行此操作。这不可能吗? 我也遇到过这样的问题,发现多次重复使用复杂的布局需要太多的代码来填充属性。也许最好在布局xml中复制粘贴相同的结构。【参考方案4】:

我想我找到了一种简单的方法,但如果用例很高,它可能会创建大量样板代码。但它对我来说非常有效

第一步:

将数据绑定元素添加到应用模块中的 build.gradle 文件中

android
...
dataBinding  enabled = true 
...

第二步:

为您的可重用布局创建一个布局文件

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <data>
        <variable
            name="text"
            type="String" />
    </data>

    <com.google.android.material.card.MaterialCardView
        android:id="@+id/card"
        android:layout_
        android:layout_
        app:cardBackgroundColor="@color/sortBtnBG"
        app:contentPadding="5dp"
        app:strokeColor="@color/cardStrokeColor"
        app:strokeWidth="1dp">

        <TextView
            android:id="@+id/card_text"
            android:layout_
            android:layout_
            android:layout_gravity="center"
            android:text="@text"
            android:textColor="@color/black"
            android:textSize="16sp" />
    </com.google.android.material.card.MaterialCardView>



</layout>

为需要更改的元素添加id,在我的情况下,我正在更改文本

第三步:

使用&lt;include/&gt;在活动布局中使用您的布局

 <LinearLayout
        android:id="@+id/sorting_options"
        android:layout_
        android:layout_
        android:padding="10dp">

         <include layout="@layout/your_layout_name"
          android:id="@+id/customCard1"/>
     

          <include layout="@layout/your_layout_name"
          android:id="@+id/customCard2"/>

</LinearLayout>

确保您将 id 提供给&lt;inlcude/&gt;

最后一步:

在你的 activity.java 文件中添加:

View custom_card1 = findViewById(R.id.customCard1);
TextView cc1 = view.findViewById(R.id.card_text);
cc1.setText("hello");

View custom_card2 = findViewById(R.id.customCard2);
TextView cc2 = view.findViewById(R.id.card_text);
cc2.setText("word");

【讨论】:

以上是关于设置包含布局的子元素的属性的主要内容,如果未能解决你的问题,请参考以下文章

设置包含布局的子元素的属性

网格布局 grid

javascript基础07

javascript基础07

dom应用

CSS3 弹性布局