convertView.getTag (); Создает ошибку Cast

Я использую фрагмент для создания ListView заполненного CheckBox es. Я попытался изо всех сил найти решение, основанное на других вопросах, но я не могу его исправить. Когда я запускаю скрипт без использования:

 convertView.getTag(); 

Мое приложение работает нормально, но позиции элемента s в списке не сохраняются. Элементы представления перемещаются. Однако, когда я использую этот метод, я получаю сообщение об ошибке. Лог-кота:

 01-02 23:54:20.662: E/InputEventReceiver(1209): Exception dispatching input event. 01-02 23:54:20.672: D/AndroidRuntime(1209): Shutting down VM 01-02 23:54:20.672: W/dalvikvm(1209): threadid=1: thread exiting with uncaught exception (group=0x40a13300) 01-02 23:54:20.782: E/AndroidRuntime(1209): FATAL EXCEPTION: main 01-02 23:54:20.782: E/AndroidRuntime(1209): java.lang.ClassCastException: com.MrBabilin.youdeserveadrink.Items cannot be cast to com.MrBabilin.youdeserveadrink.AlcoholList$MyCustomAdapter$ViewHolder 01-02 23:54:20.782: E/AndroidRuntime(1209): at com.MrBabilin.youdeserveadrink.AlcoholList$MyCustomAdapter.getView(AlcoholList.java:169) 01-02 23:54:20.782: E/AndroidRuntime(1209): at android.widget.AbsListView.obtainView(AbsListView.java:2255) 01-02 23:54:20.782: E/AndroidRuntime(1209): at android.widget.ListView.makeAndAddView(ListView.java:1769) 01-02 23:54:20.782: E/AndroidRuntime(1209): at android.widget.ListView.fillDown(ListView.java:672) 01-02 23:54:20.782: E/AndroidRuntime(1209): at android.widget.ListView.fillGap(ListView.java:636) 01-02 23:54:20.782: E/AndroidRuntime(1209): at android.widget.AbsListView.trackMotionScroll(AbsListView.java:5040) 01-02 23:54:20.782: E/AndroidRuntime(1209): at 

Эта деятельность состоит из 3 классов. Основной: IngredientsActivity

 public class IngredientsActivity extends FragmentActivity implements ActionBar.TabListener { private static final String STATE_SELECTED_NAVIGATION_ITEM = "selected_navigation_item"; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.check_list); getActionBar().setTitle("Search"); getActionBar().setIcon(R.drawable.search_1); // Set up the action bar. final ActionBar actionBar = getActionBar(); actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); // For each of the sections in the app, add a tab to the action bar. actionBar.addTab(actionBar.newTab().setText("Alcahol").setTabListener(this)); actionBar.addTab(actionBar.newTab().setText("Juice").setTabListener(this)); actionBar.addTab(actionBar.newTab().setText("Other").setTabListener(this)); } @Override public void onRestoreInstanceState(Bundle savedInstanceState) { if (savedInstanceState.containsKey(STATE_SELECTED_NAVIGATION_ITEM)) { getActionBar().setSelectedNavigationItem(savedInstanceState.getInt(STATE_SELECTED_NAVIGATION_ITEM)); } } @Override public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putInt(STATE_SELECTED_NAVIGATION_ITEM, getActionBar().getSelectedNavigationIndex()); } @Override public boolean onCreateOptionsMenu(Menu menu) { return true; } @Override public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) { } @Override public void onTabSelected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) { if (tab.getPosition() == 0) { AlcoholList simpleListFragment = new AlcoholList(); getSupportFragmentManager().beginTransaction().replace(R.id.containert, simpleListFragment).commit(); } else if (tab.getPosition() == 1) { JuiceList androidlidt = new JuiceList(); getSupportFragmentManager().beginTransaction().replace(R.id.containert, androidlidt).commit(); } else { OtherList androidversionlist = new OtherList(); getSupportFragmentManager().beginTransaction().replace(R.id.containert, androidversionlist).commit(); } } @Override public void onTabReselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) { } public static class DummySectionFragment extends Fragment { public DummySectionFragment() { } public static final String ARG_SECTION_NUMBER = "section_number"; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { TextView textView = new TextView(getActivity()); textView.setGravity(Gravity.CENTER); Bundle args = getArguments(); textView.setText(Integer.toString(args.getInt(ARG_SECTION_NUMBER))); return textView; } } } 

