如何将Activity中EditText输入值传递到自定义View用于Canvas绘制
问题原因
- 你不能手动通过
new Information()创建Activity实例:Android的Activity由系统负责生命周期管理,你自行实例化的Activity没有绑定上下文、没有加载布局,内部的et1控件为null,调用et1.getText()直接触发空指针异常,导致CustomView加载失败。 - 时间节点不匹配:CustomView在XML中被加载的时机是Activity的
onCreate阶段执行setContentView的时候,此时就算拿到正常的Activity实例,EditText还没有任何用户输入,et1.getText().toString()得到的是空字符串,调用Integer.parseInt转换空值会抛出NumberFormatException,也会引发 inflate 错误。 - 原有实现属于强耦合设计:CustomView直接依赖具体Activity类,后续迭代维护成本极高。
解决方案
采用主动传值的方式解耦两个组件,不要让CustomView主动去Activity取数据:
步骤1:修改CustomView代码,提供参数设置入口
给CustomView添加存储参数的成员变量、公共设置方法,同时给出默认值避免空数据崩溃:
public class CustomView extends View { // 给默认值,防止无数据时绘制出错 private int mSide = 100; // 提供公共方法接收外部传入的参数 public void setSide(int side) { this.mSide = side; invalidate(); // 刷新View触发重新绘制 } // 后续onDraw绘制逻辑直接使用mSide即可 @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); // 你的绘制逻辑,用mSide代替之前的passed变量 } }
步骤2:在Information Activity中合适的时机传递参数
等Activity初始化完成、拿到用户输入后,再把值传给CustomView,推荐两种触发时机按需选择:
方案A:点击按钮确认后传值
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.your_layout); // 先初始化所有控件 EditText et1 = findViewById(R.id.et1); CustomView customView = findViewById(R.id.custom_view); Button confirmBtn = findViewById(R.id.confirm_btn); confirmBtn.setOnClickListener(v -> { String input = et1.getText().toString().trim(); if (input.isEmpty()) { Toast.makeText(this, "输入不能为空", Toast.LENGTH_SHORT).show(); return; } try { int side = Integer.parseInt(input); customView.setSide(side); } catch (NumberFormatException e) { Toast.makeText(this, "请输入合法数字", Toast.LENGTH_SHORT).show(); } }); }
方案B:监听输入框变化实时传值
如果需要输入内容实时同步到绘制效果,用TextWatcher监听:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.your_layout); EditText et1 = findViewById(R.id.et1); CustomView customView = findViewById(R.id.custom_view); et1.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) {} @Override public void onTextChanged(CharSequence s, int start, int before, int count) {} @Override public void afterTextChanged(Editable s) { String input = s.toString().trim(); if (input.isEmpty()) return; try { int side = Integer.parseInt(input); customView.setSide(side); } catch (NumberFormatException ignored) { // 输入不合法时忽略,或按需给提示 } } }); }
内容的提问来源于stack exchange,提问作者Treize
相关产品推荐
相关产品推荐

