如何以编程方式向视图添加视图


185

假设我有一个LinearLayout,我想在Java程序中为其添加一个View。为此使用什么方法?我不是在问它是如何在XML中完成的,我确实知道,但是我如何才能按照此示例代码的方式进行操作?

(One View).add(Another View)

就像在Swing中一样。

Answers:


258

打电话addView是正确的答案,但是您需要做更多的工作才能使其正常工作。

如果通过构造函数(例如Button myButton = new Button();)创建View ,则需要setLayoutParams在将新构造的子级添加到父视图之前,调用新构造的视图,并传入父视图的LayoutParams内部类的实例。

例如,onCreate()假设您的LinearLayout具有id,则函数中可能包含以下代码R.id.main

LinearLayout myLayout = findViewById(R.id.main);

Button myButton = new Button(this);
myButton.setLayoutParams(new LinearLayout.LayoutParams(
                                     LinearLayout.LayoutParams.MATCH_PARENT,
                                     LinearLayout.LayoutParams.MATCH_PARENT));

myLayout.addView(myButton);

确保设置LayoutParams很重要。每个视图至少需要一个layout_width和layout_height参数。获得正确的内部阶级也很重要。我一直努力将Views添加到TableRow以使其正确显示,直到我发现没有将TableRow.LayoutParams的实例传递给子视图的setLayoutParams为止。


5
您将如何以编程方式创建视图,但是如何使用为该新视图专门编写的XML布局文件?
SK9

9
@ SK9您将使用LayoutInflater,您可以从Context(通常是当前的Activity)中获取。类似于:LayoutInflater myInflater = getLayoutInflater; 查看myView = myInflater.inflate(R.layout.myLayout,parent,false);
Brian Cooley

1
实际上,getLayoutInflater()来自Window类(而不是Context),这是Activity中的一种便捷方法。
Brian Cooley

2
作为一种编码实践,在findViewById上,强制转换为ViewGroup或始终是对象的最通用形式,这样,如果它从LinearLayout更改为RelativeLayout,则无需进行重构。
Joel Teply

1
这些是一些详细信息:D
Vivek Solanki'9

51

对于尚未感兴趣的任何人:

我发现的最好方法是使用View的inflate静态方法。

View inflatedView = View.inflate(context, yourViewXML, yourLinearLayout);

yourViewXML类似于R.layout.myView

请注意,您需要一个ViewGroup才能添加视图(可以想到的任何布局)

例如,假设您有一个片段,它的视图已被放大,并且您知道根视图是一个布局,并且您想要向其中添加视图:

    View view = getView(); // returns base view of the fragment
    if (view == null)
        return;
    if (!(view instanceof ViewGroup))
        return;

    ViewGroup viewGroup = (ViewGroup) view;
    View popup = View.inflate(viewGroup.getContext(), R.layout.someView, viewGroup);

您还可以编写一个静态方法,类似的方法是addView(View v){ // your code after get view }使用...findViewById(int resourceID)或使用inflatedView...夸大其词的视图来扩展您的片段示例。
zgc7009

25

这很晚了,但是这可能对某人有所帮助:) :)对于以编程方式添加视图,请尝试像

LinearLayout rlmain = new LinearLayout(this);      
LinearLayout.LayoutParams llp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT,LinearLayout.LayoutParams.FILL_PARENT);          
LinearLayout   ll1 = new LinearLayout (this);

ImageView iv = new ImageView(this);
iv.setImageResource(R.drawable.logo);              
LinearLayout .LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);

iv.setLayoutParams(lp);
ll1.addView(iv);
rlmain.addView(ll1);              
setContentView(rlmain, llp);

这将以编程方式创建您的整个视图。您可以添加任意数量的视图。希望这会有所帮助。:)



4

从活动添加视图的另一种方法

ViewGroup rootLayout = findViewById(android.R.id.content);
rootLayout.addView(view);

3

以编程方式设置约束的想法可能很麻烦。下面的解决方案适用于任何布局,无论是约束,线性等。最佳方式是将占位符(即具有适当约束(或适当放置在其他布局,例如线性)中的FrameLayout)设置在希望以编程方式创建的视图的位置拥有。

您所需要做的就是以编程方式将视图膨胀,并使用addChild()方法将其作为FrameLayout的子视图。然后在运行时,您的视图将被放大并放置在正确的位置。根据Android的建议,您应该仅将一个childView添加到FrameLayout [link]

假设您希望在特定位置以编程方式创建TextView,则代码如下所示:

步骤1:

在包含要放大的视图的布局中,将FrameLayout放置在正确的位置,并为其指定一个ID,例如“容器”。

步骤2 创建一个布局,将根元素作为您要在运行时膨胀的视图,将布局文件称为“ textview.xml”:

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent" android:layout_height="match_parent">

</TextView>

顺便说一句,将您的frameLayout的layout-params设置为wrap_content,否则框架布局将与父项一样大,即活动,即电话屏幕。

android:layout_width="wrap_content"
android:layout_height="wrap_content"

如果未设置,则由于默认情况下该框架的子视图转到框架布局的左上角,因此您的视图将仅飞到屏幕的左上角。

第三步

在您的onCreate方法中,执行以下操作:

FrameLayout frameLayout = findViewById(R.id.container);
                TextView textView = (TextView) View.inflate(this, R.layout.textview, null);
                frameLayout.addView(textView);

(请注意,设置的最后一个参数findViewById,以null通过调用和添加视图addView()上容器视图(的FrameLayout)是一样简单的连接通过使充气视图true中的第三参数findViewById()。更多见。)


0

你们还应该确保在覆盖时必须使用所有属性onLayout进行调用super.onLayout,否则视图不会膨胀!

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.