6

ListBoxの上にCheckBoxアイテムを持つCheckBoxがあります。チェックボックスをチェックすると、notifyDataSetChanged()が適用され、リストのすべての項目がすべてチェックされます。だから、私はnotifyDataSetChanged()を1回呼び出すと、getViewメソッドが2回ログを取得しているので、getViewが2回呼び出されていることを意味します。だから、誰が私になぜログを2回取得しているのか教えてもらえますか? getView()が2回呼び出される理由も?CheckBoxを使用したListViewの奇妙な振る舞い

メインクラス - アダプタクラスのための

checkAll = (CheckBox) findViewById(R.id.my_check_box); 
     checkAll.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { 

      @Override 
      public void onCheckedChanged(CompoundButton checkbox, boolean arg1) { 
       adapter.notifyDataSetChanged(); 
      } 
     }); 

コード - 私はCheckAllのcheckboxs上adapter.notifyDataSetChanged();が変更リスナーを確認することができます

public class myAdapter extends ArrayAdapter<Model> { 

    private final List<Model> list; 
    private final Activity context; 
    private CheckBox checkAll; 

    public myAdapter(Activity context, List<Model> list, CheckBox checkAll) { 
     super(context, R.layout.row, list); 
     this.context = context; 
     this.list = list; 
     this.checkAll = checkAll; 

    } 

    static class ViewHolder { 
     protected TextView text; 
     protected CheckBox checkbox; 
    } 

    @Override 
    public View getView(final int position, View convertView, ViewGroup parent) { 
     View view = null; 
     if (convertView == null) { 
      LayoutInflater inflator = context.getLayoutInflater(); 
      view = inflator.inflate(R.layout.row, null); 
      final ViewHolder viewHolder = new ViewHolder(); 
      viewHolder.text = (TextView) view.findViewById(R.id.label); 
      viewHolder.checkbox = (CheckBox) view.findViewById(R.id.check); 
      viewHolder.checkbox 
        .setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { 

         @Override 
         public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 
          Model element = (Model) viewHolder.checkbox.getTag(); 
          element.setSelected(buttonView.isChecked()); 
         } 
        }); 
      view.setTag(viewHolder); 
      viewHolder.checkbox.setTag(list.get(position)); 
     } else { 
      view = convertView; 
      ((ViewHolder) view.getTag()).checkbox.setTag(list.get(position)); 
     } 
     ViewHolder holder = (ViewHolder) view.getTag(); 
     holder.text.setText(list.get(position).getName()); 


     if(checkAll.isChecked() == true){ 
      System.out.println(position+" checked th position"); 
     } 
     else if(checkAll.isChecked() == false){ 
      System.out.println(position+" not checked th position"); 
     } 

     holder.checkbox.setChecked(list.get(position).isSelected());  
     return view; 
    } 
} 

LogCat出力。

11-30 20:31:33.751: INFO/System.out(1300): 0 checked th position 
11-30 20:31:33.761: INFO/System.out(1300): 1 checked th position 
11-30 20:31:33.770: INFO/System.out(1300): 2 checked th position 
11-30 20:31:33.780: INFO/System.out(1300): 3 checked th position 
11-30 20:31:33.810: INFO/System.out(1300): 4 checked th position 
11-30 20:31:33.810: INFO/System.out(1300): 0 checked th position 
11-30 20:31:33.831: INFO/System.out(1300): 1 checked th position 
11-30 20:31:33.831: INFO/System.out(1300): 2 checked th position 
11-30 20:31:33.851: INFO/System.out(1300): 3 checked th position 
11-30 20:31:33.860: INFO/System.out(1300): 4 checked th position 

Logcatの出力が同じ出力を2回取得していることがわかります。だから誰がなぜこれが起こっているのかを教えてもらえますか?

+1

この問題も私と一緒に起こります... +1 –

+2

http:// stackoverflow。com/questions/2618272/custom-listview-adapter-getview-method-being-multiple-times-and-no-coこれをチェックしてください – MKJParekh

+0

@Lalit Poptaniあなたはスクロールしますか? – Venky

答えて

5

あなたListView高さfill_parentを作ってみましょう。

Lisiviewは、提供されたスペースごとに少し調整しようとしていますが、これは私が学んだことです。これが背後にある理由です。

役立つかどうかを確認してください。

+2

を解決します。これは、画面の半分であなたのリストビューを設定したいときに意味します。あなたは上記の問題を解決できませんか? – MKJParekh

+0

は、画面の半分にfill_parent .............. – viv

+0

を置くことができます。画面の半分でリストビューを設定したい場合は、そのためにアンドロイド:layout_weightを使用できます –

0

これは、checkchangelistener内のviewHolderがリストのスクロールに伴って変化することを意味します。したがって、チェックボックスとviewHolderの間のマッピングは、この方法では実現できません。

作成sepateraクラスcheckchangelistenerはchecnChecnglistenerを実装します。コンストラクタを介してcheckchangelistenerを渡します。

EG。 getViewメソッド

viewHolder.checkbox .setOnCheckedChangeListener(新しいMycheckChangeListenet(viewHolder))で

class MyCheckChangeLsitenet implements CompoundButton.OnCheckedChangeListener 

ViewHolder viewHolder 
MyCheckChangeLsitenet(ViewHolder viewHolder) 
{ 
this.viewHolder = viewHolder ; 
} 
         @Override 
         public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 
          Model element = (Model) viewHolder.checkbox.getTag(); 
          element.setSelected(buttonView.isChecked()); 
         } 
        }); 

getViewメソッド

+1

同じ問題を抱えていますが、現在私はリストをスクロールしていません。 –

+0

用語のスクロールを忘れてしまった。内部のListView処理に慣れさせようとしています。記載された方法で進む。あなたの問題 –

3

これは本当にあなたの質問への答えではありません - それは私がこれを見たときに、それは少し私の目を傷つけることだけです:

if(checkAll.isChecked() == true){ 
    System.out.println(position+" checked th position"); 
} 
else if(checkAll.isChecked() == false){ 
    System.out.println(position+" not checked th position"); 
} 

if-statementboolean発現を必要とする方法isChecked()以来boolean theresのを返します。 true/falseと対戦する必要はありません。また、booleantrueまたはfalseにしかなりませんので、両方を確認する必要はありません。要するに、あなたはに上記煮詰めることができます。

if(checkAll.isChecked()) 
    System.out.println(position+" checked th position"); 
else 
    System.out.println(position+" not checked th position"); 

はるかにきれい:-)

どちらがあなたのプログラミングのスキルの批判としてこれを見てはいけない - ちょうど学習oppertunityとしてそれを参照してください。

+0

私の問題についての正確なアイデアを得るためのデモアプリケーションです。ありがとう、ありがとう。 –

+0

それは陽気です、kaspermoerch!これを試してみてください: 'System.out.println(position +(checkAll.isChecked()?"チェックされた位置 ":"チェックされていない位置 "))' –

+0

これも機能します。私は、しかし、三元演算子は注意して使用する必要があります見つける。常に読みやすさを向上させるとは限りません。 – kaspermoerch