при добавлений Retrofit в NestedScrollView в виде списка RecycleView выходит ошибка

список очень долго прогружается и зависает а после вылетает

без NestedScrollView и CollapsingToolbarLayout работает хорошо что делать

вот код как работает приложение много раз расходует память(не знаю как правильно написать)

код

ошибка во вкладке ran ошибка во вкладке ran код ошибки код ошибки

код самого фрагмента

    <com.google.android.material.appbar.CollapsingToolbarLayout
        android:id="@+id/collapsing_toolbar"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:contentScrim="@color/white"
        app:layout_scrollFlags="scroll|snap|exitUntilCollapsed"
        android:background="@color/white">

        <ImageView
            android:layout_width="320dp"
            android:layout_height="140dp"
            android:src="@drawable/pizza"
            android:scaleType="centerCrop"
            android:layout_gravity="center"
            android:layout_marginTop="20dp"
            android:layout_marginBottom="25dp"
            app:layout_collapseMode="parallax"/>

        <androidx.appcompat.widget.Toolbar
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:layout_collapseMode="pin"/>


    </com.google.android.material.appbar.CollapsingToolbarLayout>
</com.google.android.material.appbar.AppBarLayout>

<androidx.core.widget.NestedScrollView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="20dp"
    app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recycleView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:listitem="@layout/item"/>

</androidx.core.widget.NestedScrollView>

</androidx.coordinatorlayout.widget.CoordinatorLayout>

код класса форагмент

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_blank, container, false);

    recyclerView = view.findViewById(R.id.recycleView);
    layoutManager = new LinearLayoutManager(getContext());
    recyclerView.setLayoutManager(layoutManager);
    adapter = new ImageAdapter(postsList);
    recyclerView.setAdapter(adapter);

    fetchPosts();


    return view;
}

private void fetchPosts() {

    postviewModel = ViewModelProviders.of(getActivity()).get(PostviewModel.class);
    postviewModel.getPosts();

    postviewModel.mutableLiveData.observe(getViewLifecycleOwner(), new Observer<List<Photos_POJO>>() {
        @Override
        public void onChanged(List<Photos_POJO> photos_pojos) {
            adapter.getPostsList(photos_pojos);
        }
    });
    adapter.notifyDataSetChanged();
}

код ViewModel

public MutableLiveData<List<Photos_POJO>> mutableLiveData = new MutableLiveData<>();

public void getPosts(){

    RetrofitClient.getINSTANCE().getPhoto().enqueue(new Callback<List<Photos_POJO>>() {
        @Override
        public void onResponse(Call<List<Photos_POJO>> call, Response<List<Photos_POJO>> response) {
            if (response.isSuccessful() && response.body() != null){
                mutableLiveData.setValue(response.body());


            }
        }

        @Override
        public void onFailure(Call<List<Photos_POJO>> call, Throwable t) {

        }

    });
}

код POJO

public Photos_POJO(String title, String body) {
    this.title = title;
    this.body = body;
}

public String getTitle() {
    return title;
}

public String getBody() {
    return body;
}

public String getUrl() {
    return url;
}

код адаптера

public void getPostsList(List<Photos_POJO> photos_pojos) {
    this.postsList = photos_pojos;
    notifyDataSetChanged();
}

@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item, parent, false);
    return new ViewHolder(view);
}

@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
    holder.tvTitle.setText(postsList.get(position).getTitle());
    holder.tvBody.setText(postsList.get(position).getBody());

    Picasso.get().load(postsList.get(position).getUrl()).into(holder.imageView);
}

@Override
public int getItemCount() {
    return postsList.size();
}

public class ViewHolder extends RecyclerView.ViewHolder {
    TextView tvTitle;
    TextView tvBody;
    ImageView imageView;


    public ViewHolder(@NonNull View itemView) {
        super(itemView);

        tvTitle = itemView.findViewById(R.id.tvTitle);
        tvBody = itemView.findViewById(R.id.tvBody);
        imageView = itemView.findViewById(R.id.image);

Ответы (1 шт):

Автор решения: Wlad

Для начала надо разобраться с основной фишкой recycleview

Он НЕ отображает список целиком. Он показывает лишь те item'ы, что сейчас видит пользователь (ну и + парочка сверху и снизу). Когда вы скролите ресайкл вниз/вверх - происходит новых элементов, а старые стираются. Это надо для того, чтобы UI приложения был более быстрый.

Теперь, что происходит, когда recycleview помещают в nestedscrollview?

Происходит, грубо говоря, "выключение" основной фишки recycleview, которая описана выше. Т.е. все данные СРАЗУ же помещаются в ресайкл, что затратно для приложения. Вы сами это заметили:
"без NestedScrollView работает хорошо"

Что еще может быть не так?

№1 метод fetchPosts
Вы "кормите" адаптер данные через слушателя LiveData, а вот "обновление" ресайкла где-то в стороне. Для полноты картины надо посмотреть "в каком формате вам приходят данные по сети? это сразу целый массив, или по 1 объекту, которые заполняют массив?"

№2 onCreateView
вы все делаете в момент onCreateView. возможно, стоит это делать в методе onViewCreated. почитайте, чем эти жизненные этапы фрагмента отличаются друг от друга.

№3 Потоки
Не ясно, в каком потоке вы все это выполняете. Лог вашей ошибки говорит о том, что приложению недостаточно памяти. Причиной этому может быть так же быть то, что все это приосходит в mainThread. Попробуйте получить данные для LiveData в другом потоке, а потом через слушателя отобразить их в Ресайкле.
LiveData полностью раскрывает свой функционал именно в потоках.
Так же есть вопрос о том, КАК вы меняете данные LiveData: просто присваиваете или метод postValue() ?

В любом случае, у вас проблемы именно с оптимизацией кода.

→ Ссылка