如何用布局使一个视图膨胀


221

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

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

我想将此RelativeView与其他XML布局文件一起充气。我可能会根据情况使用不同的布局。我该怎么办?我正在尝试不同的

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

但是他们都不行。

Answers:


390

我不确定我是否遵循了您的问题-您是否要在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:错误/ AndroidRuntime(865):由以下原因引起:java.lang.IllegalStateException:指定的孩子已经有一个父母。您必须先在孩子的父母上调用removeView()。
Michal Dymel

27
现在只需尝试一下,我需要:View child = getLayoutInflater()。inflate(R.layout.child,null);
詹姆斯

3
问题不在于代码。遵循代码相当容易。您在哪里制作xml文件。类型是主题样式资源吗?我认为包括我在内的人的问题是我们将这个xml文件放在哪里
Lpc_dark

15
这不是完美的。应使用充气机的3参数版本-原因如下:doubleencore.com/2013/05/layout-inflation-as-intended
Nick Cardoso

3
答案是错误的,即使可行。请查看此职位 可能的消息
mobile.com/2013/05/layout-inflation-as-intended

107

您可以膨胀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 2010年

哼,对不起,我
一无所知

不,这是简单的布局。我想我将以编程方式添加我的元素-不使用XML。感谢帮助!
Michal Dymel 2010年

27

虽然回答很晚,但是想添加一种方法来解决这个问题

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

这里item是你想添加一个子布局的父布局。


(甚至在以后)我很难实现您的答案。我尝试了上面提到的代码,但将“ item”替换为:“ R.layout.activity_layout”我得到一个“没有适用于'(int,int)'的方法”,请问您的想法吗?
凯尔(Kyle)

1
@Kyle-甚至以后。您不能使用R资源作为对对象的引用,它们只是ints。您必须使用findViewByIdR资源传递给它,然后将其强制转换为所需的对象。然后,您可以在函数调用中使用它,例如inflate。(即ViewGroup item = (ViewGroup) findViewById(R.layout.activity_layout);...然后您可以item像上面一样使用。)
Pimp Trizkit 2013年

我想我想在上面的示例中使用RelativeLayout代替ViewGroup那里,因为您无法实例化基类ViewGroup。5分钟的编辑规则使我受益。大声笑
皮条客Trizkit

是否可以隐藏父级视图并仅显示子视图
NovusMobile

谢谢,此方法帮助了我在上一个示例中无法使用getContext()的地方,因为我正在使用片段。
RightHandedMonkey 2013年

19

即使这是一则旧文章,对此进行补充也是很有帮助的,如果要将从xml扩展的子视图添加到视图组布局中,则需要调用充气来提示其将进入哪种视图组类型要添加到。喜欢:

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

inflate方法非常重载,并在文档中描述了用法的这一部分。我有一个问题,在我进行这种类型的更改之前,从xml放大的单个视图无法在父视图中正确对齐。


最后,谢谢:)这允许将多个视图添加到单个父视图,而无需担心LayoutParams-从XML读取。做得好!
萨博

13

更简单的方法是使用

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

8

布局膨胀

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

6

如果您不在活动中,则可以使用该类中的静态from()方法LayoutInflater来获取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);
        }

那么它将抛出所有已添加视图的异常。


4

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);

希望此解决方案对您有用。


3

试试这个代码:

  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. 如果您想在容器中扩大布局(父布局):

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.


2

由于我的独特情况,我最难以解决此错误,但最终找到了解决方案。

我的情况:我正在使用一个单独的视图(XML),该视图包含一个WebView,然后在AlertDialog我单击主活动视图中的按钮时在中打开。但是不知何故,它WebView属于主活动视图(可能是因为我从此处拉资源),所以在我将其分配给我AlertDialog的视图之前(即视图),我必须先获取我的父项WebView,然后将其放入ViewGroup,然后删除该视图上的所有视图ViewGroup。这行得通,我的错误消失了。

// set up Alert Dialog box
AlertDialog.Builder alert = new AlertDialog.Builder(this);
// inflate other xml where WebView is
LayoutInflater layoutInflater = (LayoutInflater)this.getSystemService
                (Context.LAYOUT_INFLATER_SERVICE);
View v = layoutInflater.inflate(R.layout.your_webview_layout, null);
final WebView webView = (WebView) v.findViewById(R.id.your_webview_id);

// more code...

....之后,我加载了WebView....

// first, remove the parent of WebView from it's old parent so can be assigned a new one.
ViewGroup vg = (ViewGroup) webView.getParent();
vg.removeAllViews();

// put WebView in Dialog box
alert.setView(webView);
alert.show();

2

如果您尝试将子视图附加到RelativeLayout?你可以按照

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

1

使用Kotlin,您可以使用:

val content = LayoutInflater.from(context).inflate(R.layout.[custom_layout_name], null)

[your_main_layout].apply {
    //..
    addView(content)
}

-1

我已经在下面的代码段中使用了它,并且对我有用。

LinearLayout linearLayout = (LinearLayout)findViewById(R.id.item);
View child = getLayoutInflater().inflate(R.layout.child, null);
linearLayout.addView(child);
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.