无尽的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 后崩溃的主要内容,如果未能解决你的问题,请参考以下文章

如何创建一个循环(无尽的)RecyclerView?

java 无尽的RecyclerView OnScrollListener

我如何创建无尽的两侧滚动RecyclerView?

int android.support.v7.widget.RecyclerView$ViewHolder.mItemViewType' on a null.....

保留recyclelerview中的edittext内容

RecyclerView 展示多种类型Item数据