首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >如何要求具有指定id的视图

如何要求具有指定id的视图
EN

Stack Overflow用户
提问于 2013-12-18 10:05:43
回答 2查看 179关注 0票数 1

我想要编写一个自定义视图,它需要一个带有特定id的按钮才能出现(为了能够被id找到),就像在ListActivity android.R.id.list中必须存在一样,我如何对我自己的自定义id做同样的处理?

我计划在Android中重用这个视图,用于几个用例,但是所有这些用例都必须用特定的id声明一些特定的视图,这样我就可以在lib代码中通过id找到它,并对它进行操作,以便以后在使用应用程序时使用.

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-12-18 10:17:41

就像ListActivity所做的那样。

检查自定义视图中的ID,如果布局中不存在异常,则抛出异常。

来自ListActivity源的代码片段:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 @Override
public void onContentChanged() {
    super.onContentChanged();
    View emptyView = findViewById(com.android.internal.R.id.empty);
    mList = (ListView)findViewById(com.android.internal.R.id.list);
    if (mList == null) {
        throw new RuntimeException(
                "Your content must have a ListView whose id attribute is " +
                "'android.R.id.list'");
    }
票数 2
EN

Stack Overflow用户

发布于 2013-12-18 12:16:48

最好的方法是灵活地使用自定义属性。它允许任何id都是必需的id,但它也使用dev工具来强制使用有效的id。

声明您的自定义视图可以使用attrs.xml文件中的自定义属性,如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<resources>
    <declare-styleable name="MyView">
        <attr name="required_view_id" format="integer" />
    </declare-styleable>
</resources>

然后,您可以引用布局文件中的属性,如下所示。特别注意定义"app“命名空间的标题。您可以为您的自定义属性命名空间使用任何您想要的名称,但是在以后定义视图时,您必须声明它以使用任何自定义属性。注意MyView上的自定义属性。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <View
        android:id="@+id/the_id_of_the_required_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <com.full.package.to.MyView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:required_view_id="@id/the_id_of_the_required_view" />

</LinearLayout>

现在,您需要确保自定义视图类中存在此视图。可以通过重写某些构造函数来要求设置自定义属性。您还需要在某个时候实际验证所需视图的存在。以下是一个粗略的想法:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class MyView extends View {

    private int mRequiredId;

    public MyView(Context context, AttributeSet attrs) {
        super(context, attrs);
        checkForRequiredViewAttr(context, attrs);
    }

    public MyView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        checkForRequiredViewAttr(context, attrs);
    }

    // Verify that the required id attribute was set
    private void checkForRequiredViewAttr(Context context, AttributeSet attrs) {
        TypedArray a = context.obtainStyledAttributes(attrs,
                R.styleable.MyView, 0, 0);
        mRequiredId = a.getResourceId(R.styleable.MyView_required_view_id, -1);
        a.recycle();
        if (mRequiredId == -1) {
            throw new RuntimeException("No required view id attribute was set");
        }
    }

    // This allows the custom view to be programmatically instantiated, so long as
    // the required id is manually set before adding it to a layout
    public void setRequiredId(int id) {
        mRequiredId = id;
    }

    // Check for the existence of a view with the required id
    @Override
    protected void onAttachedToWindow() {
        View root = getRootView();
        View requiredView = root.findViewById(mRequiredId);
        if (requiredView == null) {
            throw new RuntimeException(
                    String.format("Cannot find view in layout with id of %s", mRequiredId));
        }
        super.onAttachedToWindow();
    }
}

使用onAttachedToWindow检查所需的视图对您来说可能不够好。例如,它不会阻止移除所需的视图。在布局中查找视图并不是一种廉价的操作,特别是对于复杂的布局,因此您不应该经常检查它。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20665297

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文