0

I have a listview which has a custom adapter where each row has a textview on the left and an edittext on the right of it that the user can use to modify an entries value.

The values that are placed in the EditText views within each view by default are obtained from a String array passed into the adapter.

I am wondering how I can allow the user to edit these values and save the results back in the same String array.

I have tried adding a text change listener so when the user edits the value the new string is placed at the appropriate position in the original string array. The problem with this is that when the user scrolls the text change listener is activated and the value in the array is overwritten with a blank string.

Here is some code:

public EditTagsListViewAdapter(Context context, String[] objectKeys, String[] objectValues) {
        super();
        this.context = context;
        this.objectKeys = objectKeys;
        this.objectValues = objectValues;
    }

    @Override
    public int getCount() {
        return objectKeys.length;
    }

    @Override
    public String[] getItem(int position) {
        String[] item = new String[2];
        item[0] = objectKeys[position];
        item[1] = objectValues[position];
        return item;
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        ViewHolder holder = null;

        LayoutInflater mInflater = (LayoutInflater)context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
        if (convertView == null) {
            convertView = mInflater.inflate(R.layout.edit_osm_tag_row, null);
            holder = new ViewHolder();
            holder.key = (TextView) convertView.findViewById(R.id.tagKey);
            holder.value = (EditText) convertView.findViewById(R.id.tagValue);

            convertView.setTag(holder);
        }
        else {
            holder = (ViewHolder) convertView.getTag();
        }

        String[] rowItem = (String[]) getItem(position);

        holder.key.setText(rowItem[0]);
        if(rowItem[1].equals("null")) {
            holder.value.setText("");
        } else {
            holder.value.setText(rowItem[1]);
        }

        holder.value.addTextChangedListener(new TextWatcher() {

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                // TODO Auto-generated method stub

            }

            @Override
            public void beforeTextChanged(CharSequence s, int start, int count,
                    int after) {
                // TODO Auto-generated method stub

            }

            @Override
            public void afterTextChanged(Editable s) {
                objectValues[position] = s.toString();
                Log.i(TAG, "Added changes to adapter");

            }
        });


        return convertView;
    }


    static class ViewHolder {
        protected TextView key;
        protected EditText value;
    }

I set some edittext values to blank after the if(rowItem[1].equals("null")) { because some of the values in the variable objectValues will be set as the string "null" but I want them to appear blank.

Hope this makes sense. Does anyone know how I can achieve this?

Thanks

sam
  • 2,469
  • 8
  • 37
  • 57

2 Answers2

2

In general your data source should not be tightly coupled with your view/adapter. This means that you can alter the data in that data source regardless of whether it is being used by your view. When the user wants to change the data, simply update your source (your array) and then instruct the adapter/view to redraw.

Some Adapters may take issue with you altering their content, but if you are implementing your own Adapter from scratch, or are using a loosely coupled Adapter class you shouldn't run into any issues.

If you are using an Adapter that extends BaseAdapter you can simply call notifyDataSetChanged() and the Adapter should figure out the rest.

mtmurdock
  • 12,756
  • 21
  • 65
  • 108
0

Rather than the TextWatcher, you can use an OnEditorActionListener to save the changes when the user presses "Enter" on the keyboard.

editText.setOnEditorActionListener(new OnEditorActionListener() {
    @Override
    public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
        if(actionId == EditorInfo.IME_NULL && event.getAction() == KeyEvent.ACTION_DOWN) {
            objectValues[position] = v.getText().toString();
            return true;
        }

        return false;
    }
});
Sam
  • 86,580
  • 20
  • 181
  • 179