Модернизация Android 2: как я могу создать расширяемый вид recycler для категорий и подкатегорий?

#android #retrofit #android-recyclerview #recyclerview-layout

#Android #модернизация #android-recyclerview #recyclerview-layout

Вопрос:

Я пытаюсь заархивировать эту функциональность для своего продуктового приложения https://imgur.com/Ugj4BIO Но мне не удалось этого сделать!

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

Вот мой Json-код, из которого я прямо сейчас извлекаю свои данные с веб-сервера, его локального хостинга

 {"cats":
[{"sub_cats": 
 [{
 "sub_id":"1",
 "sub_title":"Charger",
 "sub_img":"http://localhost/adminPohanch/public/img/img23.jpg"
 },
 {
  "sub_id":"2",
  "sub_title":"Dummy",
  "sub_img":"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTrRRV2S-HAzHVIfS0EtgfIeWnej05TRN1PqWQCLW44h3NqM9UOtQ"
 }
],
"id":"52",
"title":"Electric Equipments",
"img":""}],
"message":"Categories Loaded","success":1}
  

Вот метод абстрактного класса API retofit в

 @GET("cats.php")
    Call<Categories> getCategories();
  

Мой класс модели Categories — это

 public class Categories {
    @SerializedName("id")
    @Expose
    private String id;
    @SerializedName("title")
    @Expose
    private String title;
    @SerializedName("img")
    @Expose
    private String img;
    @SerializedName("sub_id")
    @Expose
    private String sub_id;
    @SerializedName("sub_title")
    @Expose
    private String sub_title;
    @SerializedName("sub_img")
    @Expose
    private String sub_img;

    @SerializedName("cats")
    @Expose
    private List<Categories> cats = null;

    @SerializedName("sub_cats")
    @Expose
    private List<Categories> sub_cats = null;
    @SerializedName("message")
    @Expose
    private String message;
    @SerializedName("success")
    @Expose
    private Integer success;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getImg() {
        return img;
    }

    public void setImg(String img) {
        this.img = img;
    }

    public String getSub_id() {
        return sub_id;
    }

    public void setSub_id(String sub_id) {
        this.sub_id = sub_id;
    }

    public String getSub_title() {
        return sub_title;
    }

    public void setSub_title(String sub_title) {
        this.sub_title = sub_title;
    }

    public String getSub_img() {
        return sub_img;
    }

    public void setSub_img(String sub_img) {
        this.sub_img = sub_img;
    }

    public List<Categories> getCats() {
        return cats;
    }

    public void setCats(List<Categories> cats) {
        this.cats = cats;
    }

    public List<Categories> getSub_cats() {
        return sub_cats;
    }

    public void setSub_cats(List<Categories> sub_cats) {
        this.sub_cats = sub_cats;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public Integer getSuccess() {
        return success;
    }

    public void setSuccess(Integer success) {
        this.success = success;
    }
}
  

Вот код для моей активности
из которого я получаю результат / данные и инициализирую свой адаптер

 Call<Categories> callCats = RetrofitBuilder.getInstance().getApi().getCategories();
        callCats.enqueue(new Callback<Categories>() {

            @Override
            public void onResponse(Call<Categories> call, Response<Categories> response) {
                Categories cats = response.body();
                Log.d("cats", "onResponse: "   cats);
                if (cats != null){
                    List<Categories> catsList = cats.getCats();

                    Log.d("Categories", "onResponse: "   catsList.size());
                    Log.d("Categories", "onResponse: "   cats.getCats().toString());

                    for(int i = 0; i < catsList.size(); i  ){

                        Categories categoriesData = new Categories();
                        String id = catsList.get(i).getId();
                        String title = catsList.get(i).getTitle();
                        String img = catsList.get(i).getImg();

                        categoriesData.setId(id);
                        categoriesData.setTitle(title);
                        categoriesData.setImg(img);

                        getCatItems.add(categoriesData);

                        List<Categories> sub = catsList.get(i).getSub_cats();
                        Toast.makeText(BuyerDashboard.this, "" sub.size(), Toast.LENGTH_SHORT).show();


                        for (int j = 0; j < sub.size(); j  ){

                            Categories categories = new Categories();
                            categories.setId(sub.get(i).getSub_id());
                            categories.setSub_title(sub.get(i).getSub_title());
                            categories.setSub_img(sub.get(i).getSub_img());
                            getSubItems.add(categories);

                        }
                    }

                    ExpandableRecyclerViewAdapter expandableCategoryRecyclerViewAdapter =
                            new ExpandableRecyclerViewAdapter(getApplicationContext(), getCatItems, getSubItems);
                    expanderRecyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
                    expanderRecyclerView.setAdapter(expandableCategoryRecyclerViewAdapter);
                }
            }

            @Override
            public void onFailure(Call<Categories> call, Throwable t) {
                Toast.makeText(BuyerDashboard.this, t.getMessage(), Toast.LENGTH_SHORT).show();
            }
        });
  

**ExpandableRecyclerViewAdapter **

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

    List<Categories> nameList ;
    List<Integer> counter = new ArrayList<Integer>();
    List<Categories> itemNameList;
    Context context;

    public ExpandableRecyclerViewAdapter(Context context,
                                         List<Categories> nameList,
                                         List<Categories> itemNameList ) {
        this.nameList = nameList;
        this.itemNameList = itemNameList;
        this.context = context;

        Log.d("namelist", nameList.toString());

        for (int i = 0; i < nameList.size(); i  ) {
            counter.add(0);
        }
    }

    @NonNull
    @Override
    public ExpandableRecyclerViewAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
        View v = LayoutInflater.from(viewGroup.getContext())
                .inflate(R.layout.cat_items, viewGroup, false);

        ExpandableRecyclerViewAdapter.ViewHolder vh = new ExpandableRecyclerViewAdapter.ViewHolder(v);

        return vh;
    }

    @Override
    public void onBindViewHolder(@NonNull final ExpandableRecyclerViewAdapter.ViewHolder holder, final int position) {
        Categories categories = nameList.get(position);
        holder.name.setText(categories.getTitle());
        InnerRecyclerViewAdapter itemInnerRecyclerView = new InnerRecyclerViewAdapter(itemNameList, context);
        holder.cardRecyclerView.setLayoutManager(new GridLayoutManager(context, 2));

        holder.cardView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                if (counter.get(position) % 2 == 0) {
                    holder.cardRecyclerView.setVisibility(View.VISIBLE);
                } else {
                    holder.cardRecyclerView.setVisibility(View.GONE);
                }

                counter.set(position, counter.get(position)   1);
            }
        });
        holder.cardRecyclerView.setAdapter(itemInnerRecyclerView);
    }

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

    public class ViewHolder extends RecyclerView.ViewHolder {
        TextView name;
        ImageButton dropBtn;
        RecyclerView cardRecyclerView;
        CardView cardView;

        public ViewHolder(final View itemView) {
            super(itemView);
            name = itemView.findViewById(R.id.categoryTitle);
            dropBtn = itemView.findViewById(R.id.categoryExpandBtn);
            cardRecyclerView = itemView.findViewById(R.id.innerRecyclerView);
            cardView = itemView.findViewById(R.id.cardView);

        }
    }
}
  

