2017-01-23 12 views
0

私はListViewのためのアダプタを作成しました。本当に変な動作をしています。リストビューにはオブジェクトのリストが渡され、いくつかのルールでソートされます(数を比較するとうわ...)。ここでリストがビューに表示されると、重複したエントリが表示され、並べ替えられず、エントリが失われ、リストをスクロールするとエントリが変更されます。何が起こっている?ここでなぜ私のリストビューはAndroidで奇妙に動作しますか?

はそれが必要な場合、私はより多くのコードを投稿することができ、アダプタのコードです:

public class StatViewAdapter extends BaseAdapter { 

    Activity activity; 
    ArrayList<Entry> entries; 

    TextView txtName; 
    TextView txtOK; 
    TextView txtNOK; 
    TextView txtHist; 
    TextView txtPrandom; 
    TextView txtPhist; 
    TextView txtPtotal; 

    //public StatViewAdapter(Activity activity, ArrayList<HashMap<String, String>> list){ 
    public StatViewAdapter(Activity activity, ArrayList<Entry> entries){ 

     super(); 
     this.activity=activity; 
     this.entries = entries; 

     Collections.sort(this.entries, new Comparator<Entry>() { 
      @Override 
      public int compare(Entry o1, Entry o2) { 
       if (o1.getPriority() > o2.getPriority()) { 
        return 1; 
       } 
       if (o1.getPriority() < o2.getPriority()) { 
        return -1; 
       } 
       return 0; 

      } 
     }); 

     for (int i=0;i<this.entries.size();i++) { 
      String name = this.entries.get(i).name(); 
      int p = this.entries.get(i).getPriority(); 
      System.out.println(String.format("%s: %d", name, p)); 
     } 


    } 

    @Override 
    public int getCount() { 
     // TODO Auto-generated method stub 
     //return list.size(); 
     return this.entries.size(); 
    } 

    @Override 
    public Object getItem(int position) { 
     // TODO Auto-generated method stub 
     return this.entries.get(position); 
    } 

    @Override 
    public long getItemId(int position) { 
     // TODO Auto-generated method stub 
     return 0; 
    } 



    @Override 
    public View getView(int position, View convertView, ViewGroup parent) { 
     // TODO Auto-generated method stub 

     LayoutInflater inflater=this.activity.getLayoutInflater(); 

     if(convertView == null){ 

      convertView=inflater.inflate(R.layout.list_view, null); 

      txtName=(TextView) convertView.findViewById(R.id.listname); 
      txtOK=(TextView) convertView.findViewById(R.id.listok); 
      txtNOK=(TextView) convertView.findViewById(R.id.listnok); 
      txtHist=(TextView) convertView.findViewById(R.id.listhist); 
      txtPrandom =(TextView) convertView.findViewById(R.id.listprandom); 
      txtPhist=(TextView) convertView.findViewById(R.id.listphist); 
      txtPtotal=(TextView) convertView.findViewById(R.id.listptot); 
     } 

     Entry entry = this.entries.get(position); 
     txtName.setText(entry.name()); 
     txtOK.setText(Integer.toString(entry.number_ok)); 
     txtNOK.setText(Integer.toString(entry.number_nok)); 
     txtHist.setText(entry.history); 
     txtPrandom.setText(Integer.toString(entry.randomIndex)); 
     txtPhist.setText(Integer.toString(entry.histIndex)); 
     txtPtotal.setText(Integer.toString(entry.getPriority())); 

     return convertView; 
    } 

} 
+1

明らかに、アダプタの – Selvin

+0

にアイテムのビューへの参照が直接格納されているためです。説明できますか?それは私には明らかではない... – Alex

+0

convertViewがnullではないが、getViewから返された最後のビューと同じではない場合、何が起きるかを分析する – Selvin

答えて

2

public View getView(int position, View convertView, ViewGroup parent)の目的は、ビューに指定されたpositionでオブジェクトのデータをバインドすることです。ビューはリサイクルされたビュー(convertView)であるか、メソッド内にビューを作成する必要があります。問題は、Adapterのビュー(txtNametxtOk)への参照を保持しないことです。

public class StatViewAdapter extends BaseAdapter { 

    Activity activity; 
    ArrayList<Entry> entries; 

    //TextView txtName; 
    //TextView txtOK; 
    // ... 

    public StatViewAdapter(Activity activity, ArrayList<Entry> entries){ 
    // ... 

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

     LayoutInflater inflater=this.activity.getLayoutInflater(); 

     if(convertView == null){ 
      convertView=inflater.inflate(R.layout.list_view, null); 
     } 

     TextView txtName=(TextView) convertView.findViewById(R.id.listname); 
     TextView txtOK=(TextView) convertView.findViewById(R.id.listok); 
     // ... 

     Entry entry = this.entries.get(position); 
     txtName.setText(entry.name()); 
     txtOK.setText(Integer.toString(entry.number_ok)); 
     // .... 

     return convertView; 
    } 

それは動作しますが、それはまだそれを行うには良い方法ではありません、あなたはRecyclerViewを使用するか、ViewHolderパターンを実装する場合があります。

ViewHolderパターンのアイデアは、あなたはそれが計算上高価だし、それはスクロールがラグ作ることができるので、あなたがビューをバインドするたびにfindViewByIdを呼び出す必要がないということです。

RecyclerViewは、ListViewと同じジョブを実行し、ViewHolderパターンが組み込まれた、より新しい、より柔軟なビューであるため、使いたいと思うかもしれません。

+0

いいえ、動作しません。私は同じ結果を見る。多分私はプロジェクトをきれいにする必要があります。一瞬... – Alex

+0

これはうまくいくようです。しかし、なぜこれは良い方法ではありません。 'RecyclerView'とは何ですか?リストビューにデータを表示するだけで、ビューをリサイクルしたくないのです...? – Alex

+0

私はそれが正当な理由ではない理由の答えを編集しました。また、答えを受け入れることを考慮してください。 – lelloman

関連する問題