2015-07-27 7 views
1

мне нужна активность с расширяемой RecyclerView, как в этой картине:Как использовать библиотеку ExpandableRecyclerView с несколькими (дочерними) viewTypes?

enter image description here

Так я использую this third party library project. Эта часть работает.

проблема возникла, когда я сделал то, что я описываю в двух следующих пунктах:

Мое следующее требование, что я хочу, различную дочернюю-строку для различных родительских строк. Я воспроизвожу (если это правильное слово) this example to create multiple child-viewholders.

Описания Примера: Идея заключается в основном иметь различный Чайлд-viewholders (соответствующий каждый стиль ребенок строки), простирающиеся один общий childview держатель, а затем внутри наш ExpandableRecyclerAdapter где мы выдержавший ArrayList данных, отображаемых в родительских строках в конструкторе (parentItemList в SSCCE), мы объявляем константы, представляющие все дочерние строки-типы (TYPE_EDITTEXT и TYPE_SPINNER в SSCCE ниже); а затем внутри getItemViewType(int position) мы сравниваем элемент данных с parentItemList с использованием прошедшего int position в качестве индекса с каждой текстовой строкой в ​​родительских строках и в каждом случае присваиваем переменной int viewType константу ТИП и viewType. Затем передается этот int viewType к onCreateChildViewHolder и onBindChildViewHolder, поэтому мы выполняем другой блок switch в определениях каждого из этих методов, а затем в onCreateChildViewHolder мы возвращаем соответствующий ChildViewHolder (завышенный от соответствующего ресурса макета) (либо R.layout.custom_row_child_with_edittext, либо R.layout.custom_row_child_with_spinner в SSCCE); и в onBindChildViewHolder, обновите данные в соответствии с корпусом в блоке switch.

Проблема заключается в dollowing ClassCastException:

07-26 18:21:54.380: E/AndroidRuntime(276): FATAL EXCEPTION: main 
07-26 18:21:54.380: E/AndroidRuntime(276): java.lang.ClassCastException: tests.test.epmc_mobile.search_module.no_ui.expandable_recycler_view.EPMCChildViewHolder 
07-26 18:21:54.380: E/AndroidRuntime(276):  at com.bignerdranch.expandablerecyclerview.Adapter.ExpandableRecyclerAdapter.onBindViewHolder(ExpandableRecyclerAdapter.java:144) 

Дело в том, что ExpandableRecyclerAdapter.java является частью проекта библиотеки третьей стороной, и линия # 144 (и 142 и 143, которые я добавил), являются:

Log.i(TAG, "+++++++++++++++++++++++++THE TYPE OF THE RecyclerView.ViewHolder WHICH HAS BEEN PASSED AS AN ARGUMENT IS " 
                    + holder.getClass().getSimpleName() + "++++++++++++++++++++++++++++"); 
            PVH parentViewHolder = (PVH) holder; 

Прежде чем я попытался сделать то, что я делаю выше, он отлично работает.


MainActivity.java

public class MainActivity extends FragmentActivity { 
    private static final String TAG = MainActivity.class.getSimpleName(); 
    private RecyclerView recyclerView; 
    private static int [] imageIds = {R.drawable.ic_action_call, R.drawable.ic_action_copy, R.drawable.ic_action_discard}; 
    private static String [] titles = {"Dummy Text One", "Dummy Text Two", "Dummy Text Three"}; 


    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     Log.i(TAG, "onCreate of MainActivity called.");//check 
     super.onCreate(savedInstanceState); 

     setContentView(R.layout.activity_main); 
     recyclerView = (RecyclerView) findViewById(R.id.mainActivity_recyclerView); 

     MyExpandableRecyclerAdapter myExpandableRecyclerAdapter = new MyExpandableRecyclerAdapter(this, populateDataList(this)); 
     recyclerView.setAdapter(myExpandableRecyclerAdapter); 
     recyclerView.setLayoutManager(new LinearLayoutManager(this)); 
    } 

    private ArrayList<ParentObject> populateDataList(Context context) { 
     Log.i(TAG, "populateDataList of MainActivity called.");//check 
     ArrayList<ParentObject> parentObjectList = new ArrayList<>(); 
     for (int i=0; i<imageIds.length && i<titles.length; i++) { 
      MyCustomParentObject myCustomParentObject = new MyCustomParentObject(context); 
      myCustomParentObject.setImageId(imageIds[i]); 
      myCustomParentObject.setTitle(titles[i]); 
      parentObjectList.add(myCustomParentObject); 
     } 
     return parentObjectList; 
    } 
} 

MyExpandableRecyclerAdapter.java

public class MyExpandableRecyclerAdapter extends ExpandableRecyclerAdapter<ParentViewHolder, ChildViewHolder> { 
    private static final String TAG = MyExpandableRecyclerAdapter.class.getSimpleName(); 
    LayoutInflater layoutInflater; 
    Context context; 
    private List<ParentObject> parentItemList = new ArrayList<>(); 

