如何在不同的充气线性布局视图中设置具有相同ID的EditText的值?

3
我有一个主要布局,其中包含一个LinearLayout。在这个LinearLayout中,我填充了多个包含表单和多个文本字段(3 EditText)的xml布局。
第一次尝试时,我只显示了一个表单。有一个添加表单的按钮。例如,如果用户点击“添加”按钮两次,则用户共有三个表单。我成功地获取了这三个表单的所有数据。
为此,我针对主布局“LinearLayout”,计算其子元素数量。计算完子元素数量后,我通过其位置调用主LinearLayout的子视图,然后获取EditText数据并保存到列表中。然后我将此列表移动到下一页。到目前为止,一切都正常。但是,如果用户返回上一页,则所有填充的布局都会消失。因此,我在恢复时计算列表大小,并设置用户上次编写的值。
问题是当我根据视图位置设置EditText的值时。所有填充的布局中都只显示最后一个对象(列表中的最后一个对象)的值。也就是说,当循环结束时,它会在所有布局中设置最后一个对象的值。这是我设置视图值的方法:
private void addFormDataOnResume(LinearLayout viewForm,Traveller otherTraveller)
{
    EditText dateOfBirthEt = (EditText)viewForm.findViewById(R.id.dateOfBirth);

    dateOfBirthEt.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            showDatePickerDialog(dateOfBirthEt);
        }
    });

    dateOfBirthEt.setText(otherTraveller.getOtherDateOfBirth());

    EditText firstNameET = (EditText)viewForm.findViewById(R.id.firstName);
    firstNameET.setText(otherTraveller.getOtherFirstName());

    EditText lastNameEt = (EditText)viewForm.findViewById(R.id.lastName);
    lastNameEt.setText(otherTraveller.getOtherLastName());
}

我的循环代码:

int otherTraSize = otherTravellersData.size();
//adultsForms is the main linear layout in which I am adding views
for(k=0; k < otherTraSize; k++)
{
addFormOnResume();//Function for adding form layout
int viewPos = adultsForms.getChildCount();
if(viewPos>0)
{  
addFormDataOnResume(adultsForms.getChildAt(viewPos-1), otherTravellersData.get(k));
}
}

我的添加表单功能:

private void addFormOnResume()
{
    LinearLayout viewForm = (LinearLayout)layoutInflater.inflate(R.layout.other_traveller_form, null );
            adultsForms.addView(viewForm);

}

我调试了我的代码,列表中的所有数据看起来都很好。对象按照正确的顺序具有正确的值。
请帮助我理解为什么只有最后一个对象的值被设置到所有充气的表单中。

非常感谢您的帮助......提前致谢。


你如何使用for循环? - Misha Bhardwaj
我更新了我的代码,供您参考... - Waqas Ahmed Khan
仍需要 addFormOnResume,您是将表单布局添加到位置0或其他位置,而不是在末尾添加吗? - Amulya Khare
为什么不从 addFormOnResume() 返回添加的 View?你可以将它传递给 _addFormDataOnResume()_。 - 18446744073709551615
2
当Activity被恢复时,Android会通过ID还原其文本字段。这可能会干扰你的操作。要找出是否存在这种情况,可以在添加视图实例后立即记录视图实例及其相应的值(1),以及在一秒钟后或用户按下按钮时记录(2)。 - 18446744073709551615
显示剩余2条评论
3个回答

4
最终我得到了自己问题的答案。默认情况下,当一个活动进入暂停模式时,Android会保存EditText值,并在恢复时还原最后保存的EditText值。所以,在我的情况下,它会还原所有布局表单中的最后一个表单值。解决我的问题的方法是在XML上的widget entry上设置android:saveEnabled="false"。我在所有EditText中添加了这个属性。Android不再保存我的数据,并且在onResume中,我可以轻松地从指定位置获取childView的值,即使它们有相同的ID。

0

请使用以下代码替换您的循环代码:

int otherTraSize = otherTravellersData.size();
//adultsForms is the main linear layout in which I am adding views
for(k=0; k < otherTraSize; k++)
{
addFormOnResume();//Function for adding form layout
}

