4

各行にwith listview1textviewと aがあります。edit text1 つのエディット テキスト フィールドに値を設定してから下にスクロールすると、入力したフィールド値の値が他のエディット テキスト フィールドに重複して表示されます。この問題を解決するにはどうすればよいですか?

私のアダプタークラスは次のとおりです。

public class CustomAdapter extends ArrayAdapter<String> {
  private Context       context;
  private String[]  names;
  ViewHolder holder;

  static class ViewHolder {
    public TextView text;
    public EditText editText;
  }

  public CustomAdapter(Context context, int textViewResourceId, String[] names) {
    super(context, textViewResourceId, names);
    this.context = context;
    this.names = names;
  }

  @Override
  public View getView(int position, View convertView, ViewGroup parent) {
    if (convertView == null) {
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        convertView = inflater.inflate(R.layout.row_design, parent, false);
        holder = new ViewHolder();
        holder.text = (TextView) convertView.findViewById(R.id.textView1);
        holder.editText = (EditText) convertView.findViewById(R.id.editText1);
        convertView.setTag(holder);         
    } else {            
        holder = (ViewHolder) convertView.getTag();
    }

    String s = names[position];
    holder.text.setText(s);
    return convertView;
  }
}

私はこのリンクを参照しました: Listview duplicate actionAndroid listview duplicates the item on scroll

4

4 に答える 4

5

この問題の最初の理由は、リストビューがスクロール時にそのビューを再利用するため、それを管理するためのロジックが get ビューに必要です。

if(convertview == null)
{
 //code here 
}else {
 //code here 
}    

ですが、再利用したくない場合は、次を使用できます。

 @Override
  public int getItemViewType(int position) {
    return position;
}

@Override
public int getViewTypeCount() {
    return 500;
}
于 2014-04-16T08:53:11.510 に答える
0

これは私が今まで考えた中で最高です。しかし、回避策としてこれを試してください。この問題に対するより良い/よりクリーンな解決策があることに同意します。

あなたが直面している問題は、ListViewパフォーマンスを向上させるためにビューをリサイクルするためです。

まず、データをList配列ではなく、以下のように変更していただけないでしょうか。

List<String> names;
List<String> edit;

// In Constructor()
this.names = names;
// Create a list with empty data for the editTexts
int listSize = names.size();
String emptyString = new String("");
List<String> emptyList = new ArrayList<String>(listSize);
for(int i = 0; i < listSize; i ++){
    emptyList.add(emptyString);
}
this.edit = emptyList;

// In getView()
// add watcher to editText and when it is changed, update the value in 'edit'
// Simply set the corresponding values to this row to the editText
holder.text.setText(names.get(position));
holder.editText.setText(edit.get(position));

これで問題が短期間で解決するかどうかを確認できますか。

この回答https://stackoverflow.com/a/11181721/592025から監視の使用方法を確認できます

于 2013-10-24T10:23:02.887 に答える
0

以下のコードを試してください:

public class CustomAdapter extends ArrayAdapter<String> {
  private Context       context;
  private String[]  names;

  static class ViewHolder {
    public TextView text;
    public EditText editText;
  }

  public CustomAdapter(Context context, int textViewResourceId, String[] names) {
    super(context, textViewResourceId, names);
   this.context = context;
    this.names = names;
  }

  @Override
  public View getView(int position, View convertView, ViewGroup parent) {
    View rowView = convertView;
    if (convertView == null) {
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        rowView = inflater.inflate(R.layout.row_design, parent, null);
        ViewHolder viewHolder = new ViewHolder();
        viewHolder.text = (TextView) rowView.findViewById(R.id.textView1);
        viewHolder.editText = (EditText) rowView.findViewById(R.id.editText1);
        rowView.setTag(viewHolder);         
    }          
        ViewHolder holder = (ViewHolder)rowView.getTag();


    String s = names[position];
    holder.text.setText(s);
    return rowView;
  }
}

詳細については、このリンクを参照してください。

それがあなたを助けることを願っています。

于 2013-10-24T04:28:33.177 に答える
0

アップデート:

以下の私の元の解決策はこのユースケースで機能しますが、はるかに優れた解決策は、ViewHolderHailNaRoz が触れたパターンの解決策です。HailNaRoz は彼のソリューションが機能する理由を説明していませんが、そのソリューションは再利用ViewHolderを支援するためにView使用されており、Google と Android Dev コミュニティによって採用されている推奨される方法です。は( 、など) へのViewHolder参照を保持し、表示されたときにそれらを正しいリスト行に追加し直すことができます。ViewsEditTextTextViewImageView

RecyclerViewまた、これらの問題の一部を軽減するために導入され、この方法論を強制する にも注目する価値があります。RecyclerViewgradleに追加できるサポートライブラリとして利用可能

リスト ビューのビュー ホルダーおよびリストとカードの作成 (リサイクラー ビュー)を参照してください。

オリジナル:

あなたの問題は、あなたEditTextがリサイクルされていることです。テキストのコピーを保持し、TextViewロードされるたびにリセットしますが、EditText.

そのため、テキストをEditTextフィールドに保存し、メソッドでリセットする方法が必要getView()です。

TextWatcherこれを行うには、if/else ステートメントの後に次のように設定しgetView()ます。

holder.editText.addTextChangedListener(new TextWatcher() {

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

            public void beforeTextChanged(CharSequence s, int start,
                    int count, int after) {
            }

            public void afterTextChanged(Editable s) {
                  editTextList.put(position,s.toString());
            }
        });

これにより、値がHashMap個別に保持されます。positionメソッドの int パラメータから取得されますgetView()。最終的なものにする必要があります。

HashMap:_

private HashMap<Integer,String> editTextList =new HashMap<Integer,String>();

次に、TextViewテキストを設定するときに、EditText値も設定します。

holder.text.setText(s);
holder.editText.setText(editTextList.get(position));

これにより、現在の位置のeditText値が正しいEditTextボックスに保持されます。

于 2013-10-24T10:45:24.827 に答える