Как сделать Recyclerview с дочерним Recyclerview в Android

Я хочу сделать что-то вроде домашнего просмотра Spotify с помощью Retrofit, но не могу понять, как это сделать. пожалуйста, помогите ему, я очень смущен. пожалуйста, помогите ему, это мой код XML выглядит так. Первый — это основной макет Recyclerview, второй макет — Recyclerview RowItem List, а еще один — список строк innerItem. Я хочу получить что-то вроде этого, как получить фактический результат, такой как Spotify. Я хочу показать их, но они дают мне одни и те же данные, но у меня есть разные данные с другим массивом... тогда как показать разные данные.

введите здесь описание изображения

введите здесь описание изображения

введите здесь описание изображения

Основной Recyclerview.xml

            <RelativeLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:orientation="vertical">

                <android.support.v7.widget.RecyclerView
                    android:id="@+id/list_product"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent" />


            </RelativeLayout>

RecyclerviewItem.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <android.support.v7.widget.CardView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="@dimen/_10sdp">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:layout_margin="@dimen/_5sdp">

            <TextView
                android:id="@+id/tvCatName"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:padding="@dimen/_10sdp"
                android:text="cat name"/>

            <android.support.v7.widget.RecyclerView
                android:id="@+id/catProductList"
                android:layout_width="match_parent"
                android:layout_height="wrap_content">
            </android.support.v7.widget.RecyclerView>
        </LinearLayout>
    </android.support.v7.widget.CardView>

</LinearLayout>

Inneritem.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical">

    <android.support.v7.widget.CardView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="@dimen/_10sdp">

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="vertical">

            <android.support.v7.widget.CardView
                android:layout_width="@dimen/_160sdp"
                android:layout_height="@dimen/_170sdp"
                app:cardPreventCornerOverlap="false">

            <ImageView
                android:id="@+id/imgProduct"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:src="@drawable/ic_bags"/>
            </android.support.v7.widget.CardView>


            <TextView
                android:id="@+id/tvProductName"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Yello New Shirt"
                android:layout_gravity="center"
                android:padding="@dimen/_5sdp"
                android:textStyle="bold"
                android:layout_marginTop="@dimen/_2sdp"
                android:textSize="@dimen/_16ssp"
                android:singleLine="true"/>

            <TextView
                android:id="@+id/tvProductPrice"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="15.00"
                android:layout_gravity="center"
                android:padding="@dimen/_5sdp"
                android:textStyle="bold"
                android:layout_marginTop="@dimen/_2sdp"
                android:textSize="@dimen/_13ssp"
                android:singleLine="true"/>

        </LinearLayout>
    </android.support.v7.widget.CardView>

</LinearLayout>

Мой код Я не знаю, в чем проблема

Data.java
public class Data {

    String categoryName;
    ArrayList<ProductsModel> productsModels;

    public Data() {
    }

    public Data(String categoryName, ArrayList<ProductsModel> productsModels) {
        this.categoryName = categoryName;
        this.productsModels = productsModels;
    }

    public ArrayList<ProductsModel> getProductsModels() {
        return productsModels;
    }

    public void setProductsModels(ArrayList<ProductsModel> productsModels) {
        this.productsModels = productsModels;
    }

    public String getCategoryName() {
        return categoryName;
    }

    public void setCategoryName(String categoryName) {
        this.categoryName = categoryName;
    }
}

InCategoryProductAdapter.java

public class InCategoryProductAdapter extends RecyclerView.Adapter<InCategoryProductAdapter.ViewHolder> {

    private Context context;
    private ArrayList<Data> dataArrayList;
    private RecyclerView.RecycledViewPool recycledViewPool;

