如何使用布局文件来填充一个视图

242

我有一个在XML中定义的布局。它还包含:

<RelativeLayout
    android:id="@+id/item"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
/>

我想使用其他的XML布局文件来填充这个RelativeView。根据情况,我可能会使用不同的布局。我该怎么做?我尝试了不同的变化,但没有成功。

RelativeLayout item = (RelativeLayout) findViewById(R.id.item);
item.inflate(...)

但是它们都没能很好地工作。

15个回答

425

我不确定我是否理解了你的问题 - 你是在尝试将一个子视图附加到RelativeLayout上吗?如果是这样,你需要按照以下方式进行操作:

RelativeLayout item = (RelativeLayout)findViewById(R.id.item);
View child = getLayoutInflater().inflate(R.layout.child, null);
item.addView(child);

3
我遇到了一个错误:02-25 22:21:19.324: ERROR/AndroidRuntime(865): Caused by: java.lang.IllegalStateException: 指定的子视图已经有了一个父视图。你必须先在子视图的父视图上调用 removeView() 方法。 - Michal Dymel
27
刚刚试了一下,我需要:View child = getLayoutInflater().inflate(R.layout.child,null); - James
3
问题不在于代码,代码很容易理解。你需要放置XML文件在哪里?这个类型是主题样式资源吗?我认为问题在于人们(包括我)不知道应该把这个XML文件放在哪里。 - Lpc_dark
17
这不是完美的。应该使用三参数版本的Inflater - 原因在于:http://www.doubleencore.com/2013/05/layout-inflation-as-intended/ - Nick Cardoso
3
答案是错误的,即使它能够运行。请查看此帖子 https://possiblemobile.com/2013/05/layout-inflation-as-intended/ - ARK
显示剩余4条评论

112
你需要填充一个XML资源,参见LayoutInflater文档。如果你的布局在mylayout.xml中,你可以这样做:
View view; 
LayoutInflater inflater = (LayoutInflater)   getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
view = inflater.inflate(R.layout.mylayout, null);

RelativeLayout item = (RelativeLayout) view.findViewById(R.id.item);

4
我已经将我的主视图填充完毕。现在的问题是我想从另一个XML文件中填充它的一部分。这个RelativeLayout是更大的布局的一部分,我希望用另一个XML文件的布局来填充它。 - Michal Dymel
抱歉,我不知道 :(。你的主视图中是否使用类似于<include>的内容来包含其他布局? - ccheneson
不,这是简单的布局。我想我会直接通过编程方式添加元素,而不使用XML。感谢您的帮助! - Michal Dymel

28

虽然回答晚了,但想补充一点就是可以通过以下方式来获取

LayoutInflater layoutInflater = (LayoutInflater)this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View view = layoutInflater.inflate(R.layout.mylayout, item );

在想要添加子布局的父布局中,item是父布局。


1
@Kyle - 即使更晚一些,你也不能将 R 资源用作对象的引用,它们只是整数。你必须使用 findViewById 将其传递到 R 资源中,然后将其强制转换为所需的对象类型,然后才能在函数调用中使用它,例如 inflate(即 ViewGroup item = (ViewGroup) findViewById(R.layout.activity_layout);... 然后你可以像上面那样使用 item)。 - Pimp Trizkit
是否有可能隐藏父视图,只显示子视图? - NovusMobile
谢谢,这个方法很有帮助,因为我在使用片段时无法使用先前示例中的getContext()。 - RightHandedMonkey
很高兴能帮到某个人 :-) - Shaista Naaz
@ShaistaNaaz 你好..我创建了多个相同类型的视图..通过膨胀它们..我遇到了一个问题,我应该如何获取每个项目的资源ID。 - Janmejoy
显示剩余3条评论

20

即使这是一个旧帖子,添加以下内容仍然有助于理解:如果从XML中膨胀的子视图将被添加到ViewGroup布局中,您需要调用inflate并告诉它要添加到哪种类型的ViewGroup中。例如:

View child = getLayoutInflater().inflate(R.layout.child, item, false);

inflate方法有很多重载,文档中描述了它的用法。我遇到一个问题,就是从XML中膨胀出来的单个视图在父级中没有对齐,直到我进行了这种类型的更改。


最后,谢谢 :) 这允许将多个视图添加到单个父级,但无需担心从 XML 中读取的 LayoutParams。干得好! - Sabo

14

更简单的方法是使用

View child = View.inflate(context, R.layout.child, null)
item.addChild(child) //attach to your item

使用View.inflate()是最好的方式,没有不必要的LayoutInflatergetSystemService(Context.LAYOUT_INFLATER_SERVICE)或任何烦人的东西! :D - varun

11

尝试以下代码:

  1. 如果您只想填充布局:

View view = LayoutInflater.from(context).inflate(R.layout.your_xml_layout,null); // Code for inflating xml layout
RelativeLayout item = view.findViewById(R.id.item);   

  1. 如果您想在父布局(container)中填充您的布局:

LinearLayout parent = findViewById(R.id.container);        //parent layout.
View view = LayoutInflater.from(context).inflate(R.layout.your_xml_layout,parent,false); 
RelativeLayout item = view.findViewById(R.id.item);       //initialize layout & By this you can also perform any event.
parent.addView(view);             //adding your inflated layout in parent layout.


9
布局填充
View view = null;
LayoutInflater inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
view = inflater.inflate(R.layout.mylayout, null);
main.addView(view);

6

将AttachToRoot设置为True

假设我们在一个XML布局文件中指定了一个按钮,它的布局宽度和高度都被设置为match_parent。

<Button xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/custom_button">
</Button>

在此按钮的点击事件中,我们可以设置以下代码来在此活动中填充布局。
LayoutInflater inflater = LayoutInflater.from(getContext());
inflater.inflate(R.layout.yourlayoutname, this);

希望这个解决方案对您有用!

6

如果您不在活动中,可以使用LayoutInflater类的静态from()方法获取LayoutInflater,或者也可以从上下文方法getSystemService()请求该服务:

LayoutInflater i;
Context x;       //Assuming here that x is a valid context, not null

i = (LayoutInflater) x.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
//OR
i = LayoutInflater.from(x);

(我知道这几乎是4年前的事情,但仍然值得一提)

4
如果您想多次添加单个视图,则需要使用以下方法:
   layoutInflaterForButton = getActivity().getLayoutInflater();

 for (int noOfButton = 0; noOfButton < 5; noOfButton++) {
        FrameLayout btnView = (FrameLayout) layoutInflaterForButton.inflate(R.layout.poll_button, null);
        btnContainer.addView(btnView);
    }

如果你喜欢

   layoutInflaterForButton = getActivity().getLayoutInflater();
    FrameLayout btnView = (FrameLayout) layoutInflaterForButton.inflate(R.layout.poll_button, null);

并且

for (int noOfButton = 0; noOfButton < 5; noOfButton++) {
            btnContainer.addView(btnView);
        }

然后它会抛出已添加视图的异常。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接