我正在扩展HorizontalScrollView。调用公共setItems
方法时,此布局会将子项添加到LinearLayout。这些子视图动态膨胀,其宽度取决于父级(仅在一个视图时填充父级,在> = 2个项目时为1/2父级)。
<!-- custom_layout.xml -->
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="@+id/container"
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="match_parent">
</LinearLayout>
</merge>
有时,在网络请求的回调中调用setItems
,因此布局可能已经完全膨胀。我应该在哪里调用需要父母宽度的updateView
并添加膨胀的孩子?我将调用放在onSizeChanged
和setItems
中,如下所示。
public class CustomLayout extends HorizontalScrollView {
private LinearLayout container;
private List<Item> items;
public void setItems(List<Item> items) {
this.items = items;
updateView();
}
public CustomLayout(Context context) {
super(context);
init();
}
public CustomLayout(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
private void init() {
View v = inflate(getContext(), R.layout.custom_layout, this);
container = (LinearLayout) v.findViewById(R.id.container);
updateView();
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
updateView();
}
public void updateView() {
if (items == null) {
return;
}
container.removeAllViews();
int width = getWidth();
if (items.size() > 1) {
width = width * 1 / 2;
}
for (final Item item : items) {
View child = LayoutInflator.from(getContext(), R.layout.custom_item, container, false);
child.setLayoutParams(new LinearLayout.LayoutParams(width, LinearLayout.LayoutParams.MATCH_PARENT));
container.addView(child);
}
}
}
我不知道为什么这种方式并不总是有效。有时,孩子container
由于某种原因无法呈现。查看布局层次结构显示HorizontalScrollView没有子项。 container
发生了什么事?
此外,似乎即使在网络电话中,setItems
在 onSizeChanged
之前被称为,这让我觉得onSizeChanged
是错误的这个地方updateView
?
答案 0 :(得分:0)
尝试将updateView()
方法放在onMeasure
内,而不是onSizeChanged
,并使用getMeasuredWidth()
代替getWidth()
:
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
updateView();
}
public void updateView() {
if (items == null) {
return;
}
container.removeAllViews();
int width = getMeasuredWidth();
if (items.size() > 1) {
width = width * 1 / 2;
}
for (final Item item : items) {
View child = LayoutInflator.from(getContext(), R.layout.custom_item, container, false);
child.setLayoutParams(new LinearLayout.LayoutParams(width, LinearLayout.LayoutParams.MATCH_PARENT));
container.addView(child);
}
}
此外,如果您从异步请求的回调中调用setItems()
方法,请不要忘记使用runOnUiThread
的{{1}}方法在UI线程上运行它。