在我的应用中,我有一个 Recyler 视图,里面有多个回收器视图。内部回收器视图是动态插入的。我遇到的问题是,某些内部回收器视图中的某些项目会转到其他内部回收器视图中,而这些内部不应该有任何项目,如下图所示。
顶部回收者视图不应该有那些项目,而底部是正确的。我注意到这些项目总是在同一个回收器视图上出现故障,在调试之后我还注意到在故障视图上,它甚至没有进入子适配器,这使得它变得更加奇怪。
我还应该提到,子回收器视图是根据 volley 请求插入的。我向 API 发出请求并生成项目。我也检查过,API 给出了正确的响应。
片段代码(调用主回收器视图的地方):
RequestQueue requestQueue;
String URL;
RecyclerView catList;
CategoriesMainRecycleAdapter adapter;
List<String> cats;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_categories, container, false);
catList = v.findViewById(R.id.crv_main_categories);
cats = new ArrayList<>();
URL = /*Removed this part for privacy reasons*/;
Submit();
// Inflate the layout for this fragment
return v;
}
private void Submit()
{
requestQueue = Volley.newRequestQueue(getActivity());
StringRequest stringRequest = new StringRequest(Request.Method.GET, URL, new Response.Listener<String>() {
@Override
public void onResponse(String response) {
try {
JSONArray jsonArray = new JSONArray(response);
for (int i = 0; i < jsonArray.length(); i++)
{
JSONObject cat = jsonArray.getJSONObject(i);
String a;
a = cat.getString("mCategoryName");
cats.add(a);
}
if (getActivity()!=null) {
adapter = new CategoriesMainRecycleAdapter(getActivity(), cats, (String) getText(R.string.website_link));
catList.setLayoutManager(new LinearLayoutManager(getActivity()));
catList.setAdapter(adapter);
}
} catch (JSONException e) {
Toast.makeText(getContext(), R.string.login_communication_error, Toast.LENGTH_LONG).show();
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(getActivity(), R.string.login_communication_error, Toast.LENGTH_SHORT).show();
error.printStackTrace();
}
});
requestQueue.add(stringRequest);
}
主回收器适配器代码(这是调用子适配器的地方):
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
holder.title.setText(capitalizeLetters(mCats.get(position)));
holder.viewAll.setImageResource(R.drawable.ic_baseline_arrow_forward_24_black);
holder.lbl_error.setText(R.string.no_anime_with_category_error);
holder.lbl_error.setVisibility(View.INVISIBLE);
holder.viewAll.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View v) {
v.startAnimation(AnimationUtils.loadAnimation(mContext, R.anim.image_click));
Intent i = new Intent(mContext, anime_category.class);
i.putExtra("Category", mCats.get(position));
mContext.startActivity(i);
}
}
);
//Start the other recycler views
URL = /*Removed for privacy reasons*/;
String data = "{"+
"\"mCategoryName\":" + "\"" + mCats.get(position) + "\"" +
"}";
Submit(data, holder);
}
private void Submit(String data, ViewHolder holder)
{
final String savedata= data;
requestQueue = Volley.newRequestQueue(Objects.requireNonNull(mContext));
StringRequest stringRequest = new StringRequest(Request.Method.POST, URL, new Response.Listener<String>() {
@Override
public void onResponse(String response) {
try {
holder.lbl_error.setVisibility(View.INVISIBLE);
List<anime_class> animes = new ArrayList<>();
JSONArray jsonArray = new JSONArray(response);
for (int i = 0; i < jsonArray.length(); i++)
{
JSONObject anime = jsonArray.getJSONObject(i);
anime_class a = new anime_class();
a.setmNameEN(anime.getString("mNameEN"));
a.setmNameJP(anime.getString("mNameJP"));
a.setmDescription(anime.getString("mDescription"));
a.setmThumbnail(anime.getString("mThumbnail"));
a.setmEpisodeCount(anime.getInt("mEpisodeCount"));
a.setmOnGoing(anime.getBoolean("mOnGoing"));
//Add Categories
List<String> cats = new ArrayList<>();
JSONArray catArray = anime.getJSONArray("mCategories");
for (int i2 = 0; i2 < catArray.length(); i2++)
{
cats.add(catArray.get(i2).toString());
}
a.setmCategories(cats);
animes.add(a);
}
if (mContext!=null) {
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(
holder.rcv.getContext(),
LinearLayoutManager.HORIZONTAL,
false
);
linearLayoutManager.setInitialPrefetchItemCount(animes.size());
CategoriesSubRecycleAdapter adapter = new CategoriesSubRecycleAdapter(mContext, animes);
holder.rcv.setLayoutManager(linearLayoutManager);
holder.rcv.setAdapter(adapter);
holder.rcv.setRecycledViewPool(catAnime);
}
} catch (JSONException e) {
Toast.makeText(mContext, R.string.login_communication_error, Toast.LENGTH_LONG).show();
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
if(error.networkResponse.statusCode == 404)
{
holder.lbl_error.setVisibility(View.VISIBLE);
}
else
Toast.makeText(mContext, R.string.login_communication_error, Toast.LENGTH_SHORT).show();
error.printStackTrace();
}
}) {
@Override
public String getBodyContentType() {
return "application/json; charset=utf-8";
}
@Override
public byte[] getBody() throws AuthFailureError {
return savedata == null ? null : savedata.getBytes(StandardCharsets.UTF_8);
}
};
requestQueue.add(stringRequest);
}
子回收器适配器(根据我所做的一些调试,这部分似乎工作正常):
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
holder.title.setText(capitalizeLetters(mAnime.get(position).getmNameEN()));
Glide.with(mContext).load(mAnime.get(position).getmThumbnail()).into(holder.thumbnail);
holder.crv_.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent i = new Intent(mContext, anime_page.class);
i.putExtra("mNameEN", mAnime.get(position).getmNameEN());
i.putExtra("mThumbnail", mAnime.get(position).getmThumbnail());
mContext.startActivity(i);
}
}
);
}
答案 0 :(得分:0)
我发现了一个解决问题的技巧,但我不认为它非常优化。在 Main Recycler Adapter 上,当我调用 Submit 方法从请求中获取数据时,在 onErrorResponse 上我添加了 0 个项目,方法是创建一个空列表并将其提供给适配器。
<p></p>