Android - 使用自定义ArrayAdapter获取ListView的每个EditTexts值

时间:2014-05-30 11:04:27

标签: android list android-listview android-edittext android-arrayadapter

我有一个带有客户ArrayAdapter和自定义ListItem-XML的ListView。在这个ListView的底部,我添加了一个带有Button的FooterView。现在,我想在单击此按钮时获取每​​个ListItem中三个EditTexts的所有值。

以下是我的代码:

activity_checklistresult.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ListView
        android:id="@android:id/list"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</RelativeLayout>

result_inner_view.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/item_layout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:gravity="center">

    <TextView
        android:id="@+id/tv_result_amount"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="@dimen/default_margin" />
    <EditText
        android:id="@+id/et_result_amount"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="@dimen/default_margin"
        android:inputType="number" />

    <LinearLayout
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:gravity="center_vertical"
        android:orientation="vertical">

        <TextView
            android:id="@+id/tv_result_product_name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:singleLine="true"
            android:ellipsize="end"
            android:layout_margin="@dimen/default_margin" />
        <AutoCompleteTextView
            android:id="@+id/actv_search_product"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:singleLine="true"
            android:ellipsize="end"
            android:layout_margin="@dimen/default_margin"
            android:inputType="textAutoComplete" />

    </LinearLayout>

    <TextView
        android:id="@+id/tv_result_price"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="@dimen/default_margin" />
    <EditText
        android:id="@+id/et_result_price"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="@dimen/default_margin"
        android:inputType="numberDecimal" />

</LinearLayout>

ResultListActivity.java:

public class ChecklistResultActivity extends ListActivity
{
    private MyResultAdapter adapt;
    private Button confirmButton;
    private ChecklistResultActivity rActivity;

    @Override
    public void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_checklistresult);

        // Set my Custom ArrayAdapter for this ListActivity
        setAdapter();

        rActivity = this;
    }

    private void setAdapter(){
        adapt = new MyResultAdapter(this, R.layout.result_inner_view, Controller.getInstance().getOrderedProducts());
        setListAdapter(adapt);

        // Add the confirm button at the end of the list
        addFooterConfirmButton();
    }

    private void addFooterConfirmButton(){
        ListView lv = (ListView)findViewById(android.R.id.list);
        FrameLayout footerLayout = (FrameLayout) getLayoutInflater().inflate(R.layout.result_footer_view, null);
        confirmButton = (Button)footerLayout.findViewById(R.id.confirm_result_button);
        confirmButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ...

                // Get all EditText values (and compare them with the Default Value)
            }
        });
        lv.addFooterView(footerLayout);
    }

    ...

MyResultAdapter.java:

public class MyResultAdapter extends ArrayAdapter<OrderedProduct>
{
    private Context context;
    private int layoutResourceId;
    private LayoutInflater inflater;

    public MyResultAdapter(Context c, int layoutResourceId, List<OrderedProduct> objects){
        super(c, layoutResourceId, objects);
        this.layoutResourceId = layoutResourceId;
        this.context = c;
        inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent){
        View view = convertView;
        if(view == null)
            view = inflater.inflate(layoutResourceId, parent, false);

        ...

        return view;
    }
}

// Get all EditText values (and compare them with the Default Value)的ResultListActivity中,我想循环遍历所有OrderedProducts,并将这些的默认值与两个EditTexts和AutoCompleteTextView的新填充值进行比较。那么如何从Footer-Button的onClick中获取这些值?

提前感谢您的回复。

2 个答案:

答案 0 :(得分:13)

您的适配器必须为每个创建的EditText保存更改文本:

  1. 创建地图以保存值
  2. 为每个EditText
  3. 定义并设置通用TextWatcher
  4. 在editText上设置一个标签(使用其位置或任何位置) 您想要的ID)我们将此标记用作hashMap中的键
  5. 创建一个方法来检索给定EditText
  6. 的值

    适配器:

    public class MyResultAdapter extends ArrayAdapter<OrderedProduct>
    {
        ...
    
        private HashMap<String, String> textValues = new HashMap<String, String>();
    
        ...
    
        public ViewView getView(int position, View convertView, ViewGroup parent){
    
            View view = convertView;
            boolean convertViewWasNull = false;
            if(view == null){
                view = inflater.inflate(layoutResourceId, parent, false);
                convertViewWasNull = true;
            }
    
    
            myEditText1 = findViewById...
            myEditText2 = findViewById...
    
            if(convertViewWasNull ){
    
                //be aware that you shouldn't do this for each call on getView, just once by listItem when convertView is null
                myEditText1.addTextChangedListener(new GenericTextWatcher(myEditText1));
                myEditText2.addTextChangedListener(new GenericTextWatcher(myEditText2));
            }
    
            //whereas, this should be called on each getView call, to update view tags.
            myEditText1.setTag("theFirstEditTextAtPos:"+position);
            myEditText2.setTag("theSecondEditTextAtPos:"+position);
        }
    
    
        private class GenericTextWatcher implements TextWatcher{
    
           private View view;
           private GenericTextWatcher(View view) {
                this.view = view;
            }
    
            public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {}
            public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {}
    
            public void afterTextChanged(Editable editable) {
    
                String text = editable.toString();
                //save the value for the given tag :
                MyResultAdapter.this.textValues.put(view.getTag(), editable.toString());
            }
        }
    
        //you can implement a method like this one for each EditText with the list position as parameter :
        public String getValueFromFirstEditText(int position){
              //here you need to recreate the id for the first editText
             String result = textValues.get("theFirstEditTextAtPos:"+position);
             if(result ==null)
                  result = "default value";
    
             return result;
        }
    
        public String getValueFromSecondEditText(int position){
              //here you need to recreate the id for the second editText
             String result = textValues.get("theSecondEditTextAtPos:"+position);
             if(result ==null)
                  result = "default value";
    
             return result;
        }
    
    }
    

答案 1 :(得分:4)

您可以存储所有edittext值并在需要时获取它们,您可以将它存储在afterTextChange或onTextChange中,它取决于您。

public class MyResultAdapter extends ArrayAdapter<OrderedProduct>{
    ...

    private final String[] valueList;

    public MyResultAdapter(Context c, int layoutResourceId, List<OrderedProduct> objects){
        super(c, layoutResourceId, objects);

        ...

        valueList = new String[objects.size()];

    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent){
        View view = convertView;
        if(view == null)
            view = inflater.inflate(layoutResourceId, parent, false);

        ...

        //for edittext add text watcher listener

        final pos = position;

        editText.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) {
                 valueList[pos] = s.toString();
            }

            @Override
            public void afterTextChanged(Editable s) {

            }
        });

        return view;
    }

    public String[] getValueList(){
        return valueList;
    }
}