Как я могу поместить recyclerview в другой с данными, полученными из retrofit 2

#android #android-recyclerview #retrofit2

#Android #android-recyclerview #retrofit2

Вопрос:

Я новичок в обработке этих серверов, и мне нужна большая помощь. У меня есть два recyclerview в Android. Один предназначен для категорий, другой — для элементов. Я хочу поместить элементы в категории с помощью recyclerview. Итак, я получаю все данные с помощью retrofit 2. Я могу получить данные об элементах, но данные поступают с опозданием, и я не могу видеть категории. Как я могу это решить. Пожалуйста, помогите мне решить эту проблему? Спасибо.

Вот мой код:

urunAdapter

 public class UrunAdapter extends RecyclerView.Adapter<UrunAdapter.UrunlerViewHolder> {

    private Context context;
    private List<UrunListe> urun;
    private SelectedUrun selectedUrun;
    private int urunListeSize;

    public UrunAdapter(Context context, List<UrunListe> urun, SelectedUrun selectedUrun, int urunListeSize) {
        this.context = context;
        this.urun = urun;
        this.selectedUrun = selectedUrun;
        this.urunListeSize = urunListeSize;
    }

    @NonNull
    @Override
    public UrunlerViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {

        View view = LayoutInflater.from(context).inflate(R.layout.item_products, parent, false);

        return new UrunlerViewHolder(view);
    }

    public interface SelectedUrun {
        void onSelectedUrun(int index);
    }

    @SuppressLint("SetTextI18n")
    @Override
    public void onBindViewHolder(@NonNull UrunlerViewHolder holder, int position) {
        UrunListe urunListe = urun.get(position);

        holder.urunAdi.setText(urunListe.getId()   " - "   urunListe.getUrunAdi());
        holder.urunTutar.setText( urunListe.getTutar());

    }


    @Override
        public int getItemCount() {
            return urunListeSize;
        }

        public class UrunlerViewHolder extends RecyclerView.ViewHolder{

            private TextView urunAdi,  urunTutar;
        private ImageView btnAdd;

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

            urunAdi = itemView.findViewById(R.id.urunAdi);
            urunTutar = itemView.findViewById(R.id.urunTutar);
            btnAdd = itemView.findViewById(R.id.btnAdd);

            btnAdd.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {

                    selectedUrun.onSelectedUrun(getLayoutPosition());
                }
            });

        }
    }
}
  

это categoriesAdapter

 public class CategoryAdapter extends RecyclerView.Adapter<CategoryAdapter.CategoryAdapterViewHolder> implements UrunAdapter.SelectedUrun  {

    private Context context ;
    private List<Categories> categoriesList;
    private  Categories categories;
    private List<UrunListe> urunListes = new ArrayList<>();

    private UrunAdapter rvUrunAdapter;
    private RestInterface restInterface = ServiceGenerator.createService(RestInterface.class);

    public CategoryAdapter(Context context, List<Categories> categoriesList) {
        this.context = context;
        this.categoriesList = categoriesList;
    }

    @NonNull
    @Override
    public CategoryAdapterViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {

        View view = LayoutInflater.from(context).inflate(R.layout.categories, parent, false);

        return new CategoryAdapterViewHolder(view);
    }

    private void createSubCategories(Context context1, int catId, int position){

        try {
            if (restInterface == null) {
                restInterface = ServiceGenerator.createService(RestInterface.class);
            }
        }catch (Exception e){
            Log.d("TAG apiCall", e.getMessage());
        }

        context=context1;

        String hash = "some hash";

        Call<UrunListe[]> call = restInterface.getUrunler(hash, catId);

        String url = call.request().url().toString();
        Log.i("TAG Kategoriler",url);
        call.enqueue(new Callback<UrunListe[]>() {

            @Override
            public void onResponse(Call<UrunListe[]> call, Response<UrunListe[]> response) {

                if (response.isSuccessful()){
                    urunListes = Arrays.asList(response.body());

                    Log.d("TAG apiCall", response.message());
                    Log.d("TAG apiCall", "OK ürünler");

                   // categories.setUrunListeList(urunListes);

                }
            }

            @Override
            public void onFailure(Call<UrunListe[]> call, Throwable t) {
                Log.d("TAG apiCall", "FAIL");
                Log.d("TAG apiCall", t.getMessage());
            }
        });

    }

    @Override
    public void onBindViewHolder(@NonNull CategoryAdapterViewHolder holder, int position) {

        categories = categoriesList.get(position);

        createSubCategories(context, categories.getId(), position);

        categories.setUrunListeList(urunListes);

        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(context);
        linearLayoutManager.setOrientation(RecyclerView.VERTICAL);
        holder.rvSubCategories.setLayoutManager(linearLayoutManager);
        holder.rvSubCategories.hasFixedSize();
        rvUrunAdapter = new UrunAdapter(context, categories.getUrunListeList(), this::onSelectedUrun, urunListes.size());

        holder.txtHeader.setText(categories.getCategoryName());
        holder.rvSubCategories.setAdapter(rvUrunAdapter);

        rvUrunAdapter.notifyDataSetChanged();

    }

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

    @Override
    public void onSelectedUrun(int index) {
        Toast.makeText(context, "Seçilen ürün "  urunListes.get(index).getId()    urunListes.get(index).getUrunAdi() , Toast.LENGTH_SHORT).show();
    }

    public class CategoryAdapterViewHolder extends RecyclerView.ViewHolder {

        private TextView txtHeader;
        private RecyclerView rvSubCategories;

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

            txtHeader = itemView.findViewById(R.id.txtHeader);
            rvSubCategories = itemView.findViewById(R.id.rvSubCategories);

        }
    }
}

  