    public InCategoryProductAdapter(Context context, ArrayList<Data> dataArrayList) {
        this.context = context;
        this.dataArrayList = dataArrayList;

        recycledViewPool = new RecyclerView.RecycledViewPool();
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {

        View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.main_row_list,viewGroup,false);
        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder viewHolder, int i) {

        viewHolder.tvCatName.setText(dataArrayList.get(i).getCategoryName());
        LinearLayoutManager manager = new LinearLayoutManager(context,LinearLayoutManager.HORIZONTAL,false);
        viewHolder.catProductList.setLayoutManager(manager);

        InnerItemAdapter innerItemAdapter = new InnerItemAdapter(context,dataArrayList.get(i).getProductsModels());
        viewHolder.catProductList.setAdapter(innerItemAdapter);

    }

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

    }

    class ViewHolder extends RecyclerView.ViewHolder{

        TextView tvCatName;
        RecyclerView catProductList;

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

            tvCatName = itemView.findViewById(R.id.tvCatName);
            catProductList = itemView.findViewById(R.id.catProductList);
        }
    }
}

Fragment.java

/*set Catgeory  Api if get department ID*/
    private void setCategory(int dept_id) {
        models = new ArrayList<>();
        RetrofitInterface retrofitInterface = RetrfitClient.getRetrofitClient().create(RetrofitInterface.class);
        Call<ArrayList<CategoryModel>> arrayListCall = retrofitInterface.Category_Call(dept_id);
        arrayListCall.enqueue(new Callback<ArrayList<CategoryModel>>() {
            @Override
            public void onResponse(Call<ArrayList<CategoryModel>> call, Response<ArrayList<CategoryModel>> response) {

                models = response.body();
                for (int i = 0; i < models.size(); i++) {
                    catId = models.get(i).getCategory_id();
                    setCategoryProduct(catId, models);
                }
                //Log.d("ModelsSize", "" + models.size());
            }

            @Override
            public void onFailure(Call<ArrayList<CategoryModel>> call, Throwable t) {

                Toast.makeText(getActivity(), t.toString(), Toast.LENGTH_SHORT).show();
            }
        });
    }

    /*get category wise product From Server*/

введите описание изображения здесь private void setCategoryProduct(int catId, final ArrayList categoryModels, final String catName) {

Log.d("getSingleCat", "" + catId);

productsModels = new ArrayList<>();
RetrofitInterface anInterface = RetrfitClient.getRetrofitClient().create(RetrofitInterface.class);
Call<ProductInCategoryResponse> inCategoryResponseCall = anInterface.IN_CATEGORY_RESPONSE_CALL(catId, 1);
inCategoryResponseCall.enqueue(new Callback<ProductInCategoryResponse>() {
    @Override
    public void onResponse(Call<ProductInCategoryResponse> call, Response<ProductInCategoryResponse> response) {

        productsModels = response.body().getRows();
        Log.d("productCat", "" + productsModels.size());

        data.setCategoryName(catName);
        data.setProductsModels(productsModels);

        dataArrayList = new ArrayList<>();



        HashMap<String,ArrayList<ProductsModel>> listHashMap = new HashMap<String, ArrayList<ProductsModel>>();
        for (int j=0;j<categoryModels.size();j++){
            dataArrayList.add(data);
            listHashMap.put(categoryModels.get(j).getName(), productsModels);
            Log.d("ListMap",""+listHashMap.put(categoryModels.get(j).getName(),productsModels));
        }

        Log.d("CatName",""+catName);

        /*Gson gson  = new Gson();
        String pList = gson.toJson(productsModels);*/


        LinearLayoutManager manager = new LinearLayoutManager(getActivity());
        mainRecyclerView.setLayoutManager(manager);

        InCategoryProductAdapter inCategoryProductAdapter = new InCategoryProductAdapter(getActivity(), dataArrayList);
        mainRecyclerView.setAdapter(inCategoryProductAdapter);

        /*
        Log.d("DataArray", "" + dataArrayList.size());
        Log.d("GetCat", "" + data.getCategoryName());*/
        // Log.d("DataList",""+dataArrayList.get(i).getCategoryName() + " :"+ dataArrayList.get(i).getProductsModels());

    }

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

        Toast.makeText(getActivity(), t.toString(), Toast.LENGTH_SHORT).show();
    }
});

}


