无尽的recyclerview,多种视图类型,OnscrollListener 后崩溃
Posted
技术标签:
【中文标题】无尽的recyclerview,多种视图类型,OnscrollListener 后崩溃【英文标题】:Endless recyclerview, multiple view types, crashing after OnscrollListener 【发布时间】:2019-09-21 04:03:36 【问题描述】:我试图制作一个在滚动时生成项目的 RecyclerView。 method >onScrollListener 生成具有两种不同视图类型的项目: ViewType == >FALSE 创建一个布局,右侧有 CardView 而 ViewType == TRUE a >布局,左侧有 CardView。
我试图实现的是,使用循环生成具有奇数项的 > 项目的无限列表(每次生成项目时都会增加一个 int 变量)定位在布局 CardView 右侧,否则位于布局>左侧有 CardView。
示例: [example_screenshot][1]
编辑:忘记在适配器构造函数中添加一些代码! 添加日志
适配器
public class Adapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
List<Tipo> lista;
private int visibleThreshold = 14;
private int lastVisibleItem, totalItemCount;
private OnLoadMoreListener onLoadMoreListener;
private boolean loading;
public Adapter(List<Tipo> lista,RecyclerView recyclerView)
this.lista = lista;
//Forgot to add this part on the original question!
if(recyclerView.getLayoutManager() instanceof LinearLayoutManager)
final LinearLayoutManager linearLayoutManager =
(LinearLayoutManager)recyclerView.getLayoutManager();
recyclerView.addOnScrollListener(
new RecyclerView.OnScrollListener()
@Override
public void onScrolled(RecyclerView recyclerView, int dx,int dy)
super.onScrolled(recyclerView, dx, dy);
totalItemCount = linearLayoutManager.getItemCount();
lastVisibleItem =
linearLayoutManager.findLastVisibleItemPosition();
if(!loading && totalItemCount <= (lastVisibleItem +
visibleThreshold))
if(onLoadMoreListener != null)
onLoadMoreListener.onLoadMore();
loading = true;
);
//New part ended
public void setLoaded()
loading = false;
public void setOnLoadMoreListener(OnLoadMoreListener onLoadMoreListener)
this.onLoadMoreListener = onLoadMoreListener;
public interface OnLoadMoreListener
void onLoadMore();
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType)
View v;
switch(viewType)
case 0:
v = LayoutInflater.from(parent.getContext()).inflate(R.layout.elemento_destro,parent,false);
return new ViewHolder1(v);
case 1:
v = LayoutInflater.from(parent.getContext()).inflate(R.layout.elemento_sinistro,parent,false);
return new ViewHolder2(v);
return null;
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder,
int position)
Tipo oggetto = lista.get(position);
if(oggetto != null)
if(oggetto.getType())
((ViewHolder1)viewHolder).titolo1.setText(oggetto.getName());
else
((ViewHolder2)viewHolder).titolo2.setText(oggetto.getName());
@Override
public int getItemCount()
if (lista == null)
return 0;
return lista.size();
public int getItemViewType(int position)
if (lista.get(position).DIREZIONE)
return 0;
else return 1;
查看 Holder 右项
class ViewHolder1 extends RecyclerView.ViewHolder implements View.OnClickListener
private TextView titolo1;
public ViewHolder1(@NonNull View itemView)
super(itemView);
titolo1 = itemView.findViewById(R.id.testoDestro);
@Override
public void onClick(View v)
查看 Holder 左侧项目
ViewHolder2 类扩展 RecyclerView.ViewHolder 实现 View.OnClickListener
private TextView titolo2;
public ViewHolder2(@NonNull View itemView)
super(itemView);
titolo2 = itemView.findViewById(R.id.testoSinistro);
@Override
public void onClick(View v)
主要
public class MainActivity extends AppCompatActivity
private List<Tipo> lista;
private List<String> lista2;
ImageView indietro;
Handler handler = new Handler();
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RecyclerView recyclerView;
LinearLayoutManager linearLayoutManager;
linearLayoutManager = new LinearLayoutManager(MainActivity.this);
recyclerView = (findViewById(R.id.recycler));
indietro = findViewById(R.id.indietro);
recyclerView.setLayoutManager(linearLayoutManager);
final Adapter adapter = new Adapter(Dati.getData(), recyclerView);
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(linearLayoutManager);
recyclerView.setAdapter(adapter);
adapter.setOnLoadMoreListener(new Adapter.OnLoadMoreListener()
@Override
public void onLoadMore()
lista.add(null);
adapter.notifyItemInserted(lista.size() - 1);
handler.postDelayed(new Runnable()
@Override
public void run()
lista.remove(lista.size() - 1);
adapter.notifyItemRemoved(lista.size());
for (int i = 0; i < 15; i++)
if (i % 2 == 1)
lista.add(new Tipo("Example",false));
adapter.notifyItemInserted(lista.size());
else
lista.add(new Tipo("Example",true));
adapter.notifyItemInserted(lista.size());
adapter.setLoaded();
, 3000);
System.out.println("load");
);
日志
2019-05-03 10:08:25.249 5254-5254/? I/o.myapplicatio: Late-enabling -Xcheck:jni
2019-05-03 10:08:25.469 5254-5254/com.sinfo.myapplication W/o.myapplicatio: JIT profile information will not be recorded: profile file does not exits.
2019-05-03 10:08:25.472 5254-5254/com.sinfo.myapplication I/chatty: uid=10122(com.sinfo.myapplication) identical 10 lines
2019-05-03 10:08:25.472 5254-5254/com.sinfo.myapplication W/o.myapplicatio: JIT profile information will not be recorded: profile file does not exits.
2019-05-03 10:08:25.499 5254-5254/com.sinfo.myapplication I/InstantRun: starting instant run server: is main process
2019-05-03 10:08:25.720 5254-5254/com.sinfo.myapplication W/o.myapplicatio: Accessing hidden method Landroid/view/View;->computeFitSystemWindows(Landroid/graphics/Rect;Landroid/graphics/Rect;)Z (light greylist, reflection)
2019-05-03 10:08:25.722 5254-5254/com.sinfo.myapplication W/o.myapplicatio: Accessing hidden method Landroid/view/ViewGroup;->makeOptionalFitsSystemWindows()V (light greylist, reflection)
2019-05-03 10:08:25.969 5254-5254/com.sinfo.myapplication D/OpenGLRenderer: Skia GL Pipeline
2019-05-03 10:08:26.073 5254-5272/com.sinfo.myapplication I/Adreno: QUALCOMM build : a570411, Id0218a7f5c
Build Date : 09/27/18
OpenGL ES Shader Compiler Version: EV031.25.03.00
Local Branch :
Remote Branch : refs/tags/AU_LINUX_ANDROID_LA.UM.7.5.R1.09.00.00.464.025
Remote Branch : NONE
Reconstruct Branch : NOTHING
2019-05-03 10:08:26.073 5254-5272/com.sinfo.myapplication I/Adreno: Build Config : S L 6.0.7 AArch64
2019-05-03 10:08:26.083 5254-5272/com.sinfo.myapplication I/Adreno: PFP: 0x005ff110, ME: 0x005ff066
2019-05-03 10:08:26.089 5254-5272/com.sinfo.myapplication I/ConfigStore: android::hardware::configstore::V1_0::ISurfaceFlingerConfigs::hasWideColorDisplay retrieved: 0
2019-05-03 10:08:26.089 5254-5272/com.sinfo.myapplication I/ConfigStore: android::hardware::configstore::V1_0::ISurfaceFlingerConfigs::hasHDRDisplay retrieved: 1
2019-05-03 10:08:26.090 5254-5272/com.sinfo.myapplication I/OpenGLRenderer: Initialized EGL, version 1.4
2019-05-03 10:08:26.090 5254-5272/com.sinfo.myapplication D/OpenGLRenderer: Swap behavior 2
2019-05-03 10:08:26.127 5254-5254/com.sinfo.myapplication W/o.myapplicatio: Accessing hidden field Landroid/view/View;->mAccessibilityDelegate:Landroid/view/View$AccessibilityDelegate; (light greylist, reflection)
2019-05-03 10:08:46.624 5254-5254/com.sinfo.myapplication W/ActivityThread: handleWindowVisibility: no activity for token android.os.BinderProxy@e5efecf
2019-05-03 10:08:48.664 5254-5254/com.sinfo.myapplication D/AndroidRuntime: Shutting down VM
2019-05-03 10:08:48.672 5254-5254/com.sinfo.myapplication E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.sinfo.myapplication, PID: 5254
java.lang.NullPointerException: Attempt to invoke interface method 'boolean java.util.List.add(java.lang.Object)' on a null object reference
at com.sinfo.myapplication.MainActivity$1.onLoadMore(MainActivity.java:53)
at com.sinfo.myapplication.Adapter$1.onScrolled(Adapter.java:43)
at android.support.v7.widget.RecyclerView.dispatchOnScrolled(RecyclerView.java:4961)
at android.support.v7.widget.RecyclerView$ViewFlinger.run(RecyclerView.java:5117)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:949)
at android.view.Choreographer.doCallbacks(Choreographer.java:761)
at android.view.Choreographer.doFrame(Choreographer.java:693)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:935)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6718)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
【问题讨论】:
能否请您发布您的崩溃日志? 试试 [this] (***.com/questions/31000964/…) 并提供错误信息 【参考方案1】:我认为您的问题在于您如何通知适配器。如果你没有正确通知它,那将导致适配器和数据之间的不一致,并且应用程序将崩溃。
例如,如果您删除了所有项目,而是告诉适配器您添加了更多项目 - 这将导致崩溃。
在您的代码中,您正在添加项目并告诉它两个不同的位置。
lista.add(null);
adapter.notifyItemInserted(lista.size() - 1);
和
lista.add(new Tipo("Example",false));
adapter.notifyItemInserted(lista.size());
您是在告诉适配器您在哪里插入了新项目,但在这些位置中您是在告诉它两个不同的位置(.size()
和 .size() - 1
)。
【讨论】:
我意识到我忘记在Adapter构造函数中上传部分代码。另外,日志已上传。【参考方案2】:lista = new Arraylist<>();
您需要在使用之前初始化您的列表。
【讨论】:
以上是关于无尽的recyclerview,多种视图类型,OnscrollListener 后崩溃的主要内容,如果未能解决你的问题,请参考以下文章
java 无尽的RecyclerView OnScrollListener
int android.support.v7.widget.RecyclerView$ViewHolder.mItemViewType' on a null.....