Android点击按钮在ConstraintLayout布局下动态添加可编辑文本框的方法
问题原因
你当前的新增控件堆叠在左上角,是因为ConstraintLayout的子控件必须配置约束规则才能正常定位,你只添加了控件没有设置约束,默认就会对齐到父布局左上角坐标(0,0)。
调整方案
不需要切换布局,用ConstraintSet动态给新增的EditText设置约束即可,实现步骤如下:
- 首先给你的布局文件中默认存在的可编辑plain text(EditText)设置唯一id,示例:
<EditText android:id="@+id/default_todo_et" <!-- 其余原有属性保持不变 --> />
- 修改
MainActivity代码:
首先在类中新增成员变量,记录上一个添加的EditText的ID,用于后续约束定位:
private int lastAddedEtId;
修改onCreate中的逻辑:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ConstraintLayout constraintLayout = findViewById(R.id.constraintLayout); Button buttonAddNewToDo = findViewById(R.id.addNewToDo); // 拿到默认的EditText EditText defaultTodoEt = findViewById(R.id.default_todo_et); // 初始化上一个输入框ID为默认输入框的ID lastAddedEtId = defaultTodoEt.getId(); buttonAddNewToDo.setOnClickListener(new View.OnClickListener(){ @Override public void onClick(View view){ // 新建EditText EditText newToDo = new EditText(MainActivity.this); // 生成唯一ID,用于设置约束 int newEtId = View.generateViewId(); newToDo.setId(newEtId); // 复制默认EditText的布局参数,保证宽高、左右边距等属性完全一致 newToDo.setLayoutParams(defaultTodoEt.getLayoutParams()); newToDo.setHint("enter new to do"); // 把新控件添加到父布局 constraintLayout.addView(newToDo); // 用ConstraintSet动态设置约束 ConstraintSet constraintSet = new ConstraintSet(); constraintSet.clone(constraintLayout); // 左右约束对齐父布局,边距可根据你的默认控件调整,这里示例是16dp constraintSet.connect(newEtId, ConstraintSet.START, ConstraintSet.PARENT_ID, ConstraintSet.START, dp2px(16)); constraintSet.connect(newEtId, ConstraintSet.END, ConstraintSet.PARENT_ID, ConstraintSet.END, dp2px(16)); // 顶部约束到上一个输入框的底部,设置16dp的间距 constraintSet.connect(newEtId, ConstraintSet.TOP, lastAddedEtId, ConstraintSet.BOTTOM, dp2px(16)); // 应用约束 constraintSet.applyTo(constraintLayout); // 更新上一个输入框ID为当前新建的输入框ID,供下一次添加使用 lastAddedEtId = newEtId; } }); }
- 新增dp转px的工具方法,保证不同分辨率设备上间距一致:
private int dp2px(int dp) { return (int) (dp * getResources().getDisplayMetrics().density + 0.5f); }
可选优化
如果后续新增的输入框过多,可能会超出屏幕底部遮挡右下角按钮,你可以在根ConstraintLayout中嵌套一个ScrollView包裹所有输入框的展示区域,保证内容过多时可以滚动查看。
内容的提问来源于stack exchange,提问作者mockingbird
相关产品推荐
相关产品推荐