person axar    schedule 19.07.2019    source источник
comment
Возьмите родителя RecyclerView в своем макете, затем в макете элемента выберите еще один дочерний элемент RecyclerView.   -  person Jeel Vankhede    schedule 19.07.2019
comment
Мне нужно сделать один основной макет Recyclerview, а другой - с текстовым представлением и макетом представления recycler, чтобы сделать оба класса адаптера, но у меня есть два разных API, как присоединиться к нам.   -  person axar    schedule 19.07.2019
comment
Вы можете обернуть свой дочерний список дочернего адаптера в родительский список. Т.е. Класс модели элемента родительского списка содержит только одну строку для привязки заголовка, затем берет один объект списка массива типа класса дочерней модели, а затем передает его дочернему адаптеру по положению.   -  person Jeel Vankhede    schedule 19.07.2019


Ответы (4)


SnapHelper

SnapHelper — это вспомогательный класс, который помогает привязать любое дочернее представление RecyclerView. Например, вы можете привязать firstVisibleItem RecyclerView, поскольку вы, должно быть, видели в приложении магазина игр, что firstVisibleItem всегда будет полностью виден, когда прокрутка доходит до положения ожидания.

https://blog.mindorks.com/using-snaphelper-in-recyclerview-fc616b6833e8

import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.LinearSnapHelper;
import android.support.v7.widget.OrientationHelper;
import android.support.v7.widget.RecyclerView;
import android.view.View;

/**
 * Created by Mayur patel on 15/01/17.
 */

public class StartSnapHelper extends LinearSnapHelper {

    private OrientationHelper mVerticalHelper, mHorizontalHelper;

    public StartSnapHelper() {

    }

    @Override
    public void attachToRecyclerView(@Nullable RecyclerView recyclerView)
            throws IllegalStateException {
        super.attachToRecyclerView(recyclerView);
    }

    @Override
    public int[] calculateDistanceToFinalSnap(@NonNull RecyclerView.LayoutManager layoutManager,
                                              @NonNull View targetView) {
        int[] out = new int[2];

        if (layoutManager.canScrollHorizontally()) {
            out[0] = distanceToStart(targetView, getHorizontalHelper(layoutManager));
        } else {
            out[0] = 0;
        }

        if (layoutManager.canScrollVertically()) {
            out[1] = distanceToStart(targetView, getVerticalHelper(layoutManager));
        } else {
            out[1] = 0;
        }
        return out;
    }

    @Override
    public View findSnapView(RecyclerView.LayoutManager layoutManager) {

        if (layoutManager instanceof LinearLayoutManager) {

            if (layoutManager.canScrollHorizontally()) {
                return getStartView(layoutManager, getHorizontalHelper(layoutManager));
            } else {
                return getStartView(layoutManager, getVerticalHelper(layoutManager));
            }
        }

        return super.findSnapView(layoutManager);
    }

    private int distanceToStart(View targetView, OrientationHelper helper) {
        return helper.getDecoratedStart(targetView) - helper.getStartAfterPadding();
    }

    private View getStartView(RecyclerView.LayoutManager layoutManager,
                              OrientationHelper helper) {

        if (layoutManager instanceof LinearLayoutManager) {
            int firstChild = ((LinearLayoutManager) layoutManager).findFirstVisibleItemPosition();

            boolean isLastItem = ((LinearLayoutManager) layoutManager)
                    .findLastCompletelyVisibleItemPosition()
                    == layoutManager.getItemCount() - 1;

            if (firstChild == RecyclerView.NO_POSITION || isLastItem) {
                return null;
            }

            View child = layoutManager.findViewByPosition(firstChild);

            if (helper.getDecoratedEnd(child) >= helper.getDecoratedMeasurement(child) / 2
                    && helper.getDecoratedEnd(child) > 0) {
                return child;
            } else {
                if (((LinearLayoutManager) layoutManager).findLastCompletelyVisibleItemPosition()
                        == layoutManager.getItemCount() - 1) {
                    return null;
                } else {
                    return layoutManager.findViewByPosition(firstChild + 1);
                }
            }
        }

        return super.findSnapView(layoutManager);
    }

