Бесконечный просмотрщик, несколько типов представлений, сбой после OnscrollListener - PullRequest
1 голос
/ 02 мая 2019

Я пытался создать RecyclerView, который генерирует элементы при прокрутке. Метод> onScrollListener генерирует элементы с двумя различными типами представлений: ViewType ==> FALSE создает макет с CardView справа, в то время как ViewType == TRUE a> макет с CardView слева.

то, чего я пытался добиться, - это с помощью цикла генерировать бесконечный список> элементов с нечетными элементами (с переменной int, которая увеличивается каждый раз, когда> генерируется элемент), расположенной в макете. макет> с 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;}
}

Просмотр держателя правой позиции

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) {

}
}

Держатель левого предмета

класс 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)

1 Ответ

0 голосов
/ 02 мая 2019

Я считаю, что ваша проблема связана с тем, как вы уведомляете свой адаптер. Если вы не уведомите об этом правильно, это приведет к несоответствию между адаптером и данными, и приложение упадет.

Например, если вы удалите все элементы, но вместо этого сообщите адаптеру, что добавили больше - это приведет к сбою.

В своем коде вы добавляете элементы и сообщаете ему две разные позиции.

lista.add(null);
adapter.notifyItemInserted(lista.size() - 1);

и

lista.add(new Tipo("Example",false));
adapter.notifyItemInserted(lista.size());

Вы указываете адаптеру, куда вы вставили новый элемент, но в них вы указываете ему два разных положения (.size() и .size() - 1).

...