【问题标题】:RecyclerView is loading twice product on click event in recyclerView in androidRecyclerView 在 android 的 recyclerView 中的点击事件上加载了两次产品
【发布时间】:2018-09-26 07:43:49
【问题描述】:

我已在片段中应用了 recyclerView,我在片段中展示了运行良好的 api 产品。当我单击产品并转到下一个片段时,我在 recyclerView 上执行了单击侦听器。但是当我转到上一个片段时,我的 recyclerView 会一次又一次地加载数据。我怎么能避免这种情况。我希望它加载一次数据。 这是我的代码 xml 代码:

<android.support.v7.widget.RecyclerView
    android:id="@+id/lsCategory"
    android:layout_width="wrap_content"
    android:layout_height="40dp"
    android:layout_marginLeft="2dp"
    android:layout_marginTop="4dp"
    android:layout_marginRight="2dp"
    android:background="@color/colorPrimary"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent" />

这是我的回收站查看代码:

 public class HomeFragment extends Fragment implements View.OnClickListener {
private List<Category> categories = new ArrayList<>();
    private CategoryAdapter categoryAdapter;

 public void getInfo(View view){
    lsCategory =  view.findViewById(R.id.lsCategory);
}
public void setInfo(){
    getData();
}
public void getData(){
    final StringRequest request = new StringRequest(Request.Method.GET, URLs.homeMainURL,
    new Response.Listener<String>() {
        @Override
        public void onResponse(String response) {
                //categories
                JSONArray categoryArray = jsonObject.getJSONArray("ListCategories");
                setCategoryAdapter(categoryArray);
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
    }, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
         error.printStackTrace();
        }
    });
    VolleySingleton.getInstance(context).addToRequestQueue(request);
}
private void setCategoryAdapter(JSONArray array) {

    try {
        for (int i = 0; i < array.length(); i++) {
            JSONObject object = array.getJSONObject(i);
            final String name = object.getString("Name");
            final int Id = object.getInt("ID");
            categories.add(new Category(Id, name));
        }

    }catch(JSONException e) {
        e.printStackTrace();
    }
    categoryAdapter = new CategoryAdapter(context, categories);
    lsCategory.setLayoutManager(new LinearLayoutManager(context,LinearLayoutManager.HORIZONTAL,false));
    lsCategory.setAdapter(categoryAdapter);
}

这是我的类别适配器

@Override
public void onBindViewHolder(@NonNull CategoryAdapter.ViewHolder holder, int position) {
    holder.setData(categories.get(position));
}
public class ViewHolder extends RecyclerView.ViewHolder {
    TextView textViewItemName;
    private int Id ;
    public ViewHolder(View itemView) {
        super(itemView);
        textViewItemName = itemView.findViewById(R.id.tvCategoris);
    }
    public void setData(final Category category){
        textViewItemName.setText(category.getCategoryName());
        Id = category.getId();

        textViewItemName.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ExpandableCategoryList fragment = new ExpandableCategoryList();
                Bundle bundle = new Bundle();
                bundle.putInt("Id",Id);
                fragment.setArguments(bundle);
                ((MainActivity)context).replaceFragment(fragment,
                        "TAG",null,false);
            }
        });
    }
}

【问题讨论】:

  • 可以添加以前的片段更改代码吗?
  • 在回收视图代码所在的位置显示您的完整片段代码!
  • 请您解释一下
  • 在 for 循环中设置 Adapter 可能会有所帮助?在那之后,adapter.notifydatachange(); 另外,add(new Category(Id, name)); 也可能会创建另一个项目。这是可疑的。
  • 显示完整的片段代码。你有共享回收视图代码。显示回收视图正在加载数据的片段的所有代码。

标签: android android-studio android-fragments android-recyclerview


【解决方案1】:

我希望这对你有用。

在将数据添加到其中之前清除您的数组列表,并在尝试捕获代码之前添加。如下所示并通知您的适配器。

  if(categories!=null){
        categories.clear();
     }

try {
       for (int i = 0; i < array.length(); i++) {
            JSONObject object = array.getJSONObject(i);
            final String name = object.getString("Name");
            final int Id = object.getInt("ID");
            categories.add(new Category(Id, name));
        }

    }catch(JSONException e) {
        e.printStackTrace();
    }
    categoryAdapter = new CategoryAdapter(context, categories);
    rvCategory.setLayoutManager(new 
    LinearLayoutManager(context,LinearLayoutManager.HORIZONTAL,false));
    rvCategory.setAdapter(categoryAdapter);
    categoryAdapter.notifyDataSetChanged();

【讨论】:

    【解决方案2】:

    使用fragmentTransaction.add(containerViewId, fragment, tag);而不是 fragmentTransaction.replace(containerViewId, fragment, tag);

    addreplace的区别是:

    replace 删除现有片段并添加新片段。这意味着当您按下返回按钮时,将创建被替换的片段并调用其 onCreateView。

    add 保留现有片段并添加一个新片段,这意味着现有片段将处于活动状态并且它们不会处于“暂停”状态,因此当按下后退按钮时不会调用 onCreateView现有片段(添加新片段之前存在的片段)。

    对于fragment的生命周期事件onPause、onResume、onCreateView等生命周期事件,replace时会调用,add时不会调用。

    【讨论】:

      【解决方案3】:

      这是大多数安卓开发者都面临的通病,可以通过以下方法解决。
      1. 首先,每次加载/调用此片段时,在向其添加数据之前清除 category 对象。
      例子。类别.清除();如果它是一个列表
      2. 在您的适配器中,将这个 setHasStableIds(true); 添加到构造函数中。它将停止复制列表中的数据。
      3. 覆盖适配器中的以下方法(IMP)

          @Override
          public int getItemViewType(int position) {
           return position;
          }
      
          @Override
          public long getItemId(int position){
              return position;
          }
          @Override
          public int getItemCount() {
              return category.size();
          }
      

      让我知道它是否有效!

      【讨论】:

      • 我想再问一件事,我是如何将主 Activity 放入缓存中的,这样我就无法加载 api 数据。只有它加载缓存数据
      • 如果您没有大量数据,那么使用共享首选项可能是一个不错的选择。您的数据将存储在缓存中,无需与服务器通信即可轻松获取
      • 我有大量数据
      • 在这种情况下,我认为你应该使用 SQLite,因为在共享首选项上存储大量数据并不是最好的主意(尽管它更容易)。
      【解决方案4】:

      有两种方式:

      第一:

      如果您使用的是替换,那么您也应该使用 addtobackstack(null) 方法。从下一个片段返回到上一个片段时,它不会再次调用上一个片段的 onCreate 方法。确保您在 onCreate 方法中调用 API。

      第二:

      尝试阅读片段中的 setRetain(True),也许它会帮助您停止再次加载片段 oncreate 方法。确保您在 onCreate 方法中调用 API。

      希望这会有所帮助。快乐编码:)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-01-30
        • 1970-01-01
        • 1970-01-01
        • 2018-04-06
        • 1970-01-01
        相关资源
        最近更新 更多