【问题标题】:How to Programmatically Add Views to Views如何以编程方式将视图添加到视图
【发布时间】:2010-03-07 09:31:45
【问题描述】:

假设我有一个LinearLayout,我想在我的程序中从 Java 代码中添加一个视图。使用什么方法?我不是在问它是如何在 XML 中完成的,我知道,而是我如何才能按照这个示例代码的方式做一些事情?

(One View).add(Another View)

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

【问题讨论】:

    标签: android


    【解决方案1】:

    调用addView 是正确的答案,但您需要做更多的事情才能让它发挥作用。

    如果您通过构造函数(例如,Button myButton = new Button();)创建视图,则需要在新构造的视图上调用 setLayoutParams,传入父视图的 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 参数。获得正确的内部阶级也很重要。我一直在努力将视图添加到 TableRow 以正确显示,直到我发现我没有将 TableRow.LayoutParams 的实例传递给子视图的 setLayoutParams。

    【讨论】:

    • 如何以编程方式创建视图,但使用专门为这个新视图编写的 XML 布局文件?
    • @SK9 您将使用 LayoutInflater,您可以从 Context(通常是当前 Activity)中获取它。类似于:LayoutInflater myInflater = getLayoutInflater;查看 myView = myInflater.inflate(R.layout.myLayout, parent, false);
    • 其实getLayoutInflater()来自Window类(不是Context),是Activity中的便捷方法。
    • 作为一种编码实践,在 findViewById 上,转换为 ViewGroup 或始终是对象的最通用形式,这样如果它从 LinearLayout 更改为 RelativeLayout,则无需重构。
    • 这些是一些细节:D
    【解决方案2】:

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

    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 代码(视图是片段的 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 一样膨胀...只是为了扩展您的片段示例。
    • 在弄乱了布局并尝试做myLinearLayout.add(view)之后,这是唯一有效的方法。谢谢!
    【解决方案3】:

    要以编程方式添加视图,您可以:

    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】:

      LinearLayoutViewGroup 的子类,它有一个名为addView 的方法。 addView 方法应该是你所追求的。

      【讨论】:

        【解决方案5】:

        以编程方式设置约束的想法可能令人厌烦。下面的这个解决方案适用于任何布局,无论是约束、线性等。最好的方法是在您期望以编程方式创建视图的位置设置一个占位符,即具有适当约束(或适当放置在其他布局中,如线性)的 FrameLayout拥有。

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

        假设您希望在特定位置以编程方式创建 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 的布局参数设置为 wrap_content ,否则框架布局将变得与父级(即活动,即手机屏幕)一样大。

        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() 添加视图与通过在@987654332 的第三个参数中传递true 来简单地附加膨胀视图相同@. 更多内容请见this。)

        【讨论】:

          【解决方案6】:

          从 Activity 添加视图的另一种方法

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

          【讨论】:

            【解决方案7】:

            你们还应该确保当你覆盖 onLayout 时,你必须使用所有属性调用 super.onLayout,否则视图不会被夸大!

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2017-01-04
              • 1970-01-01
              • 1970-01-01
              • 2017-10-09
              • 2017-06-28
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多