我是iOS开发人员,相对较新的Android,我尝试创建可重用的组件,将控制器逻辑和视图定义分开。我想要一个类似于iOS IBOutlets的模式,您可以在其中定义一个可以与不同的xib文件或故事板布局一起使用的类。
例如,假设我要创建自定义进度条组件。我希望用户能够提供所需的子项,并在xml中单独设计和设置它们。
这里有一些我想要完成的伪代码:
layout.xml
<FrameLayout>
<!-- A vertical progress bar -->
<CustomProgressBar>
<LinearLayout orientation="vertical">
<ImageView id="@+id/bar" src="@drawable/bar_image" />
<TextView id="@+id/label" text="Bar 1"/>
</LinearLayout>
</CustomProgressBar>
<!-- A horizontal bar using same controller class -->
<CustomProgressBar>
<LinearLayout orientation="horizontal">
<ImageView src="@drawable/background_image" />
<ImageView id="@+id/bar" src="@drawable/bar_image" />
<TextView id="@+id/label" text="Bar 1"/>
</LinearLayout>
</CustomProgressBar>
<FrameLayout>
然后我的自定义类可能如下所示:
public class CustomProgressBar extends FrameLayout {
private ImageView bar;
private TextView label;
.
.
@Override
protected void onFinishInflate() {
super.onFinishInflate();
// Store the references of the components
bar = (ImageView) findViewById(R.id.bar);
label = (TextView) findViewById(R.id.label);
// Now I should be able to write general code for this component
// using the reference components I found
}
}
在上面的示例中,开发人员在同一个xml文件中实例化2个CustomProgressBars。但是每个栏的布局都截然不同(子显示树和方向不同)。这里显而易见的问题是xml不会编译,因为我在xml中对不同的视图使用相同的id。为了解决编译问题,我可以更改id名称,但是控制器类不知道如何找到对这些子代的引用。
有没有其他方法可以解决这个问题?
答案 0 :(得分:0)
ViewGroup
中有一些名为getChildCount
和getChildAt
的方法,可让您通过索引提取子视图。
所以你需要做的是:
@Override
protected void onFinishInflate() {
super.onFinishInflate();
getProgressViews(this);
}
private ImageView bar;
private TextView label;
private void getProgressViews(ViewGroup viewGroup) {
int childCount = viewGroup.getChildCount();
for (int i = 0; i < childCount; i++) {
View view = viewGroup.getChildAt(i);
if (view.getClass().getSuperclass() == ViewGroup.class) {
getProgressViews((ViewGroup) view);
}
if (view instanceof ImageView) {
bar = (ImageView) view;
}
if (view instanceof TextView) {
label = (TextView) view;
}
}
}
如果您希望使用这些也手动将它们绘制到屏幕,则需要覆盖onLayout
方法。