2016-10-11 10 views
1

私はチェックボックスを含む複数選択リストビューを実装しようとしていますが、カスタムアダプタークラスを定義しました。"変数は内部クラスからアクセスされ、最終的に宣言する必要があります"エラーカスタムアダプターでエラー

package com.ameer.easycooking; 

import android.content.Context; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.ArrayAdapter; 
import android.widget.CheckBox; 
import android.widget.CompoundButton; 
import android.widget.TextView; 

import java.util.ArrayList; 
import java.util.List; 

public class CategoryAdapter extends ArrayAdapter<String> { 

    private List<String> categoryList; 
    private Context context; 
    private List<String> selected = new ArrayList<>(); 

    public CategoryAdapter(List<String> categoryList, Context context) { 
     super(context, R.layout.category_list_item, categoryList); 
     this.categoryList = categoryList; 
     this.context = context; 
    } 

    public static class CategoryHolder { 
     private CheckBox checkBox; 
     private TextView categoryName; 

     public CategoryHolder(CheckBox checkBox, TextView categoryName) { 
      this.checkBox = checkBox; 
      this.categoryName = categoryName; 
     } 

     public CheckBox getCheckBox() { 
      return checkBox; 
     } 

     public void setCheckBox(CheckBox checkBox) { 
      this.checkBox = checkBox; 
     } 

     public TextView getCategoryName() { 
      return categoryName; 
     } 

     public void setCategoryName(TextView categoryName) { 
      this.categoryName = categoryName; 
     } 
    } 

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

     CategoryHolder holder = new CategoryHolder((CheckBox) v.findViewById(R.id.checkBox), (TextView) v.findViewById(R.id.name)); 

     if (convertView == null) { 
      LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
      v = inflater.inflate(R.layout.category_list_item, null); 

      holder.getCheckBox().setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { 
       @Override 
       public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 
         if (isChecked) { 
          selected.add(holder.getCheckBox().getText().toString()); 
         }else{ 
          selected.remove(holder.getCheckBox().getText().toString()); 
         } 
       } 
      }); 
      v.setTag(holder); 
     } else { 
      holder = (CategoryHolder) v.getTag(); 
     } 

     String category = categoryList.get(position); 
     holder.categoryName.setText(category); 
     holder.checkBox.setTag(category); 

     return v; 
    } 

    public List<String> getSelected() { 
     return selected; 
    } 
} 

私はselected一覧でチェック項目を格納し、その後、クラスの終わりにゲッターでそれらを取得したいと思いますが、「ホルダー」は、最終的に宣言する必要があることを私に言って、私がしなければです最終的に宣言します。holder = (CategoryHolder) v.getTag();を使用して値を割り当てることはできません。したがって、1つの問題を解決することは別の問題を作成することです。 :(あなたがOnCheckedChangeListenerのパラメータから必要な情報を得ることができますどのように私は両方解決することができ、事前に

おかげ

+0

あなたの所有者は内部クラスです。グローバル変数として宣言し、必要なときに初期化する必要があります。 – Pztar

答えて

1

:?。。buttonViewがチェック要素であるので、あなたがする必要があるすべては以下の通りです:

@Override 
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 
     CheckBox checkbox; 
     if (buttonView instanceof CheckBox) 
     { 
      checkbox = (CheckBox)buttonView; 
     } 
     else return; 

     if (isChecked) { 
      selected.add(checkbox.getText().toString()); 
     }else{ 
      selected.remove(checkbox.getText().toString()); 
     } 
} 
+0

あなたが提案したように自分のコードを変更しましたが、今は 'CategoryHolder holder = new CategoryHolder(CheckBox)v.findViewById(R.id.checkBox)、(TextView)v.findViewById R.id.name)); 'それはなぜですか? – user3501779

+0

@ user3501779 - 私の答えを聞いてうれしいです。一歩進んでいます。少なくとも今は実行中です。何とかしています.-) convertViewは時にはヌルになることがあるので、NPEを取得しています。ですから 'v'に' null'を代入すれば 'v.findViewById()'はNPEを引き起こします。 – 0X0nosugar

+0

この情報に続いて、私は上記の行を 'if(convertView == null)'の条件に移し、現在動作しており、ListViewに項目を表示しています。しかし、私は常に 'selected'で空文字列を取得しています。 'getText()'メソッドはCheckBoxテキストまたはTextViewテキストを返しますか?私はCheckBoxテキストに何も割り当てず、対応するTextViewに割り当てるので、問題がどこにあるのだろうと思っています。 – user3501779

0

あなたが内部クラスへのオブジェクトを使用している場合は、それfinalを宣言する必要があり ここで説明されていますWhy Java inner classes require "final" outer instance variables?

だから、あなたはその変数フィンを作ることができますal:

final CategoryHolder holder = convertView != null ? 
    (CategoryHolder) v.getTag() : 
    new CategoryHolder((CheckBox) v.findViewById(R.id.checkBox), (TextView) v.findViewById(R.id.name)); 
関連する問題