2012-01-04 20 views
3

私がそれをスクロールするとリストビューが並べ替えられます。これは非常に混乱します。あなたのビュー(AvailableExpenseView)は項目で構成されているので、アダプタがconvertViewてビューを再利用しようとすると、その後、あなたはすでにあるビューを取得し、私はそれをスクロールすると、リストビューの順序が変わるのはなぜですか?

public class LoadExpenseList extends BaseAdapter{ 
     List<Expense> expenses; 
     Context context; 

     public LoadExpenseList(Context context, int textViewResourceId, 
       List<Expense> expenses) { 
      super(); 
      this.expenses = expenses; 
      this.context = context; 
     } 

     public View getView(final int position, View convertView, ViewGroup parent){ 
      //View v = convertView; 
      AvailableExpenseView btv; 

      if (convertView == null) { 
       btv = new AvailableExpenseView(context, expenses.get(position)); 
      } else { 
       btv = (AvailableExpenseView) convertView; 
      }   
      btv.setOnClickListener(new OnClickListener() { 

       @Override 
       public void onClick(View v) { 
        Log.i("Expense_Availables", "Item Selected!!"); 
        Intent intent = new Intent(getActivity(), ItemDetailActivity.class); 

        int id = expenses.get(position).getExpenseItemId(); 
        intent.putExtra("id", id); 

        startActivity(intent); 
       } 

      }); 

      btv.setOnLongClickListener(new OnLongClickListener() { 

       @Override 
       public boolean onLongClick(View arg0) { 
        // TODO Auto-generated method stub 
        return false; 
       } 

      }); 

      registerForContextMenu(btv); 

      return btv; 
     } 

     @Override 
     public int getCount() { 
      return expenses.size(); 
     } 

     @Override 
     public Object getItem(int position) { 
      return expenses.get(position); 
     } 

     @Override 
     public long getItemId(int position) { 
      return expenses.get(position).getExpenseItemId(); 
     } 

    } 

答えて

4

を:ここで

は、私が使用しているカスタムアダプタです別のアイテムに結びついている。

モデルアイテムでビューを構成しないでください。代わりに、convertView.setExpense(expenses.get(position))などと呼んでください。

ListViewはパフォーマンスを向上させるためにビューを再利用しようとします。つまり、リスト内の最初のアイテムは新しく作成されたビューで表示され、後でスクロールすると、以前作成したビューを再利用しようとします。ビューはconvertViewです。これらの行に注目してください:

 if (convertView == null) { 
      // You create a view using the proper item 
      btv = new AvailableExpenseView(context, expenses.get(position)); 
     } else { 
      // You don't override the item that was previously assigned 
      // when the view was created 
      btv = (AvailableExpenseView) convertView; 
     }  

convertViewがnullの場合は、新しいビューを作成しているが、あなたはアイテムを使用してビューを構築しています。これは、ポジション0で呼び出されるとしましょう。まず、リストにある費用を使用してビューを作成します。後でlistViewは位置20と言うビューを取得したいとし、「okは位置0に使用したビューを再利用できる」と言うので、このビューはconvertViewとして渡されますが、このビューはすでに位置0の項目で作成されていますこれを無効にしないでください。したがって、20番目のアイテムを表す最初のアイテムを持つビューを使用することになります。あなたがAvailableExpenseViewを編集し、あなたのビューを移入するsetExpense()メソッドを作成する必要があります。もちろん、

 AvailableExpenseView btv; 

     if (convertView == null) { 
      // dont create your view with an item 
      btv = new AvailableExpenseView(context); 
     } else { 
      btv = (AvailableExpenseView) convertView; 
     } 

     // Assign the expense wether it is a newly created view or 
     // a view that is reused 
     btv.setExpense(expenses.get(position)); 

:あなたは簡単にこのような何かを行うことができ、これを解決するために

+0

もっと詳しく説明できますか?私はあなたが何を意味するかはかなり分かりません。 – Cody

+0

私の答えを編集してください。 – aromero

0

リサイクルAvailableExpenseViewのために費用を.get(位置)に設定する必要があります。また、新しいインスタンスに対して行うこともできます。

インスタンスがリサイクルされ、間違った行(インスタンス化された行と再利用している行ではない行)で間違って表示される場合。

より正確には、あなたはAvailableExpenseViewのためにあなたのコードを与えることはありませんが、それは次に

よう
 public class AvailableExpenseView { 

      private Expense expense = null; 

      public class AvailableExpenseView(Context context) { 
      super(context); 
      }//cons 

      /* 
      Just add this method and use it. 
      */ 

      public void setExpense(Expense expense) { 
      this.expense = expense; 
      }//met 
     }//class 

をlookeも、あなたのアダプタでこれを実行します。

 if (convertView == null) { 
      btv = new AvailableExpenseView(context); 
     } 
     btv = (AvailableExpenseView) convertView; 
     btv.setExpense(expenses.get(expenses.get(position))); 

をそれはコンポーネントを持ってうれしいです緩いコンストラクタでボタンを作成するために何も必要ないJVM内の例について考えてみましょう。その後、直交メソッドによってカスタマイズすることができます:プロパティの "セッター"。コンポーネントをこのように設計すると、使いやすく、より多価になります。

0

あなたの問題はここにある:

if (convertView == null) { 
    btv = new AvailableExpenseView(context, expenses.get(position)); 
} else { 
    btv = (AvailableExpenseView) convertView; 
} 

convertViewがnullの場合、その後、あなたが位置に費用と新しいAvailableExpenseViewを作成します。これは問題ありません。

convertViewがnullでない場合は、既存のAvailableExpenseViewを参照します。これは、以前のケースでは、現在の位置に表示したいものとは異なる費用に初期化されています。

あなたは2つのオプションがあります。ブロック場合は、正しい費用は、あなたが新しいAvailableExpenseViewを作成または1つをリサイクルしているかどうかに使用されるように、この後にBTVのための費用を設定 -

か:他のブロックでは、リサイクルされたビューの正しいExpenseオブジェクトを設定します。

関連する問題