класс модели

 public class UrunListe {

    @SerializedName("id")
    @Expose
    private int id;

    @SerializedName("parentCatId")
    @Expose
    private int parentCatId;

    @SerializedName("urunAdi")
    @Expose
    private String urunAdi ;

    @SerializedName("adet")
    @Expose
    private int adet;

    @SerializedName("ucret")
    @Expose
    private String tutar;

    @SerializedName("aktif")
    @Expose
    private int aktif;
}
  
 public class Categories {

    @SerializedName("id")
    @Expose
    private int id;

    @SerializedName("kategori_adi")
    @Expose
    private String categoryName;

    private List<UrunListe> urunListeList;
}


  
 @GET("getKategoriler")
    Call<Categories[]> getKategoriler(@Query(value = "hash",encoded = true) String hash );

    @GET("getUrunler")
    Call<UrunListe[]> getUrunler(@Query(value = "hash",encoded = true) String hash,
                                 @Query(value = "parentCatId",encoded = true) int parentCatId);
  

это asp.net серверная часть

 
 #region getUrunler
        [WebMethod]
        [ScriptMethod(ResponseFormat = ResponseFormat.Json)]
        public void getUrunler()
        {
            HttpContext context = HttpContext.Current;
            context.Response.Clear();
            context.Response.ClearHeaders();
            context.Response.ClearContent();
            context.Response.Cache.SetCacheability(HttpCacheability.NoCache);
            context.Response.ContentType = "application/json";
            context.Response.Charset = Encoding.UTF8.WebName;
            context.Response.ContentEncoding = Encoding.UTF8;
            context.Response.BinaryWrite(Encoding.UTF8.GetPreamble());

            try
            {
                string hash = null;
                hash = temizle(context.Request.QueryString["hash"]);

                string parentCatId = null;

                try
                {
                    parentCatId = temizle(context.Request.QueryString["parentCatId"]);
                }
                catch { }



                if (hash == "some hash")
                {

                    DbCon dbCon = new DbCon();

                    DataTable dt = null;

                    try
                    {
                        dt = dbCon.getDataTable("select * from urun_liste where aktif=1 and parentCatId ="   parentCatId);
                    }
                    catch
                    {
                        dt = dbCon.getDataTable("select * from urun_liste");
                    }

                  

                    JavaScriptSerializer jss = new JavaScriptSerializer(); jss.MaxJsonLength = 2147483644;
                    List<Dictionary<string, object>> rows = new List<Dictionary<string, object>>();
                    Dictionary<string, object> row;

                    foreach (DataRow dr in dt.Rows)
                    {
                        row = new Dictionary<string, object>();

                        foreach (DataColumn col in dt.Columns)
                        {

                            row.Add(col.ColumnName, dr[col].ToString());
                        }
                        rows.Add(row);
                    }


                    context.Response.Write(jss.Serialize(rows));
                    //return jss.Serialize(rowRoot);
                }
                else
                {

                    HttpContext.Current.Response.Write("Bilgileriniz kayit edildi. IP Adresiniz : "   KullaniciIP()   " Tekrari halinde hakkinizda yasal islem baslatilacaktir.");
                }
            }
            catch
            {

                HttpContext.Current.Response.Write("Bilgileriniz kayit edildi. IP Adresiniz : "   KullaniciIP()   " Tekrari halinde hakkinizda yasal islem baslatilacaktir.");
            }
        }
        #endregion

        #region getKategoriler
        [WebMethod]
        [ScriptMethod(ResponseFormat = ResponseFormat.Json)]
        public void getKategoriler()
        {
            HttpContext context = HttpContext.Current;
            context.Response.Clear();
            context.Response.ClearHeaders();
            context.Response.ClearContent();
            context.Response.Cache.SetCacheability(HttpCacheability.NoCache);
            context.Response.ContentType = "application/json";
            context.Response.Charset = Encoding.UTF8.WebName;
            context.Response.ContentEncoding = Encoding.UTF8;
            context.Response.BinaryWrite(Encoding.UTF8.GetPreamble());

            try
            {
                string hash = null;
                hash = temizle(context.Request.QueryString["hash"]);


                if (hash == "some hash")
                {

                    DbCon dbCon = new DbCon();

                    DataTable dt = null;

                    dt = dbCon.getDataTable("select * from kategoriler");

                    JavaScriptSerializer jss = new JavaScriptSerializer(); jss.MaxJsonLength = 2147483644;
                    List<Dictionary<string, object>> rows = new List<Dictionary<string, object>>();
                    Dictionary<string, object> row;

                    foreach (DataRow dr in dt.Rows)
                    {
                        row = new Dictionary<string, object>();

                        foreach (DataColumn col in dt.Columns)
                        {

                            row.Add(col.ColumnName, dr[col].ToString());
                        }
                        rows.Add(row);
                    }


                    context.Response.Write(jss.Serialize(rows));
                    //return jss.Serialize(rowRoot);
                }
                else
                {

                    HttpContext.Current.Response.Write("Bilgileriniz kayit edildi. IP Adresiniz : "   KullaniciIP()   " Tekrari halinde hakkinizda yasal islem baslatilacaktir.");
                }
            }
            catch
            {

                HttpContext.Current.Response.Write("Bilgileriniz kayit edildi. IP Adresiniz : "   KullaniciIP()   " Tekrari halinde hakkinizda yasal islem baslatilacaktir.");
            }
        }
        #endregion

  

