首先,是的,我读了关于这个话题的所有其他帖子。不仅仅是这个网站的人…(你看,我有点沮丧)
大多数都建议使用android:id,而不是XML文件中的id。我做到了。
我从别人那里了解到,这种观点。findViewById的工作方式与Activity.findViewById不同。我也处理了。
在我的location_layout.xml中,我使用:
<FrameLayout .... >
<some.package.MyCustomView ... />
<LinearLayout ... >
<TextView ...
android:id="@+id/txtLat" />
...
</LinearLayout>
</FrameLayout>
在我的活动中,我做:
...
setContentView( R.layout.location_layout );
在我的自定义视图类中:
...
TextView tv = (TextView) findViewById( R.id.txtLat );
返回null。这样做,我的Activity工作得很好。所以这可能是因为活动。findViewById和View。findViewById差异。所以我存储上下文传递给本地的海关视图构造函数,并尝试:
...
TextView tv = (TextView) ((Activity) context).findViewById( R.id.txtLat );
它也返回null。
然后,我改变了我的自定义视图扩展ViewGroup而不是视图,并改变了location_layout.xml,让TextView是我的自定义视图的直接子,以便视图。findViewById应该正常工作。令人惊讶的是:它并没有解决任何问题。
我到底做错了什么?
欢迎任何意见。
在我的情况下,我已经膨胀布局,但子视图返回null。最初我是这么想的:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_history);
footerView = ((LayoutInflater) getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.listview_footer, null, false);
pbSpinner = (ProgressBar) findViewById(R.id.pbListviewFooter);
tvText = (TextView) findViewById(R.id.tvListviewFooter);
...
}
然而,当我把它改成下面的时候,它工作了:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_history);
footerView = ((LayoutInflater) getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.listview_footer, null, false);
pbSpinner = (ProgressBar) footerView.findViewById(R.id.pbListviewFooter);
tvText = (TextView) footerView.findViewById(R.id.tvListviewFooter);
...
}
关键是要特别引用已经膨胀的布局,以便获得子视图。即添加footerView:
footerView.findViewById……
我只是想把我的具体案子提出来。也许能帮到别人。
我使用的指令在我的Android UI XML像这样:
父视图:
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:tag="home_phone"
android:background="@color/colorPrimary">
...
<include
layout="@layout/retry_button"
android:visibility="gone" />
子视图(retry_button):
<com.foo.RetryButton
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/retry"
android:layout_gravity="center"
android:orientation="vertical"
android:layout_width="100dp"
android:layout_height="140dp">
. findviewbyid (R.id.retry)将总是返回null。但是,如果我把ID从子视图移到include标签,它就开始工作了。
固定的家长:
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:tag="home_phone"
android:background="@color/colorPrimary">
...
<include
layout="@layout/retry_button"
android:id="@+id/retry"
android:visibility="gone" />
固定的孩子:
<com.foo.RetryButton
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_gravity="center"
android:orientation="vertical"
android:layout_width="100dp"
android:layout_height="140dp">
在我的例子中,当我将调用从父对象移动到由父对象实例化的适配器对象时,findViewById返回null。在尝试了这里列出的技巧但没有成功之后,我将findViewById移回父对象中,并在适配器对象实例化期间将结果作为参数传递。
例如,我在父对象中这样做:
Spinner hdSpinner = (Spinner)view.findViewById(R.id.accountsSpinner);
然后我在创建适配器对象时将hdSpinner作为参数传递:
mTransactionAdapter = new TransactionAdapter(getActivity(),
R.layout.transactions_list_item, null, from, to, 0, hdSpinner);