Android自定义CropImageView中findViewById获取控件返回null问题
问题原因
- 核心原因是
LayoutInflater.inflate()方法的使用逻辑错误:当你调用inflate(getContext(), R.layout.crop_image_view, this)时,第三个参数attachToRoot传了true(传入父布局实例时的默认行为),此时inflate方法返回的不是你加载的RelativeLayout布局实例,而是传入的父布局(也就是当前CropImageView本身)。此时布局还未完成挂载流程,直接用返回的父布局实例调用findViewById会找不到刚加载的子控件,返回null。 - 次要排查点:需要确认XML布局中
CropOverlayView的全类名路径与实际类路径一致,如果类名写错会导致布局inflate失败,同样会出现控件查找返回null的问题。
解决方案
提供两种可行修改方式:
方式1:修改inflate参数,手动挂载布局
将init方法修改为如下代码:
private void init(Context context) { // 第三个参数传false,inflate返回的就是加载的RelativeLayout实例 View cropLayout = LayoutInflater.from(context).inflate(R.layout.crop_image_view, this, false); // 手动将布局添加到当前自定义View中 addView(cropLayout); // 从加载的布局里查找子控件 mImageView = cropLayout.findViewById(R.id.img_crop); mCropOverlayView = cropLayout.findViewById(R.id.overlay_crop); }
方式2:直接从当前自定义View查找控件
如果你需要保留attachToRoot=true的写法,直接通过当前View实例查找即可:
private void init(Context context) { inflate(context, R.layout.crop_image_view, this); // 直接从当前CropImageView实例查找已挂载的子控件 mImageView = findViewById(R.id.img_crop); mCropOverlayView = findViewById(R.id.overlay_crop); }
内容的提问来源于stack exchange,提问作者Syed Arsalan Kazmi
相关产品推荐
相关产品推荐

