【问题标题】:Custom compound view and .findViewById()自定义复合视图和 .findViewById()
【发布时间】:2016-11-11 11:00:00
【问题描述】:

我真的很担心.findViewById() 方法及其在自定义复合视图创建中的使用。我不确定它保证永远不会返回null 的确切位置。

假设我有这个自定义复合视图,并且它被添加到一些 .xml 中,如下所示:

<com.app.path.TwoButtonsView
            android:id="@+id/ok_cancel_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>

two_buttons_view.xml:

<?xml version="1.0" encoding="utf-8"?>
<merge>

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
                  xmlns:tools="http://schemas.android.com/tools"
                  android:layout_width="match_parent"
                  android:layout_height="match_parent"
                  android:orientation="horizontal">

        <TextView
            android:id="@+id/first_button"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:clickable="true"
            android:gravity="center"
            android:textAllCaps="true"/>

        <TextView
            android:id="@+id/second_button"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:clickable="true"
            android:gravity="center"
            android:textAllCaps="true"/>
    </LinearLayout>
</merge>

TwoButtonsView.java

public class TwoButtonsView extends LinearLayout {

    // views
    private TextView mFirstButtonView;
    private TextView mSecondButtonView;

    public TwoButtonsView(Context context) {
        super(context);
        init(context, null);
    }

    public TwoButtonsView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context, attrs);
    }

    public TwoButtonsView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context, attrs);
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public TwoButtonsView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        init(context, attrs);
    }

    private void init(Context context, AttributeSet attrs) {
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        inflater.inflate(R.layout.two_buttons_view, this);

        // retrieve views
        mFirstButtonView = (TextView) findViewById(R.id.first_button); // is there a chance it will return null?
        mSecondButtonView = (TextView) findViewById(R.id.second_button); // is there a chance it will return null?
    }
}

我的问题是:.findViewById(RESOURCE_ID) 是否有可能在调用inflater.inflate(R.layout.two_buttons_view, this); 之后立即返回null,或者我应该在onFinishInflate() 回调上调用我的init() 方法?

【问题讨论】:

    标签: android android-custom-view layout-inflater custom-view findviewbyid


    【解决方案1】:

    我的问题是:.findViewById(RESOURCE_ID) 调用后将立即返回 null inflater.inflate(R.layout.two_buttons_view, this)

    不,没有,只要您要查找的视图在布局中并且您明确添加到视图的层次结构中。最后,findViewById 在View[] 上循环,由addView 填充。

    关于

    LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    inflater.inflate(R.layout.two_buttons_view, this);
    

    ViewGroup 具有静态方法inflate,因此您无需检索inflater 调用getSystemService

    【讨论】:

    • 非常感谢您的回答,@Blackbelt!请你解释一下onFinishInflate()的目的是什么?
    • 这是一个回调,当布局中声明的所有子元素都已添加时调用。在您的情况下,您正在手动添加
    • 再次感谢您的回答:D。最后一个问题:您说我手动添加了它们,但是“非手动”添加它们的另一种方法是什么?我想不出任何 =/
    • 当您在 xml 中声明它们时。 Android 将它们膨胀并为您添加它
    • 哦,但是这个自定义视图是通过 xml 添加的(在另一个布局中),所以它的子视图(在它的 xml 中)。
    猜你喜欢
    • 2013-09-01
    • 1970-01-01
    • 2021-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多