findViewById 用于在包含的合并根元素中查看
findViewById for view inside an included merge root-element
我想在多个活动中使用一个视图。在我的例子中,它是一个 FloatingActionButton。当我通过 findViewById 搜索视图时,程序抛出 NullPointerException。如何访问 FloatingActionButton?
由于按钮应该始终相同,因此我创建了一个 XML 布局,仅在 merge
根元素中包含 FloatingActionButton 以减少使用 ìnclude
.[=28 时的开销=]
floating_button.xml
<merge xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/include_merge" >
<android.support.design.widget.FloatingActionButton
android:id="@+id/addBloodDonation"/>
</merge>
要在我的其他 XML 布局中使用它,我使用 include
标签
XML Activitiy Layouts that should include
the FloatingActionButton
<include
android:id="@+id/include_merge"
layout="@layout/floating_button" />
目前有效。
为了在我的所有 Activity 中具有相同的功能,我创建了一个 BaseActivity,我的其他 类 继承自该 BaseActivity,例如我的 MainActivity.
BaseActivity
public abstract class BaseActivity extends AppCompatActivity {
public FloatingActionButton fab;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
View include_merge = findViewById(R.id.include_merge);
fab = include_merge.findViewById(R.id.addBloodDonation);
}
}
MainActivity (exemplarily)
public class MainActivity extends BaseActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
当启动应用程序时,我在 BaseActivity 中收到一个 NullPointerException 试图找到内部元素作为 View 变量 include_merge 为空。
正如我所读 here,include
标签和根元素应该具有相同的 android:id
。使用 merge
作为根元素时有区别吗?甚至可以将 merge
标签转换为视图。
我是否需要在 BaseActivity 中使用 setContentView,因为它的 onCreate 方法在 MainActivity 之一之前被调用?
编辑:
已将 setContentView(R.layout.activity_main);
添加到评论中提到的 BaseActivity,但仍未修复它。
您不必为 <include>
或 <merge>
标签设置 id
。只需删除它以及 findViewById(R.id.include_merge)
。 <merge>
标签表示将其所有视图添加到<include>
标签的容器中。因此没有 View
与您设置的 id。但是你可以直接找到FAB
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
fab = include_merge.findViewById(R.id.addBloodDonation);
}
我想在多个活动中使用一个视图。在我的例子中,它是一个 FloatingActionButton。当我通过 findViewById 搜索视图时,程序抛出 NullPointerException。如何访问 FloatingActionButton?
由于按钮应该始终相同,因此我创建了一个 XML 布局,仅在 merge
根元素中包含 FloatingActionButton 以减少使用 ìnclude
.[=28 时的开销=]
floating_button.xml
<merge xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/include_merge" >
<android.support.design.widget.FloatingActionButton
android:id="@+id/addBloodDonation"/>
</merge>
要在我的其他 XML 布局中使用它,我使用 include
标签
XML Activitiy Layouts that should
include
the FloatingActionButton
<include
android:id="@+id/include_merge"
layout="@layout/floating_button" />
目前有效。
为了在我的所有 Activity 中具有相同的功能,我创建了一个 BaseActivity,我的其他 类 继承自该 BaseActivity,例如我的 MainActivity.
BaseActivity
public abstract class BaseActivity extends AppCompatActivity {
public FloatingActionButton fab;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
View include_merge = findViewById(R.id.include_merge);
fab = include_merge.findViewById(R.id.addBloodDonation);
}
}
MainActivity (exemplarily)
public class MainActivity extends BaseActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
当启动应用程序时,我在 BaseActivity 中收到一个 NullPointerException 试图找到内部元素作为 View 变量 include_merge 为空。
正如我所读 here,include
标签和根元素应该具有相同的 android:id
。使用 merge
作为根元素时有区别吗?甚至可以将 merge
标签转换为视图。
我是否需要在 BaseActivity 中使用 setContentView,因为它的 onCreate 方法在 MainActivity 之一之前被调用?
编辑:
已将 setContentView(R.layout.activity_main);
添加到评论中提到的 BaseActivity,但仍未修复它。
您不必为 <include>
或 <merge>
标签设置 id
。只需删除它以及 findViewById(R.id.include_merge)
。 <merge>
标签表示将其所有视图添加到<include>
标签的容器中。因此没有 View
与您设置的 id。但是你可以直接找到FAB
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
fab = include_merge.findViewById(R.id.addBloodDonation);
}