#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 не отвечает на контрольные точки