    private static final int TYPE_EDITTEXT = 0; 
    private static final int TYPE_SPINNER = 1; 


    public MyExpandableRecyclerAdapter(Context context, List<ParentObject> parentObjectItemsList) { 
     super(context, parentObjectItemsList); 
     Log.i(TAG, "Constructor of MyExpandableRecyclerAdapter called.");//check 
     layoutInflater = LayoutInflater.from(context); 
     this.context = context; 
     parentItemList = parentObjectItemsList; 
    } 



    @Override 
    public int getItemViewType(int position) { 
     int viewType; 
     if (parentItemList.get(position).equals("EditText Entry")) { 
      viewType = TYPE_EDITTEXT; 
     } else { 
      viewType = TYPE_SPINNER; 
     } 
     return viewType; 
    } 




    @Override 
    public MyParentViewHolder onCreateParentViewHolder(ViewGroup container, int viewType) { 
     Log.i(TAG, "onCreateParentViewHolder of MyExpandableRecyclerAdapter called.");//check 
     Log.i(TAG, "IN onCreateParentViewHolder, THE TYPE OF AN ITEM IN THE parentItemList IS " + parentItemList.get(1)); 
     return new MyParentViewHolder(layoutInflater.inflate(R.layout.custom_row_parent, container, false)); 
    } 



    @Override 
    public MyChildViewHolder onCreateChildViewHolder(ViewGroup container, int viewType) { 
     Log.i(TAG, "onCreateChildViewHolder of MyExpandableRecyclerAdapter called.");//check 
     switch(viewType) { 
     case TYPE_EDITTEXT: 
      return new MyChildViewHolder(layoutInflater.inflate(R.layout.custom_row_child_with_edittext, container, false), context); 
     case TYPE_SPINNER: 
      return new MyChildViewHolder(layoutInflater.inflate(R.layout.custom_row_child_with_spinner, container, false), context); 
     default: 
      return new MyChildViewHolder(layoutInflater.inflate(R.layout.custom_row_child_with_edittext, container, false), context); 
     } 
    } 



    @Override 
    public void onBindParentViewHolder(ParentViewHolder parentViewHolder, int position, Object parentObject) { 
     Log.i(TAG, "onBindParentViewHolder of MyExpandableRecyclerAdapter called.");//check 
     MyParentViewHolder myParentViewHolder = (MyParentViewHolder) parentViewHolder; 
     MyCustomParentObject myCustomParentObject = (MyCustomParentObject) parentObject; 
     myParentViewHolder.textView.setText(myCustomParentObject.getTitle()); 
     myParentViewHolder.imageView.setImageResource(myCustomParentObject.getImageId()); 
    } 



    @Override 
    public void onBindChildViewHolder(ChildViewHolder childViewHolder, int position, Object childObject) { 
     Log.i(TAG, "onBindChildViewHolder of MyExpandableRecyclerAdapter called.");//check 

     switch(childViewHolder.getItemViewType()) { 
     case TYPE_EDITTEXT: 
      MyChildViewHolderWithEditText myChildViewHolderWithEditText = (MyChildViewHolderWithEditText) childViewHolder; 
      myChildViewHolderWithEditText.textView.setText("TextView " + (position+1) + " Title"); 
     case TYPE_SPINNER: 
      MyCustomChildObject myCustomChildObject = (MyCustomChildObject) childObject; 
      ArrayAdapter arrayAdapter = new ArrayAdapter(context, android.R.layout.simple_list_item_1, myCustomChildObject.getSpinnerItems()); 
      arrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); 
      MyChildViewHolderWithSpinner myChildViewHolderWithSpinner = (MyChildViewHolderWithSpinner) childViewHolder; 
      myChildViewHolderWithSpinner.spinner.setAdapter(arrayAdapter); 
     } 
    } 

} 

MyCustomParentObject.java

public class MyCustomParentObject implements ParentObject { 
    private static final String TAG = MyCustomParentObject.class.getSimpleName(); 
    //List to store all the children of the parent object in. 
    private List<Object> childObjectList; 
    private String [] bib; 

    MyCustomParentObject (Context context) { 
     super(); 
     bib = context.getResources().getStringArray(R.array.spinner_options); 
    } 


    @Override 
    public List<Object> getChildObjectList() { 
     Log.i(TAG, "getChildObjectList of MyCustomParentObject called.");//check 
     //"You can either return a newly created list of children here or attach them later" 
     return populateChildObjectList(); 
    } 

    @Override 
    public void setChildObjectList(List<Object> childObjectList) { 
     Log.i(TAG, "setChildObjectList of MyCustomParentObject called.");//check 
     childObjectList = childObjectList; 
    } 