InnerRecyclerViewAdapter For Childs/(sub-categories)

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

    public List<Categories> nameList;
    Context context;
    public InnerRecyclerViewAdapter(List<Categories> nameList, Context context) {

        this.nameList = nameList;
        this.context = context;
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int i) {
        View v = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.sub_cat_items, parent, false);


        InnerRecyclerViewAdapter.ViewHolder vh = new InnerRecyclerViewAdapter.ViewHolder(v);

        return vh;
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, final int position) {
        Categories subCategories = nameList.get(position);
        holder.name.setText(subCategories.getTitle());
        holder.name.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                Intent i = new Intent(context, ProductsActivity.class);
                Categories subCategories = nameList.get(position);
                i.putExtra("sub_cat_id", subCategories.getId());
                i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                context.startActivity(i);
            }
        });
    }

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

    public class ViewHolder extends RecyclerView.ViewHolder {
        TextView name;

        public ViewHolder(View itemView) {
            super(itemView);
            name = itemView.findViewById(R.id.itemTextView);
        }
    }
}
  

Right now I am not displaying anything for Images I am focusing on Title of categories(parents) and sub-categories (child)

Here is my sub_cat_items file

 <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <android.support.v7.widget.CardView
        android:id="@ id/cardView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        >

        <LinearLayout
            android:id="@ id/linearLayoutHolder"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:padding="10dp">


            <ImageView
                android:id="@ id/sub_cat_img"
                android:layout_width="50dp"
                android:layout_height="50dp"
                android:layout_gravity="center"
                android:background="@drawable/pohanch" />

            <TextView
                android:id="@ id/itemTextView"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:layout_marginTop="5dp"
                android:text="Fresh Fruits"
                android:textAlignment="center"
                android:textSize="14sp" />

        </LinearLayout>

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

</RelativeLayout>
  

И последним здесь является мой файл cat_items

 <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:animateLayoutChanges="true">


    <android.support.v7.widget.CardView
        android:id="@ id/cardView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="3dp">

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <LinearLayout
                android:id="@ id/linearLayoutHolder"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="horizontal"
                android:padding="20dp">

                <RelativeLayout
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginLeft="10dp"
                    android:layout_marginStart="10dp"
                    android:orientation="vertical">

                    <TextView
                        android:id="@ id/categoryTitle"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="Fruits amp;amp; Vegetables"
                        android:textColor="@color/basiccolor"
                        android:textSize="16sp" />

                    <ImageButton
                        android:id="@ id/categoryExpandBtn"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_alignParentEnd="true"
                        android:layout_alignParentRight="true"
                        android:background="#FFF"
                        android:src="@drawable/ic_arrow_downward_black_24dp" />

                </RelativeLayout>


            </LinearLayout>

            <android.support.v7.widget.RecyclerView
                android:id="@ id/innerRecyclerView"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_below="@ id/linearLayoutHolder"
                android:background="#f6f6f6"
                android:visibility="gone">

            </android.support.v7.widget.RecyclerView>
        </RelativeLayout>

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


</RelativeLayout>
  

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

Вот мой вывод https://imgur.com/Feq6XBP

Ответ №1:

Проверьте этот пример кода для настройки expandableview . https://github.com/developernadeem/ShopGrocery

Ответ №2:

RecyclerView предназначен для списка, а не для расширяемого списка просмотра может быть, вы хотите проверить это руководство:https://www.androidhive.info/2013/07/android-expandable-list-view-tutorial

Или, может быть, хотите проверить эту библиотеку: https://github.com/thoughtbot/expandable-recycler-view

Конечно, вы можете использовать RecyclerView, но вам нужно изменить макет, выполнив свои собственные вычисления и заставив слушателя делать расширяемый и не расширяемый

Ответ №3:

Модернизация возвращает классы конфигурации объекта таким образом

 public class Category{
List<Cats> cats;
private String message;
private int success;
}



Public class Cats{
List<SubCats> sub_cats;
private String id;
private String title;
private String img;
}



public class SubCats{
private String sub_id;
private String sub_title;
private String sub_img;
}
  

Теперь

 @GET("cats.php")
Call<Category> getCategories();
  

Вам также нужно настроить JSON, удалить красные метки на изображении. Это кажется ненужным.
Также перенастроите PHPНеобходимо отформатировать ваш объект ответа