Комментарии:

1. что значит элементы приходят с опозданием? вы сказали, что собираете элементы вместе

2. @ArvinRezaei, я успешно получаю данные, но при отладке if (response.isSuccessful()) они появляются после завершения recyclerview и добавляют только первый список. Я хочу добавить каждый список в свою категорию.

3. @ArvinRezaei я также добавил классы моделей

4. Опубликуйте свой модифицированный код и формат данных сервера.

5. @VSSChaitanyaChavali Я тоже их добавил

Ответ №1:

Firstly, You should change your UrunAdapter.getItemCount() для возврата urun.size() вместо urunListeSize . Синхронизировать будет легко.

Вам нужно вызвать notifyDataSetChanged() в обратном вызове. Вместо передачи categories.getId() просто передайте объект categories . Также вы должны передать адаптер элемента. Модификация, как только она извлекает данные, обновит categories.urunListeList и уведомит через адаптер, что набор данных изменился.

Код onBindViewHolder

 @Override
public void onBindViewHolder(@NonNull CategoryAdapterViewHolder holder, int position) {
    categories = categoriesList.get(position);

    categories.setUrunListeList(new ArrayList<UrunListe>());

    LinearLayoutManager linearLayoutManager = new LinearLayoutManager(context);
    linearLayoutManager.setOrientation(RecyclerView.VERTICAL);
    holder.rvSubCategories.setLayoutManager(linearLayoutManager);
    holder.rvSubCategories.hasFixedSize();
    rvUrunAdapter = new UrunAdapter(context, categories.getUrunListeList(), this::onSelectedUrun, urunListes.size());

    holder.txtHeader.setText(categories.getCategoryName());
    holder.rvSubCategories.setAdapter(rvUrunAdapter);

    //rvUrunAdapter.notifyDataSetChanged();
    //This is not required.

    createSubCategories(context, categories, rvUrunAdapter, position);

}
  

Соответствующим образом измените заголовок метода ‘createSubCategories’.

 private void createSubCategories(Context context1, Categories catId, UrunAdapter urunAdapter, int position)
  

Наконец, измените код onResponse. Здесь вы не должны присваивать результат обратного вызова categories.urunListeList. Вместо этого вы должны добавить.

 @Override

        public void onResponse(Call<UrunListe[]> call, Response<UrunListe[]> response) {

            if (response.isSuccessful()){
                 List<UrunListe> tempList = Arrays.asList(response.body());
                  //If you are planning to refresh this data, you should clear it first.
                urunListeList.clear();
                for(UrunListe urunListe:templist)                    
                    categories.urunListeList.add(urunListe);

                Log.d("TAG apiCall", response.message());
                Log.d("TAG apiCall", "OK ürünler");

               urunAdapter.notifyDataSetChanged();

            }
        }
  

Комментарии:

1. элементы не отображаются. В debug call.enqueue появляется после подключения адаптера. Почему он пропускает часть call.enqueue?

2. Call. enque() должно появиться после подключения адаптера. Если вы обновляете набор данных в onResponse методе, вы также должны вызывать notifyDataSetChanged только там. И для того, чтобы вызвать его, адаптер уже должен быть запущен и запущен. Установите точку останова в onResponse методе и проверьте, что происходит.

3. да, я пробовал с точкой останова. и после Call<UrunListe[]> call = restInterface.getUrunler(hash, catId); пропусков call.enqueue переходит в другую позицию категории. элементы приходят пустыми. Я имею в виду, что recyclerview пуст, но список заполнен элементами

4. Установите точку останова в операторе, который имеет Arrays.asList(response.body())

5. на стороне активности список становится пустым. а также адаптер urun не отвечает на контрольные точки