0

Я действительно беспокоюсь о методе .findViewById() и его использовании в пользовательском сложном представлении. Я не уверен в том месте, где гарантировано, что он никогда не вернется null.Пользовательский составной вид и .findViewById()

Скажем, у меня есть этот вид пользовательского соединения и его добавляют в некоторые .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) вернет null сразу после звонка inflater.inflate(R.layout.two_buttons_view, this);, или я должен позвонить своему методу init() на onFinishInflate() callback?

ответ

2

Мой вопрос: есть ли шанс, что .findViewById (RESOURCE_ID) возвратит нуль сразу после вызова inflater.inflate (R.layout.two_buttons_view это)

Нет, есть не так, пока просмотры, которые вы ищете, находятся в макете, и вы явно добавили в иерархию представления. В конце концов, findViewById петли на View[], заполненные addView.

Небольшое примечание о

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

ViewGroup имеет статический метод inflate, так что вам не нужно, чтобы получить inflater вызова getSystemService

+0

Большое спасибо за ваш ответ, @Blackbelt! Не могли бы вы объяснить мне, что является целью 'onFinishInflate()' тогда, пожалуйста? –

+1

- это обратный вызов, который получает вызов, когда все дети, объявленные в макете, были добавлены. В вашем случае вы добавляете вручную – Blackbelt

+0

Еще раз спасибо за ответ: D. Один последний вопрос: вы сказали, что я добавил их вручную, но каков другой способ добавить их «не вручную»? Я не мог придумать ни одного =/ –