我的RecyclerView出了问题。让我详细解释一下这个问题。我尝试使用四种不同的子视图实现RecylerView。我按照“Double Wong”的方法进行了操作。所以基本上我从一个主ViewHolder扩展了四个ViewHolder,在onCreateViewHolder()我选择应该初始化哪一个。为此,我重写了getItemViewType()方法。它工作正常,只要所有子类型都是类型0.(类型0表示该项不在数据库中,类型1 - 3表示数据库中有不同的标志)。
有时我会得到 ArrayIndexOutOfBoundsException ,有时它是 ClassCastException ,我无法找出模式。 这是我的代码,我做了一些削减,使其更短。
public class SucheSerienFragment extends Fragment {
...
public List<Pair<SerieInfo, Integer>> listTvShows;
private SerieCardViewSucheAdapter serieCardViewSucheAdapter;
...
private class LoadSerie extends AsyncTask<String, Void, String> {
@Override
protected String doInBackground(String... search) {
...
int type;
if (db.checkSerie(serieInfo)) {
serieInfo = db.getSerieByName(serieInfo.getName());
if (serieInfo.getArchivFlag() == 0){
type = SucheMainViewHolder.TYPE_AT_WATCHLIST;
} else if (serieInfo.getArchivFlag() == 1) {
type = SucheMainViewHolder.TYPE_PAUSIERT;
} else if (serieInfo.getArchivFlag() == 2) {
type = SucheMainViewHolder.TYPE_ABGESCHLOSSEN;
} else {
type = SucheMainViewHolder.TYPE_SEARCH;
} } else {
type = SucheMainViewHolder.TYPE_SEARCH;
}
final SerieInfo finalSerieInfo = serieInfo;
final int finalType = type;
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
listTvShows.add(new Pair(finalSerieInfo, finalType));
serieCardViewSucheAdapter.notifyItemInserted(serieCardViewSucheAdapter.getItemCount() - 1);
}
});
}
}
} catch (TVDBOutboundConnectionException e1) {
Log.e(TAG, "Es konnte keine Verbindung aufgebaut werden");
Log.e(TAG, "Error" + e1);
e1.printStackTrace();
}
return "Executed";
}
@Override
protected void onPostExecute(String string) {
Log.d(TAG, "onPostExecute");
progressBarLoadSerie.setVisibility(View.GONE);
if (listTvShows.isEmpty()) {
Toast.makeText(getActivity(), "Keine Serie gefunden", Toast.LENGTH_SHORT).show();
nothingFoundFrameLayout.setVisibility(View.VISIBLE);
}
}
@Override
protected void onPreExecute() {
Log.d(TAG, "onPreExecute");
progressBarLoadSerie.setVisibility(View.VISIBLE);
}
@Override
protected void onProgressUpdate(Void... values) {
Log.d(TAG, "onPrograessUpdate");
}
}
public class SucheMainViewHolder extends RecyclerView.ViewHolder{
public static final int TYPE_SEARCH = 0;
public static final int TYPE_AT_WATCHLIST = 1;
public static final int TYPE_PAUSIERT= 2;
public static final int TYPE_ABGESCHLOSSEN= 3;
public SucheMainViewHolder(View itemView) {
super ( itemView );
}
}
public class SucheAbgeschlossenHolder extends SucheMainViewHolder {
public TextView tvSerienName;
public TextView tvCurrentEpisode;
public ImageView tvSerienImage;
public RelativeLayout linearBackground;
public ImageView imgViewSerie;
public ImageButton playButton;
public ImageButton deleteButton;
public ImageButton abschliesButton;
public SucheAbgeschlossenHolder(View v) {
super(v);
tvSerienName = (TextView) v.findViewById(R.id.tvSerienName);
tvCurrentEpisode = (TextView) v.findViewById(R.id.tvSerienOverview);
tvSerienImage = (ImageView) v.findViewById(R.id.imgViewSerie);
linearBackground = (RelativeLayout) v.findViewById(R.id.rla);
playButton = (ImageButton) v.findViewById(R.id.playImageButton);
deleteButton = (ImageButton) v.findViewById(R.id.deleteImageButton);
abschliesButton = (ImageButton) v.findViewById(R.id.abschliesenImageButton);
imgViewSerie = (ImageView) v.findViewById(R.id.imgViewSerie);
}
}
SuchePausiertHolder extends SucheMainViewHolder {
public TextView tvSerienName;
public TextView tvCurrentEpisode;
public ImageView tvSerienImage;
public RelativeLayout linearBackground;
public ImageView imgViewSerie;
public ImageButton playButton;
public ImageButton deleteButton;
public ImageButton abschliesButton;
public SuchePausiertHolder(View v) {
super(v);
tvSerienName = (TextView) v.findViewById(R.id.tvSerienName);
tvCurrentEpisode = (TextView) v.findViewById(R.id.tvSerienOverview);
tvSerienImage = (ImageView) v.findViewById(R.id.imgViewSerie);
linearBackground = (RelativeLayout) v.findViewById(R.id.rla);
playButton = (ImageButton) v.findViewById(R.id.playImageButton);
deleteButton = (ImageButton) v.findViewById(R.id.deleteImageButton);
abschliesButton = (ImageButton) v.findViewById(R.id.abschliesenImageButton);
imgViewSerie = (ImageView) v.findViewById(R.id.imgViewSerie);
}
}
public class SucheSerieViewHolder extends SucheMainViewHolder{
public TextView tvSerienName;
public TextView tvSerienOverview;
public TextView tvRating;
public ImageView tvSerienImage;
public ImageButton btnAddSerie;
public LinearLayout linearSerienSucheBackground;
public SucheSerieViewHolder(View v) {
super(v);
tvSerienName = (TextView) v.findViewById(R.id.tvSerienName);
tvSerienOverview = (TextView) v.findViewById(R.id.tvSerienOverview);
tvSerienImage = (ImageView) v.findViewById(R.id.imgViewSerie);
btnAddSerie = (ImageButton) v.findViewById(R.id.btnAddSerie);
linearSerienSucheBackground = (LinearLayout) v.findViewById(R.id.linearSerienSuche);
tvRating = (TextView) v.findViewById(R.id.tvRating);
}
}
public class SucheWatchedHolder extends SucheMainViewHolder {
public TextView tvSerienName;
public TextView tvCurrentEpisode;
public ImageView tvSerienImage;
public View btnNext;
public RelativeLayout linearBackground;
public ImageView imgViewSerie;
public SucheWatchedHolder(View v) {
super(v);
tvSerienName = (TextView) v.findViewById(R.id.tvSerienName);
tvCurrentEpisode = (TextView) v.findViewById(R.id.tvSerienOverview);
tvSerienImage = (ImageView) v.findViewById(R.id.imgViewSerie);
btnNext = (View) v.findViewById(R.id.btnNext);
linearBackground = (RelativeLayout) v.findViewById(R.id.rla);
imgViewSerie = (ImageView) v.findViewById(R.id.imgViewSerie);
} }
@Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) >{
LayoutInflater mInflater = LayoutInflater.from ( >viewGroup.getContext () );
int type = getItemViewType(viewType);
switch (type) {
case SucheMainViewHolder.TYPE_SEARCH:
ViewGroup vSuche = ( ViewGroup ) mInflater.inflate ( >R.layout.cardview_serie_suche, viewGroup, false );
SucheSerieViewHolder vhSuche = new SucheSerieViewHolder ( >vSuche );
return vhSuche;
default:
vSuche = ( ViewGroup ) mInflater.inflate ( >R.layout.cardview_serie_suche, viewGroup, false );
vhSuche = new SucheSerieViewHolder ( vSuche );
return vhSuche;
case SucheMainViewHolder.TYPE_AT_WATCHLIST:
ViewGroup vSucheWatched = ( ViewGroup ) mInflater.inflate ( >R.layout.cardview_serie, viewGroup, false );
SucheWatchedHolder vhSucheWatched = new SucheWatchedHolder >( vSucheWatched );
return vhSucheWatched;
case SucheMainViewHolder.TYPE_PAUSIERT:
ViewGroup vSuchePausiert = ( ViewGroup ) mInflater.inflate >( R.layout.cardview_serie_pausiert, viewGroup, false );
SuchePausiertHolder vhSuchePausiert = new >SuchePausiertHolder ( vSuchePausiert );
return vhSuchePausiert;
case SucheMainViewHolder.TYPE_ABGESCHLOSSEN:
ViewGroup vSucheAbgeschlossen = ( ViewGroup ) >mInflater.inflate ( R.layout.cardview_serie_abgeschlossen, viewGroup, false );
SucheAbgeschlossenHolder vhSucheAbgeschlossen= new >SucheAbgeschlossenHolder( vSucheAbgeschlossen );
return vhSucheAbgeschlossen;
}
}
...
@Override
public void onBindViewHolder(ViewHolder viewHolder, final int position) {
final SerieInfo serieInfo = listSerieInfo.get(position).first;
if (viewHolder == null) {
return;
}
switch (viewHolder.getItemViewType()) {
default:
...
return;
case SucheMainViewHolder.TYPE_SEARCH:
...
return;
case SucheMainViewHolder.TYPE_AT_WATCHLIST:
...
return;
case SucheMainViewHolder.TYPE_PAUSIERT:
...
return;
case SucheMainViewHolder.TYPE_ABGESCHLOSSEN:
...
return;
}
}
...
@Override
public int getItemViewType(int position) {
return listSerieInfo.get(position).second;
}
06-01 00:49:17.327 23289-23289/com.turnonandroid.seriencounter E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.turnonandroid.seriencounter, PID: 23289
java.lang.IndexOutOfBoundsException: Invalid index 1, size is 1
at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:255)
at java.util.ArrayList.get(ArrayList.java:308)
at com.turnonandroid.serienmanager.Adapter.SerieCardViewSucheAdapter.getItemViewType(SerieCardViewSucheAdapter.java:390)
at com.turnonandroid.serienmanager.Adapter.SerieCardViewSucheAdapter.onCreateViewHolder(SerieCardViewSucheAdapter.java:359)
at android.support.v7.widget.RecyclerView$Adapter.createViewHolder(RecyclerView.java:5062)
at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:4368)
at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:4278)
at android.support.v7.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:1947)
at android.support.v7.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1359)
at android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1322)
at android.support.v7.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:556)
at android.support.v7.widget.RecyclerView.dispatchLayout(RecyclerView.java:2673)
at android.support.v7.widget.RecyclerView.onLayout(RecyclerView.java:2971)
at android.view.View.layout(View.java:16552)
at android.view.ViewGroup.layout(ViewGroup.java:5355)
at android.widget.RelativeLayout.onLayout(RelativeLayout.java:1070)
at android.view.View.layout(View.java:16552)
at android.view.ViewGroup.layout(ViewGroup.java:5355)
at android.widget.RelativeLayout.onLayout(RelativeLayout.java:1070)
at android.view.View.layout(View.java:16552)
at android.view.ViewGroup.layout(ViewGroup.java:5355)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:335)
at android.widget.FrameLayout.onLayout(FrameLayout.java:272)
at android.view.View.layout(View.java:16552)
at android.view.ViewGroup.layout(ViewGroup.java:5355)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:335)
at android.widget.FrameLayout.onLayout(FrameLayout.java:272)
at android.view.View.layout(View.java:16552)
at android.view.ViewGroup.layout(ViewGroup.java:5355)
at android.widget.RelativeLayout.onLayout(RelativeLayout.java:1070)
at android.view.View.layout(View.java:16552)
at android.view.ViewGroup.layout(ViewGroup.java:5355)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:335)
at android.widget.FrameLayout.onLayout(FrameLayout.java:272)
at android.view.View.layout(View.java:16552)
at android.view.ViewGroup.layout(ViewGroup.java:5355)
at android.support.v7.internal.widget.ActionBarOverlayLayout.onLayout(ActionBarOverlayLayout.java:493)
at android.view.View.layout(View.java:16552)
at android.view.ViewGroup.layout(ViewGroup.java:5355)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:335)
at android.widget.FrameLayout.onLayout(FrameLayout.java:272)
at android.view.View.layout(View.java:16552)
at android.view.ViewGroup.layout(ViewGroup.java:5355)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1707)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1561)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1470)
at android.view.View.layout(View.java:16552)
at android.view.ViewGroup.layout(ViewGroup.java:5355)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:335)
at android.widget.FrameLayout.onLayout(FrameLayout.java:272)
at android.view.View.layout(View.java:16552)
at android.view.ViewGroup.layout(ViewGroup.java:5355)
at android.support.v4.widget.DrawerLayout.onLayout(DrawerLayout.java:907)
at android.view.View.layout(View.java:16552)
at android.view.ViewGroup.layout(ViewGroup.java:5355)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:335)
at android.widget.FrameLayout.onLayout(FrameLayout.java:272)
at android.view.View.layout(View.java:16552)
at android.view.ViewGroup.layout(ViewGroup.java:5355)
at android.view.ViewRootImpl.performLayout(ViewRoo
06-01 00:56:09.436 27453-27453/com.turnonandroid.seriencounter E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.turnonandroid.seriencounter, PID: 27453
java.lang.ClassCastException: com.turnonandroid.serienmanager.SucheSerieViewHolder cannot be cast to com.turnonandroid.serienmanager.SucheWatchedHolder
at com.turnonandroid.serienmanager.Adapter.SerieCardViewSucheAdapter.onBindViewHolder(SerieCardViewSucheAdapter.java:167)
at android.support.v7.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:5084)
at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:4385)
at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:4278)
at android.support.v7.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:1947)
at android.support.v7.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1359)
at android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1322)
at android.support.v7.widget.LinearLayoutManager.scrollBy(LinearLayoutManager.java:1150)
at android.support.v7.widget.LinearLayoutManager.scrollVerticallyBy(LinearLayoutManager.java:1007)
at android.support.v7.widget.RecyclerView.scrollByInternal(RecyclerView.java:1355)
at android.support.v7.widget.RecyclerView.onTouchEvent(RecyclerView.java:2209)
at android.view.View.dispatchTouchEvent(View.java:9244)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2536)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2229)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2542)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2243)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2542)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2243)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2542)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2243)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2542)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2243)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2542)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2243)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2542)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2243)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2542)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2243)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2542)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2243)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2542)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2243)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2542)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2243)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2542)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2243)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2542)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2243)
at com.android.internal.policy.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:2392)
at com.android.internal.policy.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1730)
at android.app.Activity.dispatchTouchEvent(Activity.java:2710)
at android.support.v7.internal.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:59)
at com.android.internal.policy.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:2353)
at android.view.View.dispatchPointerEvent(View.java:9439)
at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:4181)
at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:4047)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3593)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3646)
感谢您阅读并思考我的问题。
答案 0 :(得分:0)
好的,关于IndexOutOfBoundsException
,您应该检查适配器中的getItemCount()
。如果您在listSerieInfo.get(position)
中呼叫getViewType()
,则该方法应如下所示:
return listSerieInfo != null ? listSerieInfo.size() : 0;
关于ClassCastException
,您必须将default
中的onBindViewHolder
选项移到底部。应该永远在那里。
答案 1 :(得分:0)
所以我通过不同的方式修复了问题。因此,不是添加不同种类的ViewHolders,而是只有一种。其中包括各种ViewHolders(在布局中),但可见性为GONE。在onBindViewHolder()方法中,我检查应该显示哪种类型,并将可见性设置为VISIBLE。这可能不是最好的方式(可能是最糟糕的),但对我来说它的工作。