2017-06-14 7 views
0

誰かが私を完全に狂ってしまう前に助けてください。AndroidのListViewで項目を選択すると奇妙な動作が発生する

リストビューがあるとします。それには9項目ありますが、スクロールせずに6を表示するスペースしかありません。項目が選択されている場合は、背景色がこの値を示すように変わります。

2から8までの項目を選択すると、すべてが世界で良好です。

項目1を選択すると、項目9とその逆も選択されます。また、ランダムな回数だけ上下にスクロールすると、選択が変更されます。上下にスクロールし続けると、選択範囲は1と9に戻ります。選択した項目の値は、常に選択した実際の項目です。

これは私のアダプターからの私のコードです:

public class AvailableJobAdapter extends ArrayAdapter<JobDto> { 
 

 
    private Context context; 
 
    private ArrayList<JobDto> items; 
 
    private LayoutInflater vi; 
 

 
    public AvailableJobAdapter(Context context, ArrayList<JobDto> items) { 
 
     super(context, 0, items); 
 
     this.context = context; 
 
     this.items = items; 
 
     vi = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
 
    } 
 

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

 
     ViewHolder holder = null; 
 

 
     JobDto jh = getItem(position); 
 

 
     if (convertView == null) { 
 
      convertView = vi.inflate(R.layout.inflator_job_list, null); 
 

 
      holder = new ViewHolder(); 
 

 
      holder.numberText = (TextView) convertView.findViewById(R.id.txtNumber); 
 
      holder.descriptionText = (TextView) convertView.findViewById(R.id.txtDescription); 
 
      holder.statusText = (TextView) convertView.findViewById(R.id.txtStatus); 
 

 
      convertView.setTag(holder); 
 

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

 
     holder.numberText.setText(jh.getJobNumber()); 
 
     holder.descriptionText.setText(jh.getDescription()); 
 
     holder.statusText.setText(jh.getStatus()); 
 

 
     return convertView; 
 
    } 
 

 
    public static class ViewHolder { 
 
     public TextView numberText; 
 
     public TextView descriptionText; 
 
     public TextView statusText; 
 
    } 
 
}

と、これは私のクリックのリスナーからのコードです:

jobs.setOnItemClickListener(new AdapterView.OnItemClickListener() { 
 
      @Override 
 
      public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 
 
       Button btnOk = (Button) findViewById(R.id.btnOk); 
 

 
       view.setSelected(true); 
 

 
       int selected = position; 
 

 
       int pos = val.get(selected); 
 

 
       int firstItem = jobs.getFirstVisiblePosition(); 
 
       int viewIndex = selected - firstItem; 
 

 
       if (pos == 0) { 
 

 

 
        jobs.getChildAt(viewIndex).setBackgroundColor(getResources().getColor(R.color.selected)); 
 

 
        val.set(selected, 1); 
 

 
        selectedCount ++; 
 

 
       } else { 
 

 
        jobs.getChildAt(viewIndex).setBackgroundColor(getResources().getColor(R.color.unselected)); 
 

 
        val.set(selected, 0); 
 

 
        selectedCount --; 
 
       } 
 

 
       if (selectedCount > 0){ 
 
        btnOk.setEnabled(true); 
 
       } else { 
 
        btnOk.setEnabled(false); 
 
       } 
 

 
      } 
 

 
     });

私はこれを研究し、さまざまな提案を試みるのに数時間を費やしました。

ご協力いただきますようお願い申し上げます。

**** EDIT **** いくつかの提案をした後、巨大なリストでテストしました。

アイテム1を選択した場合、あなたの画面は、10の項目のためのスペースを持っている場合、それはまた、これらの値の間では11、21、31、41など

何が正しく動作浮き彫りに - :これは動作が正確に何であります。

+0

「val」とは何ですか?私は宣言が表示されません –

+0

valは、複数の選択を記憶するために使用している整数のArrayListです – MagicWand

答えて

0

:あなたのListViewをアダプタに接続されている場合、リストビューは完全にリストの全高を満たすのに十分なアイテムが移入されるまで

、アダプターは、行をインスタンス化します。その時点で、追加の行項目はメモリに作成されません。

代わりに、ユーザーがリストをスクロールすると、画面を離れたアイテムは後で使用できるようにメモリに保持され、その後、画面に入る新しい行はすべて、メモリ内に保持されている古い行を再利用します。このように、1000個のアイテムのリストであっても、〜7個のアイテムビューの行だけがインスタンス化されたり、メモリに保持されたりします。

これは、あなたが直面している問題の根源です。クリックリスナーのビューの背景色を変更しています。しかし、選択した項目が画面からスクロールされると、その項目はスワイプされている新しい項目に対して再利用されます。再利用されたビューの背景色が変更されたため、新しいアイテムは結果的に同じ色になります。

ビューはリサイクルされていることを考慮する必要があるため、getView()で取得すると「ダーティ」になる可能性があります。私はあなたが上の引用符を得た場所からガイドを見てお勧めします、それは素敵で重要な読書です。

これを修正するには、ブール値フィールドをJobDtoクラスに追加し、項目を選択したかどうかを追跡するために使用します。 getView()では、それに応じて背景色を更新することができます。おそらく、背景色を変更するために、アイテムルートビュー(convertView)をViewHolderに追加する必要があります。

+0

遅延の申し訳ありません。これは私のためにそれを釘付けにしました。あなたの助けに感謝します。 – MagicWand

0

setOnItemClickListener()でのみ更新setSelected()クリックされた位置とnotifydatasetの場合はfalseになります。 getViewで条件を入力してください

if(jh.isSelelcted()) 
{ 
// background is selected color 
}else{ 
// background is non selected color 
} 

注:他の条件を処理します。 this guideから

関連する問題