繁体   English   中英

具有XML子级的自定义Android组件

[英]Custom Android Components with XML children

我是一个iOS开发人员,相对于Android来说还比较新,我正在尝试创建可重用的组件,这些组件将控制器逻辑和View定义分开。 我想要一种类似于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名称,但是控制器类将不知道如何找到对这些子代的引用。

有没有其他方法可以解决此问题?

ViewGroup有一些名为getChildCountgetChildAt方法,这些方法使您可以按索引提取子视图。

因此,您将需要执行以下操作:

@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方法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM