EditText в ListView без его повторного ввода - PullRequest
5 голосов
/ 25 февраля 2012

Все еще плохо знаком с android и даже больше с пользовательским адаптером курсора, поэтому у меня возникают проблемы с пониманием того, как запретить повторному просмотру моего списка просмотра для предотвращения ввода из одного текста редактирования в другое при прокрутке. В другом посте я видел, как изменить имя convertview, но как это сделать, я рисую пустым. Я надеялся, что кто-то здесь сможет дать более подробную информацию или пример того, как это сделать, основываясь на том коде, который я написал до сих пор.

public class editview extends ListActivity {
    private dbadapter mydbhelper;
    private PopupWindow pw;
    public static int editCount;
    public static ListView listView;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mydbhelper = new dbadapter(this);
        mydbhelper.open();


        View footer = getLayoutInflater().inflate(R.layout.footer_layout, null);
        ListView listView = getListView();
        listView.addFooterView(footer);
        showResults();
        }

    //Populate view
    private void showResults (){
        Cursor cursor = mydbhelper.getUserWord();
        startManagingCursor(cursor);
        String[] from = new String[] {dbadapter.KEY_USERWORD};
         int[] to = new int[] {R.id.textType};
         ItemAdapter adapter = new ItemAdapter(this, R.layout.edit_row, cursor,
                        from, to);
            adapter.notifyDataSetChanged();
            this.setListAdapter(adapter);
            editCount = adapter.getCount();

    }


            //footer button
            public void onClick(View footer){
                    final MediaPlayer editClickSound = MediaPlayer.create(this, R.raw.button50);
                    editClickSound.start();
                    startActivity(new Intent("wanted.pro.madlibs.OUTPUT"));

                }

//custom cursor adapter
class ItemAdapter extends SimpleCursorAdapter {
    private LayoutInflater mInflater;
    private Cursor cursor;


    public ItemAdapter(Context context, int layout, Cursor cursor, String[] from,
            int[] to) {
        super(context, layout, cursor, from, to);
        this.cursor = cursor;
        mInflater = LayoutInflater.from(context);

    }


    static class ViewHolder {
        protected TextView text;
        protected EditText edittext;

    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {


        ViewHolder holder;
        if (convertView == null) {
            convertView = mInflater.inflate(R.layout.edit_row, null);


             holder = new ViewHolder();
            holder.text = (TextView) convertView.findViewById(R.id.textType);
            holder.edittext = (EditText) convertView.findViewById(R.id.editText);



            convertView.setTag(holder);

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

        }
        cursor.moveToPosition(position);
        int label_index = cursor.getColumnIndex("userword"); 
        String label = cursor.getString(label_index);

        holder.text.setText(label);

        return convertView;

    }

}

Изменено на

class ItemAdapter extends SimpleCursorAdapter {
    private LayoutInflater mInflater;
    private Cursor cursor;
    Map<Integer, String> inputValues = new HashMap<Integer, String>();
    public View getView(final int position, View convertView, ViewGroup parent) {
        ....

        ViewHolder holder;
        if (convertView == null) {
            convertView = mInflater.inflate(R.layout.edit_row, null);


             holder = new ViewHolder();
            holder.text = (TextView) convertView.findViewById(R.id.textType);
            holder.edittext = (EditText) convertView.findViewById(R.id.editText);


            convertView.setTag(holder);

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

        }
        cursor.moveToPosition(position);
        int label_index = cursor.getColumnIndex("userword"); 
        String label = cursor.getString(label_index);

        holder.text.setText(label);
        String oldText =  inputValues.get(position);
        holder.edittext.setText(oldText == null ? "" : oldText); 
        holder.edittext.addTextChangedListener(new TextWatcher(){
            public void afterTextChanged(Editable editable) {
                inputValues.put(position, editable.toString());
            }

но он перерабатывается после того, как все edittext имеют данные. Пытался использовать holder.edittext.setText (oldText), но тот же эффект.

Start filling in fields

Finish filling in fields

Scroll up.

Ответы [ 2 ]

4 голосов
/ 25 февраля 2012

Прежде всего, вы действительно не хотите предотвращать повторное использование представлений списка. Просмотр утилизации - это огромная оптимизация. Для получения действительно полезной информации о списках см. Google IO talk: http://www.youtube.com/watch?v=wDBM6wVEO70

При этом вы правильно определили свою проблему: у вас намного меньше правок EditTexts, чем у элементов в вашем списке. Когда вы прокручиваете список, эти EditTexts перерабатываются, и вы снова и снова видите один и тот же ввод.

По сути, вам нужно сохранить входные данные для ваших EditTexts в некоторой структуре данных (HashMap, если они будут редактировать только несколько значений, возможно, List, если они будут изменять большинство значений, либо будет работать), который отображает положение для входа. Вы можете сделать это, добавив textChangedListener к вашим текстам редактирования в getView:

@Override
public View getView(final int position, View convertView, ViewGroup parent){
    ...
    cursor.moveToPosition(position);
    int label_index = cursor.getColumnIndex("userword");
    String label = cursor.getString(label_index);

    holder.text.setText(label);

    //clear whatever text was there from some other position
    //and set it to whatever text the user edited for the current 
    //position if available
    String oldText = yourMapOfPositionsToValues.get(position);
    holder.setText(oldText == null ? "" : oldText); 

    //every time the user adds/removes a character from the edit text, save 
    //the current value of the edit text to retrieve later
    holder.edittext.addTextChangedListener(new TextWatcher(){
        @Override
        public void afterTextChanged(Editable editable) {
            yourMapOfPositionsToValues.put(position, editable.toString());
        }
        ....
    };

    return convertView;
}

Всякий раз, когда ваш пользователь заканчивает редактирование, вы можете просматривать структуру данных и делать с этими значениями все, что угодно.

Edit:

Я изменил onTextChanged на afterTextChanged, потому что я использовал это раньше, и я знаю, что это работает. Имейте в виду, что afterTextChanged вызывается каждый раз, когда изменяется LETTER, а не только после того, как пользователь заканчивает вводить слово. Если пользователь вводит «dog», то afterTextChanged будет вызываться три раза, сначала с «d», затем с «do», затем с «dog».

HashMap прост: отобразите yourMapOfPositionsToValues ​​= new HashMap ();

для добавления или обновления элемента: yourMap.put (position, someText); чтобы получить элемент: yourMap.get (position);

если хешмапы не имеют смысла, потратьте некоторое время на их изучение. Это невероятно важная структура данных.

Ваша реализация TextWatcher неверна. Ваша структура данных должна принадлежать не одному представлению, а деятельности или вашему адаптеру. Вам кажется, что позиции не стабильны, потому что ваш список принадлежит каждому представлению. Сами позиции стабильны в том смысле, что если базовые данные не изменятся, курсор будет возвращать одни и те же данные каждый раз для одной и той же позиции. Однако текст редактирования используется для нескольких различных позиций.

Создайте хеш-карту в качестве переменной экземпляра, которую я продемонстрировал выше, в конструкторе вашего адаптера. Затем добавьте именно тот TextWatcher, который я написал изначально, нет необходимости в именованном классе, проще анонимный. Ваш код должен работать.

1 голос
/ 04 июня 2015

Решением этой проблемы является удаление добавленного текстового наблюдателя перед настройкой текста.В противном случае предыдущий текстовый наблюдатель в этом представлении будет по-прежнему вызываться вместе с новым текстовым наблюдателем.Сохраните текстовый наблюдатель как тег на EditText, чтобы отслеживать его.

Object oldWatcher = viewHolder.quantitySold.getTag();
    if(oldWatcher != null){
        viewHolder.quantitySold.removeTextChangedListener((CustomTextWatcher)oldWatcher);
    } 
    String oldText =  inputValues.get("key"+position);
    Log.d(TAG, "oldText: "+oldText+" position: "+position);
    viewHolder.quantitySold.setText(oldText == null ? "" : oldText);
    CustomTextWatcher watcher = new CustomTextWatcher(
            cursor.getString(SKUFragment.COL_NAME),
            cursor.getInt(SKUFragment.COL_ID),
            cursor.getDouble(SKUFragment.COL_UNIT_PRICE),
            position
    ) {
        @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) {
            if (s != null) {
                int quantity = 0;
                if (!TextUtils.isEmpty(s.toString())) {
                    quantity = Integer.parseInt(s.toString());
                    inputValues.put("key"+mPosition, "" + quantity);
                }else{
                    inputValues.put("key"+mPosition, "");
                }
                double value = quantity * skuPrice;
                mListener.onQuantityChanged(skuName+", position: "+mPosition, skuId, quantity, value);
            }
        }
    };
    viewHolder.quantitySold.setTag(watcher);
    viewHolder.quantitySold.addTextChangedListener(watcher);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...