[英]Programmatically add view into a LinearLayout
我正在尝试在 LinearLayout 中模拟 ListView 以显示具有相同布局的三行。 这个单一的视图由一个评级栏和一个内容组成。 很奇怪,但是所有 ratingBars 都收到最后分配的值。 首先,这是我的自定义组件,它扩展了 LinearLayout,只是添加了这两个方法:
public void setElements(List<Item> elements) {
removeAllViews();
for (int i = 0; i < elements.size() && i < 3; i++) {
View vi = buildElementView(elements.get(i));
vi.setId(i);
addView(vi);
}
}
private View buildElementView(Item itemElement) {
View view = inflater.inflate(R.layout.element_list_item, null, true);
// set values
View header = view.findViewById(R.id.header);
RatingBar ratingInItem = (RatingBar) header.findViewById(R.id.ratingBarInItem);
TextView content = (TextView) view.findViewById(R.id.content);
content.setText(itemElement.getContent());
ratingInItem.setRating(itemElement.getRating());
return view;
}
这是我正在膨胀的布局:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res/com.weorder.client"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="@color/transparent"
android:minHeight="60.0dp"
android:orientation="vertical"
android:paddingBottom="8.0dp"
android:paddingLeft="5.0dp"
android:paddingRight="5.0dp"
android:paddingTop="8.0dp" >
<RelativeLayout
android:id="@+id/header"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<RatingBar
android:id="@+id/ratingBarInItem"
style="@style/RatingBarSm"
android:isIndicator="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="3dp"
android:numStars="5"
android:stepSize="0.1" />
</RelativeLayout>
<TextView
android:id="@+id/content"
style="@style/Content"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="3dp"
android:layout_marginRight="3dp"
android:layout_marginTop="3dp"
android:textColor="@color/dark_brown"
android:textSize="@dimen/text_size_small" />
</LinearLayout>
我在片段的 onActivityCreated() 中调用了 setElements 方法。 它在片段开始时运行良好,但是当我尝试旋转手机时,项目的内容会正确更改但评级栏获得最后一个值(如果有 3 个元素的评级为 1,2 和 3,则所有评级栏都有 3 星) . 这是一个错误吗?
编辑:这是我的 onSaveInstanceMethod:
@Override
public void onSaveInstanceState(Bundle outState) {
if (elements != null) {
outState.putSerializable("elements", elements);
}
super.onSaveInstanceState(outState);
}
谢谢
我认为您使用的 findViewById() 具有导致问题的错误视图。
这是一个基于您正在做的对我有用的示例。
LinearLayout ll = (LinearLayout)findViewById(R.id.ll);
ViewGroup parentGroup = parentGroup = (ViewGroup)ll;
for (int i = 0; i < 3; i++)
{
LayoutInflater inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.element_list_item, null, true);
RatingBar rBar = (RatingBar)view.findViewById(R.id.ratingBar1);
rBar.setProgress(i);
parentGroup.addView(view);
}
结果应显示三个评级栏,分别为 0、1 和 2 星,具体取决于您设置评级栏的方式。 我将新视图附加到视图父视图三次。 父视图是我的线性布局,新视图是评级栏(或您选择的任何内容)。
为了保存片段使用
@Override
public void onSaveInstanceState(Bundle outState)
{
super.onSaveInstanceState(outState);
getFragmentManager().putFragment(outState, Content.class.getName(), this);
}
然后你可以在 onCreateView 中获取你的 arguments 并恢复你的数据(如果需要)
Bundle extras = this.getArguments();
if(extras != null)
{
//set arguments here
}
它在片段开始时运行良好,但是当我尝试旋转手机时,项目的内容会正确更改但评级栏获得最后一个值(如果有 3 个元素的评级为 1,2 和 3,则所有评级栏都有 3 星) . 这是一个错误吗?
这不是错误 - 这就是 Android 的工作原理。
为什么会这样?
默认情况下,系统将保存和恢复具有 ID 的 state 视图,并使用这些 ID 来维护 state 的内部 map。因为您在LinearLayout
中使用相同的布局,所以每个孩子都有一个 ID ratingBarInItem
的RatingBar
。 当系统保存视图的 state 时,它会保存第一个柱的 state,然后用第二个柱覆盖它,然后用第三个柱覆盖它。 然后,当您恢复 state 时,它会将 ID 为ratingBarInItem
的每个视图恢复为它在 state map 中的视图 - 这将是最后保存的值,即来自第三项的值。
你如何解决这个问题?
你有两个选择。
您表明您已经在保存视图中的“元素”。 那么,您可以更新onRestoreInstanceState
以读取这些元素,然后使用它们重新更新子视图(即再次调用setElements
)。
在扩充子视图以添加到布局后,使用generateViewID创建一个新的唯一 ID,您可以在每个RatingBar
上设置。
RatingBar ratingInItem = (RatingBar) header.findViewById(R.id.ratingBarInItem);
ratingInItem.setID(View.generateViewID());
然后您不必实施保存或恢复 state 因为,现在每个视图都有一个唯一的 ID,默认的系统行为将起作用。
希望有帮助!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.