То фрагмент: AlcoholList

 import android.content.Context; import android.content.SharedPreferences; import android.os.Bundle; import android.preference.PreferenceManager; import android.support.v4.app.ListFragment; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ArrayAdapter; import android.widget.CheckBox; import android.widget.ListView; public class AlcoholList extends ListFragment{ MyCustomAdapter dataAdapter = null; private Set<String> recipesList = new HashSet<String>(); private ArrayList<Items> stateList = new ArrayList<Items>(); public AlcoholList() { Items _states1 = new Items ("Gin",false); stateList.add(_states1); Items _states2 = new Items ("Ginger Liqueur",false); stateList.add(_states2); Items _states3 = new Items ("Citrus Vodka",false); stateList.add(_states3); Items _states4 = new Items ("Champagne",false); stateList.add(_states4); Items _states5 = new Items ("Coconut Rum",false); stateList.add(_states5); Items _states6 = new Items ("Pear Vodka",false); stateList.add(_states6); Items _states7 = new Items ("Rum",false); stateList.add(_states7); Items _states8 = new Items ("Tequila",false); stateList.add(_states8); Items _states9 = new Items ("Triple Sec",false); stateList.add(_states9); Items _states10 = new Items ("Kahlua",false); stateList.add(_states10); Items _states11 = new Items ("Vanilla Vodka",false); stateList.add(_states11); Items _states12 = new Items ("Sake",false); stateList.add(_states12); Items _states13 = new Items ("Bourbon",false); stateList.add(_states13); Items _states14 = new Items ("Vodka",false); stateList.add(_states14); Items _states15 = new Items ("Beer",false); stateList.add(_states15); }; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); dataAdapter = new MyCustomAdapter(this.getActivity(),R.layout.da_item, stateList); setListAdapter(dataAdapter); SharedPreferences sharedPreferences = PreferenceManager .getDefaultSharedPreferences(getActivity()); recipesList = sharedPreferences.getStringSet("string", recipesList); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.list_fragment, container, false); } @Override public void onListItemClick(ListView list, View v, int position, long id) { } private class MyCustomAdapter extends ArrayAdapter<Items> { private ArrayList<Items> stateList; public MyCustomAdapter(Context context, int textViewResourceId, ArrayList<Items> stateList) { super(context, textViewResourceId, stateList); this.stateList = new ArrayList<Items>(); this.stateList.addAll(stateList); } private class ViewHolder { CheckBox name; } @Override public View getView (int position, View convertView, ViewGroup parent) { ViewHolder holder = null; Log.v("ConvertView", String.valueOf(position)); if (convertView == null) { LayoutInflater vi = (LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE); convertView = vi.inflate(R.layout.da_item, null); holder = new ViewHolder(); convertView.setTag(holder); holder.name = (CheckBox) convertView.findViewById(R.id.ingredientbox); holder.name.setOnClickListener( new View.OnClickListener() { public void onClick(View v) { CheckBox cb = (CheckBox) v; Items _state = (Items) cb.getTag(); _state.setSelected(cb.isChecked()); } }); } else { holder = (ViewHolder) convertView.getTag(); // THIS IS THE PROBLEM } Items state = stateList.get(position); holder.name.setText(state.getName()); holder.name.setChecked(state.isSelected()); holder.name.setTag(state); return convertView; } } } 

То класс Array: Items

 public class Items { String name ; boolean selected; public Items(String name, boolean selected){ super(); this.name=name; this.selected=selected; } public String getName() { return name; } public void setName(String name) { this.name = name; } public boolean isSelected() { return selected; } public void setSelected(boolean selected) { this.selected = selected; } } 

Я не знаю, полезно ли это, но эта проблема не возникала до того, как я попытался реализовать представления фрагментов. Код, который работал, был:

  public class IngredientsActivity extends Activity { MyCustomAdapter dataAdapter = null; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.check_list); //Generate list View from ArrayList displayListView(); } private void displayListView() { //Array list of countries ArrayList<Items> stateList = new ArrayList<Items>(); Items _states2 = new Items ("420" ,false); stateList.add(_states2); Items _states3 = new Items ("Amanda Bynes" ,false); stateList.add(_states3); Items _states4 = new Items ("Angelina Jolie" ,false); stateList.add(_states4); Items _states5 = new Items ("Anne Hathaway" ,false); stateList.add(_states5); Items _states6 = new Items ("Bachelorette Contestants" ,false); stateList.add(_states6); Items _states7 = new Items ("Beauty and the Beast" ,false); stateList.add(_states7); Items _states8 = new Items ("Beyonce" ,false); stateList.add(_states8); Items _states9 = new Items ("Big Boi" ,false); stateList.add(_states9); Items _states10 = new Items ("Charlie Sheen" ,false); stateList.add(_states10); } //create an ArrayAdaptar from the String Array dataAdapter = new MyCustomAdapter(this,R.layout.da_item, stateList); ListView listViews = (ListView) findViewById(R.id.ingList2); // Assign adapter to ListView listViews.setAdapter(dataAdapter); } private class MyCustomAdapter extends ArrayAdapter<Items> { private ArrayList<Items> stateList; public MyCustomAdapter(Context context, int textViewResourceId, ArrayList<Items> stateList) { super(context, textViewResourceId, stateList); this.stateList = new ArrayList<Items>(); this.stateList.addAll(stateList); } private class ViewHolder { CheckBox name; } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder = null; Log.v("ConvertView", String.valueOf(position)); if (convertView == null) { LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE); convertView = vi.inflate(R.layout.da_item, null); holder = new ViewHolder(); holder.name = (CheckBox) convertView.findViewById(R.id.ingredientbox); convertView.setTag(holder); holder.name.setOnClickListener( new View.OnClickListener() { public void onClick(View v) { CheckBox cb = (CheckBox) v; Items _state = (Items) cb.getTag(); _state.setSelected(cb.isChecked()); } }); } else { holder = (ViewHolder) convertView.getTag(); } Items state = stateList.get(position); holder.name.setText(state.getName()); holder.name.setChecked(state.isSelected()); holder.name.setTag(state); return convertView; } } } 

Вопрос: как я могу предотвратить сбой приложения после вызова convertView.getTag ()

Файл R.layout.da_item содержит только файл R.id.ingredientbox поэтому ваши covertView и holder.name относятся к одному и тому же объекту.

Теперь, когда вы звоните

 convertView.setTag(holder); 

Держатель установлен в тег объекта convertView, а затем вы вызываете

 holder.name.setTag(state); 

Который переопределяет тег, поскольку оба объекта одинаковы.

Попробуйте удалить второй звонок и проверить.

EDIT Измените класс держателя на:

  private class ViewHolder { Items state; CheckBox name; } 

Не записывайте имя holder.name.setTag(state); , Вместо этого выполните следующие действия:

 holder.state=state; 

Теперь, когда вы хотите, чтобы предметы просто говорили:

 Items _state = ((ViewHolder) cb.getTag()).state;