【问题标题】:Android - Dynamically Add Views into ViewAndroid - 将视图动态添加到视图中
【发布时间】:2011-09-07 04:13:18
【问题描述】:

我有一个视图的布局 -

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:padding="0px"
    android:orientation="vertical">

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:id="@+id/items_header"
        style="@style/Home.ListHeader" />

    <TextView 
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:id="@+id/items_none"
        android:visibility="gone"
        style="@style/TextBlock"
        android:paddingLeft="6px" />

    <ListView 
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:id="@+id/items_list" />


</LinearLayout>

我想做的是在我的主要活动中使用这样的布局

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:padding="0px"
    android:id="@+id/item_wrapper">
</LinearLayout>

我想循环遍历我的数据模型并将包含第一个布局的多个视图注入到主布局中。我知道我可以通过完全在代码中构建控件来做到这一点,但我想知道是否有一种方法可以动态构建视图,以便我可以继续使用布局而不是将所有内容都放入代码中。

【问题讨论】:

标签: android dynamic view android-layout


【解决方案1】:

使用LayoutInflater 根据您的布局模板创建一个视图,然后将其注入到您需要的视图中。

LayoutInflater vi = (LayoutInflater) getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View v = vi.inflate(R.layout.your_layout, null);

// fill in any details dynamically here
TextView textView = (TextView) v.findViewById(R.id.a_text_view);
textView.setText("your text");

// insert into main view
ViewGroup insertPoint = (ViewGroup) findViewById(R.id.insert_point);
insertPoint.addView(v, 0, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT));

您可能需要调整要插入视图的索引。

此外,根据您希望它适合父视图的方式设置 LayoutParams。例如与FILL_PARENT,或MATCH_PARENT等。

【讨论】:

  • 这是您想要将动态生成的布局放在主视图中的任何位置。这是您必须从自己的代码中填写的部分。
  • 对于那些想立即尝试的人 - 如第一行所示获得的布局充气器仍然可以解决但似乎不起作用,请改用getLayoutInflater()
  • 使用活动中的LayoutInflater vi = getLayoutInflater(); 来保留您无法获得的活动主题。
  • 在我的视图中,我有文本视图和图像,它们最初具有可见性 =“gone”。现在动态添加后,我将其可见性设置为在循环内可见,但它不起作用。
【解决方案2】:

查看LayoutInflater 类。

LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
ViewGroup parent = (ViewGroup)findViewById(R.id.where_you_want_to_insert);
inflater.inflate(R.layout.the_child_view, parent);

【讨论】:

    【解决方案3】:

    看起来你真的想要一个带有自定义适配器的 ListView 来膨胀指定的布局。使用ArrayAdapternotifyDataSetChanged() 方法,您可以完全控制视图的生成和渲染。

    看看这些教程

    【讨论】:

      【解决方案4】:

      为了让@Mark Fisher 的回答更清楚,插入的视图应该是布局文件夹下的 xml 文件,但里面没有像 LinearLayout 等这样的布局(ViewGroup)。我的例子:

      res/layout/my_view.xml

      <?xml version="1.0" encoding="utf-8"?>
      <TextView xmlns:android="http://schemas.android.com/apk/res/android"
          android:id="@+id/i_am_id"
          android:text="my name"
          android:textSize="17sp"
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          android:layout_weight="1"/>
      

      那么,插入点应该是类似LinearLayout这样的布局:

      res/layout/activity_main.xml

      <?xml version="1.0" encoding="utf-8"?>
      <RelativeLayout
          xmlns:android="http://schemas.android.com/apk/res/android"
          xmlns:tools="http://schemas.android.com/tools"
          android:id="@+id/aaa"
          android:layout_width="match_parent"
          android:layout_height="match_parent">
      
          <LinearLayout
              android:id="@+id/insert_point"
              android:layout_width="match_parent"
              android:layout_height="match_parent">
      
          </LinearLayout>
      
      </RelativeLayout>
      

      那么代码应该是

      @Override
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_shopping_cart);
      
          LayoutInflater inflater = getLayoutInflater();
          View view = inflater.inflate(R.layout.my_view, null);
          ViewGroup main = (ViewGroup) findViewById(R.id.insert_point);
          main.addView(view, 0);
      }
      

      我发布这个非常相似的答案的原因是,当我尝试实现 Mark 的解决方案时,我陷入了应该为 insert_point 和子视图使用哪个 xml 文件的问题上。我首先在子视图中使用了布局,它完全不起作用,我花了几个小时才弄清楚。所以希望我的探索可以节省别人的时间。

      【讨论】:

        【解决方案5】:
        // Parent layout
        LinearLayout parentLayout = (LinearLayout)findViewById(R.id.layout);
        
        // Layout inflater
        LayoutInflater layoutInflater = getLayoutInflater();
        View view;
        
        for (int i = 1; i < 101; i++){
            // Add the text layout to the parent layout
            view = layoutInflater.inflate(R.layout.text_layout, parentLayout, false);
        
            // In order to get the view we have to use the new view with text_layout in it
            TextView textView = (TextView)view.findViewById(R.id.text);
            textView.setText("Row " + i);
        
            // Add the text view to the parent layout
            parentLayout.addView(textView);
        }
        

        【讨论】:

        • 虽然此代码 sn-p 可能是解决方案,但 including an explanation 确实有助于提高您的帖子质量。请记住,您是在为将来的读者回答问题,而这些人可能不知道您提出代码建议的原因。
        • 它是否有效,但之后只能获取最后一个 textView ID
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-07-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多