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

217

假设我有一个LinearLayout,并且我想在Java代码中向其中添加一个视图。我应该使用哪种方法?我不是在问如何在XML中实现,这一点我已经知道了。我想知道的是,我如何实现下面这个示例代码中类似的操作:

(One View).add(Another View)

就像在Swing中可以做的那样。

7个回答

293

调用 addView 是正确的答案,但你需要做更多的工作才能让它正常工作。

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

例如,假设你的 LinearLayout 具有 ID R.id.main,则你的 onCreate() 函数中可能会有以下代码:

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参数。同时选择正确的内部类也很重要。我曾经遇到过将View添加到TableRow中无法正常显示的问题,直到我发现没有向子视图的setLayoutParams方法传递TableRow.LayoutParams实例。


7
你如何通过使用为此新视图专门编写的XML布局文件来以编程方式创建视图? - Ken
12
您可以使用LayoutInflater,这可以从Context中获取,通常是当前Activity。像这样:LayoutInflater myInflater = getLayoutInflater(); View myView = myInflater.inflate(R.layout.myLayout, parent, false); - Brian Cooley
1
实际上,getLayoutInflater()方法来自Window类(而不是Context),它是Activity中的一个便利方法。 - Brian Cooley
2
作为编程实践,在findViewById时,将其转换为ViewGroup或始终使用对象的最通用形式,以便如果它从LinearLayout更改为RelativeLayout,则无需重构。 - Joel Teply
2
这些是一些细节 :D - Vivek Solanki
显示剩余2条评论

63

我发现最好的方法是使用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);

编辑:

上述示例的 Kotlin 代码(view 是片段的 getView()):

(view as? ViewGroup)?.let {
        View.inflate(context, R.layout.add_credit_card, it)
}

你也可以编写一个静态方法,例如 addView(View v){ // your code after get view },该方法将获取使用 findViewById(int resourceID) 找到的视图或像你的 inflatedView 一样被填充的视图...只是为了扩展你的片段示例。 - zgc7009
在尝试了布局充气和使用myLinearLayout.add(view)之后,这是唯一有效的方法。感谢您! - Eric B.

29

要通过编程方式添加视图,您可以执行以下操作:

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);
你还可以添加任意数量的视图。

23

9
编程设置约束的想法可能会令人疲倦。下面的解决方案适用于任何布局,无论是约束还是线性布局等。最好的方法是设置一个占位符,即一个具有适当约束(或在其他布局中正确放置)的FrameLayout,放置在您期望程序创建的视图的位置。
您需要做的就是通过使用addChild()方法将视图以编程方式填充并将其作为子项添加到FrameLayout中。然后在运行时,您的视图将被填充并放置在正确的位置。根据Android的建议,您应该只向FrameLayout[链接]添加一个childView。
以下是您的代码示例,假设您希望在特定位置以编程方式创建TextView: 步骤1: 在包含要填充的视图的布局中,在正确的位置放置一个FrameLayout,并为其指定一个ID,例如“container”。 步骤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,否则frame layout将变得与父级(即活动,即手机屏幕)一样大。
android:layout_width="wrap_content"
android:layout_height="wrap_content"

如果未设置,则因为框架的子视图默认会移到框架布局的左上方,因此您的视图将简单地飞到屏幕的左上方。
第3步:
在您的onCreate方法中,执行以下操作:
FrameLayout frameLayout = findViewById(R.id.container);
                TextView textView = (TextView) View.inflate(this, R.layout.textview, null);
                frameLayout.addView(textView);

(请注意,将findViewById的最后一个参数设置为null,并通过在容器视图(frameLayout)上调用addView()来添加视图,与仅通过在findViewById()的第三个参数中传递true来传递充气视图是相同的。有关更多信息,请参见this。)

4

一种从Activity添加视图的方法

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

-1

你们还需要确保在重写 onLayout 方法时,一定要调用 super.onLayout 并传入所有属性,否则视图将无法被填充!


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