    private List<Object> populateChildObjectList() { 
     Log.i(TAG, "populateChildObjectList of MyCustomParentObject called.");//check 
     childObjectList = new ArrayList<>(); 
     MyCustomChildObject myCustomChildObject = new MyCustomChildObject(); 
     myCustomChildObject.setSpinnerItems(bib); 
     Object myCustomChildObjectCasted = (Object) myCustomChildObject; 
     childObjectList.add(myCustomChildObjectCasted); 
     return childObjectList; 
    } 


    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 
    private int imageId; 
    private String title; 
    public int getImageId() { 
     Log.i(TAG, "getImageId of MyCustomParentObject called.");//check 
     return imageId; 
    } 
    public void setImageId(int imageId) { 
     Log.i(TAG, "setImageId of MyCustomParentObject called.");//check 
     this.imageId = imageId; 
    } 
    public String getTitle() { 
     Log.i(TAG, "getTitle of MyCustomParentObject called.");//check 
     return title; 
    } 
    public void setTitle(String title) { 
     Log.i(TAG, "setTitle of MyCustomParentObject called.");//check 
     this.title = title; 
    } 

} 

MyCustomChildObject.Java

public class MyCustomChildObject { 
    private static final String TAG = MyCustomParentObject.class.getSimpleName(); 

    private String [] spinnerItems; 

    public String [] getSpinnerItems() { 
     return spinnerItems; 
    } 

    public void setSpinnerItems(String [] spinnerItems) { 
     this.spinnerItems = spinnerItems; 
    } 

} 

MyCustomParentViewHolder.java

public class MyParentViewHolder extends ParentViewHolder { 
    private static final String TAG = MyParentViewHolder.class.getSimpleName(); 
    TextView textView; 
    ImageView imageView; 

    public MyParentViewHolder(View itemView) { 
     super(itemView); 
     Log.i(TAG, "Constructor of MyParentViewHolder called.");//check 
     textView = (TextView) itemView.findViewById(R.id.parentCustomRow_textView); 
     imageView = (ImageView) itemView.findViewById(R.id.parentCustomRow_imageView); 
    } 

} 

MyCustomChildViewHolder.java

public class MyChildViewHolder extends ChildViewHolder { 
    private static final String TAG = MyChildViewHolder.class.getSimpleName(); 

    public MyChildViewHolder(View itemView, final Context context) { 
     super(itemView); 
     Log.i(TAG, "Constructor of MyChildViewHolder called.");// check 
    } 
} 

MyCustomChildViewHolderWithEditText.java

public class MyChildViewHolderWithEditText extends MyChildViewHolder { 
    EditText editText; 
    TextView textView; 

    public MyChildViewHolderWithEditText(View itemView, Context context) { 
     super(itemView, context); 

     textView = (TextView) itemView.findViewById(R.id.childViewHolderWithEditText_TextView); 
     editText = (EditText) itemView.findViewById(R.id.childViewHolderWithEditText_editText); 
    } 

} 

MyCustomChildViewHolderWithSpinner.java

public class MyChildViewHolderWithSpinner extends MyChildViewHolder { 
    Spinner spinner; 

    public MyChildViewHolderWithSpinner(View itemView, Context context) { 
     super(itemView, context); 

     spinner = (Spinner) itemView.findViewById(R.id.childViewHolderWithSpinner_spinner); 
     //ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(context, R.array.childViewSpinnerFields, android.R.layout.simple_spinner_item); 
     //adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); 
     ///spinner.setAdapter(adapter); 
     spinner.setOnItemSelectedListener(new OnItemSelectedListener() { 
      @Override 
      public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {} 
      @Override 
      public void onNothingSelected(AdapterView<?> parent) {} 
     }); 
    } 

} 

ответ

0

Сравнивая Line#13 of this stack-trace of the error free program и this one of the program which results in the exception, и, глядя на определение onCreateViewHolder(ViewGroup viewGroup, int viewType) метода на Line#117 of this ExpandableRecyclerAdapter.java class, из которого я делаю вывод, что onCreateViewHolder это передается неправильный viewType параметр.

Но я до сих пор не удалось выяснить, почему!


Я думаю Я понял.

На самом деле трюк TYPE_SOMETHING констант, которые я использую в MyExpandableRecyclerAdapter тот же один они использовали в ExpandableRecyclerAdapter, то есть в моем MyExpandableRecyclerAdapter, 0 это значение TYPE_EDITTEXT и 1 это значение TYPE_SPINNER; тогда как в их ExpandableRecyclerAdapter, который распространяется на мои MyExpandableRecyclerAdapter, 0 - это значение TYPE_PARENT и 1 - это значение TYPE_CHILD.

Если Android рамки проходит один и тот же параметр viewTypeonCreateViewHolder, который возвращается из getItemViewType(int position), он будет проходить 1, если он был TYPE_SPINNER в моей MyExpandableRecyclerAdapter, но их ExpandableRecyclerAdapter поймет это как TYPE_CHILD, и, таким образом, называют onCreateChildViewHolder.

Так что я думаю, что все, что я пытаюсь добиться не может быть сделано. = (

 Смежные вопросы

  • Нет связанных вопросов^_^