    private OrientationHelper getVerticalHelper(RecyclerView.LayoutManager layoutManager) {
        if (mVerticalHelper == null) {
            mVerticalHelper = OrientationHelper.createVerticalHelper(layoutManager);
        }
        return mVerticalHelper;
    }

    private OrientationHelper getHorizontalHelper(RecyclerView.LayoutManager layoutManager) {
        if (mHorizontalHelper == null) {
            mHorizontalHelper = OrientationHelper.createHorizontalHelper(layoutManager);
        }
        return mHorizontalHelper;
    }
}

Теперь прикрепите это к вашему RecyclerView.

SnapHelper startSnapHelper = new StartSnapHelper();
startSnapHelper.attachToRecyclerView(yourRecyclerView);
person Mayur Patel    schedule 19.07.2019
comment
Я должен проверить треску GitHub, не совсем то же самое, что мне нравится. Я хочу, чтобы основной вид ресайклера находился внутри другого текстового представления и представления ресайклера. - person axar; 19.07.2019
comment
@axar это означает, что вам нужно настроить несколько типов, верно? - person Mayur Patel; 19.07.2019
comment
Да Установите несколько типов, пожалуйста, проверьте мой XML - person axar; 19.07.2019
comment
Затем вы должны различать метод getItemViewType RecyclerView.Adapter‹RecyclerView.ViewHolder› - person Mayur Patel; 19.07.2019

Вы можете создать фрагмент, содержащий заголовок и горизонтальный recyclerView, и всякий раз, когда вы получаете ответ от сервера, добавляйте этот фрагмент в счет своего списка, например, этот код:

    for (ViewModel items : model.getViewList()) {
        TextView textView = new TextView(activity);
        textView.setText(items.getTitle());
        textView.setPadding(UnitUtil.dpToPx(16), UnitUtil.dpToPx(4), UnitUtil.dpToPx(16), UnitUtil.dpToPx(4));

        RecyclerView recyclerView = new RecyclerView(activity);
        recyclerView.setLayoutManager(new LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, true));
        recyclerView.setHasFixedSize(true);
        recyclerView.setAdapter(new ContentAdapter(items.getContentList(), (anEnum, position, item, viewId) -> startActivity(new ContentFactory().getActivity(ActivityType.fromId(((ContentSimilarModel) item).getType())
                , activity, item)), false));
        recyclerView.addItemDecoration(new ContentDecoration());
        binding.homeViewLy.addView(textView);
        binding.homeViewLy.addView(recyclerView);
    }
person Payam Kokabi    schedule 19.07.2019

На данный момент я делаю что-то подобное в приложении, но пока еще рано, и я пытаюсь это сделать с помощью LinearLayout, обернутого прокруткой, в моем представлении ресайклера. Я программно добавляю в список, и пока он очень хорошо работает для вертикальной прокрутки. Доступен вид горизонтальной прокрутки, который мне еще предстоит попробовать, но он должен работать так же.

person sean le roy    schedule 25.02.2021
comment
вы можете легко использовать recyclerview View pool, также можете создать подэлемент... Пожалуйста, посетите код github.com/alghifari/RecycledViewPoolExample - person axar; 25.02.2021

Используйте представление Nested recyler и прочитайте это, оно расскажет вам, как это реализовать.

 > https://android.jlelse.eu/easily-adding-nested-recycler-view-in-android-a7e9f7f04047
person jins joseph    schedule 19.07.2019
comment
но он не работает с независимыми списками двух/нескольких типов, все они содержат только один тип списка - person USMAN osman; 14.03.2020