Android自定义View中findViewById返回空,如何获取组件?
解决自定义View中findViewById返回null的问题
核心问题分析
- 自定义View未加载自身布局:你的
PlayersFragment继承自View,但没有在构造方法中加载包含buttonAdd的布局文件,导致该View内部不存在目标子控件。 - 查找范围错误:使用
context.findViewById(R.id.buttonAdd)是从整个Activity的视图树中查找控件,而非自定义View自身的内部视图范围。 - 类名混淆风险:
PlayersFragment这个名称通常用于Fragment类,但你这里继承的是View,容易造成误解,建议改为PlayersView这类更贴合的名称。
具体修复步骤
步骤1:创建自定义View的布局文件
新建view_players.xml布局文件,写入包含buttonAdd的布局结构:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <Button android:id="@+id/buttonAdd" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Add"/> </LinearLayout>
步骤2:修改自定义View构造方法,加载布局
在PlayersFragment(建议改名PlayersView)的构造方法中,通过LayoutInflater加载自身布局并添加到当前View:
@RequiresApi(api = Build.VERSION_CODES.O) public PlayersFragment(Context context, AttributeSet attSet) { super(context, attSet); // 加载自定义View的布局,第三个参数true表示将布局添加到当前View LayoutInflater.from(context).inflate(R.layout.view_players, this, true); }
步骤3:在onFinishInflate中从自身查找控件
将context.findViewById改为findViewById(View自身的方法,默认从当前View内部查找):
@Override protected void onFinishInflate() { super.onFinishInflate(); // 从当前自定义View内部查找目标控件 _addButton = findViewById(R.id.buttonAdd); }
步骤4:(可选)修正类名避免混淆
将PlayersFragment改名为PlayersView,同时更新MainActivity布局中的引用:
<com.example.myemptyapplication.PlayersView android:id="@+id/fragment_container_view_players" android:layout_weight="1" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginLeft="10px"/>
额外说明
如果你的PlayersFragment原本是想实现Fragment功能,那应该继承Fragment类,在Fragment的onCreateView方法中加载布局并查找控件,而非继承View。
内容的提问来源于stack exchange,提问作者Tammy Roytvarf
相关产品推荐
相关产品推荐