int viewPos = adultsForms.getChildCount();
if(viewPos>0)
{  
   for(int x=0; x<viewPos; x++){
      Log.d("current value",otherTravellersData.get(x).getOtherFirstName());
      addFormDataOnResume(adultsForms.getChildAt(viewPos-1), otherTravellersData.get(x));}
}

顺便说一下,我在我的帖子中进行了一些编辑。希望你正在尝试最新的代码。 - Misha Bhardwaj
请尝试更新的代码并让我知道logcat的输出结果好吗?我想验证是否传递了正确的数据。 - Misha Bhardwaj
它会被打印多少次?我的意思是,对于你所有的视图来说,这是否正确或者传递的是相同的数据? - Misha Bhardwaj
好的,你可以通过在addFormOnResume方法中使用setTag来为你的子视图添加不同的标记。然后在for循环中验证是否正在发送正确的标记。 - Misha Bhardwaj
1
最终我得到了自己问题的答案。默认情况下,当一个活动进入onPause模式时,Android会根据id保存EditText的值,并在恢复时还原EditText的最后保存值。所以,在我的情况下,它会在所有布局表单中还原上次的表单值。解决我的问题的方法是在XML上的小部件条目上设置android:saveEnabled="false"。我在所有EditText中都添加了这个。Android不再保存我的数据,而在onResume中,我可以通过从指定位置获取childView来设置表单字段的值,即使它们具有相同的Id。 :) - Waqas Ahmed Khan
显示剩余3条评论

-1

这是我的工作代码

 @Override
        public void onClick(View v) {
            switch (v.getId()) {

        case R.id.btnAdd:
            view = layoutInflater.inflate(R.layout.fragment_add_materials, null);
            parentLinearLayout.addView(view);
            arrayList.add(view);

            edtMaterialName = (EditText) view.findViewById(R.id.edtinput_material1);
            editTextCoast = (EditText) view.findViewById(R.id.editTextCoast1);

            edtMaterialName.addTextChangedListener(getMyTextWatcher(edtMaterialName,arrayListMaterials.size()-1 ,"name"));
            editTextCoast.addTextChangedListener(getMyTextWatcher(editTextCoast, arrayListMaterials.size()-1,  "cost"));

            break;




TextWatcher getMyTextWatcher(final EditText edtText, final int listPosition, String nameOrcost){
            return new MyTextWatcher(edtText, listPosition, nameOrcost);
        }




class MyTextWatcher implements TextWatcher{
    int position;
    EditText edtText;
    String nameOrcost;
    MaterialData data;
    boolean flag;
    int count;

    public MyTextWatcher(EditText edtText1, int listPosition, String nameOrcost){
        this.position = listPosition;
        this.edtText=edtText1;
        this.nameOrcost = nameOrcost;
        data = arrayListMaterials.get(position);

    }

    @Override
    public void afterTextChanged(Editable sEditable) {
        try{
        if(this.nameOrcost.equals("name") && edtText.getEditableText().toString().length()>0){
            data.setMaterialName(edtText.getEditableText().toString());
        }
        if(this.nameOrcost.equals("cost") && edtText.getEditableText().toString().trim().length()>0){
            String tempCost = edtText.getEditableText().toString().trim();
            NumberFormat myFormatter = NumberFormat.getInstance();
            Number number = myFormatter.parse(tempCost);

            data.setMaterialprice(new BigDecimal(number.toString()).toString());
        }
        arrayListMaterials.set(position, data);
        setTotalPrice(arrayListMaterials);
        }catch (Exception e) {
            e.printStackTrace();
        }
        if(this.nameOrcost.equals("cost") && edtText.getEditableText().toString().trim().length()>0){
            Utilty.insertCommaIntoNumber(edtText, sEditable.toString());
        }
    }

    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {
        try{    
            if(this.nameOrcost.equals("cost"))
            data.setMaterialprice("0");

            if(this.nameOrcost.equals("name"))
            data.setMaterialName("");

            arrayListMaterials.set(position, data);

        }catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {
    }


}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接