在多个标签中使用的一个片段

时间:2018-04-15 18:50:21

标签: android android-recyclerview android-viewpager

我从服务器收到一个(类别)列表,并使用SectionsPagerAdapter制作标签。我使用一个常见的片段,其中我有一个RecyclerView。用户登录后,我将类别存储在TempData.productCategories中且小于15.当用户选择选项卡时,我会使用所选类别的产品刷新RecyclerView。问题是,目前我有4个类别。只有第一个和最后一个有产品(每个类别下有一个产品)。显示没有产品的第一个选项卡可能是因为第二个选项卡为空,Android会在第一个选项卡之后自动加载第二个选项卡。我想看看第一类产品。谁能告诉我我做错了什么?

服务器获取我的商店ID,一个商店ID少于15个类别:

@Override
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {

    mViewPager.setCurrentItem(tab.getPosition());

    //doing after a delay otherwise activity is null
    final int position = tab.getPosition();
    Handler handler = new Handler();
    handler.postDelayed(new Runnable() {
        @Override
        public void run() {

            String cat  = TempData.productCategories.get(position).getName();

            Log.i("Temp", "pos: " + position + ", cat: " + cat);

            AnyItemFragment.updateList(cat, context);
        }
    }, 400);

}

以下是此功能中使用的其他方法:

public static void setupListForCategory(final Activity context, final RecyclerView listView, final String category) {
    List<ProductUserModel> prods = getProductsUser(category);

    if(prods.isEmpty()) return;

    setupList(context, listView, prods);
}

在这里我更新适配器:

private static void setupList(final Activity context, RecyclerView listView, List<ProductUserModel> prods){

    FastItemAdapter<ProductUserModel> p             = new FastItemAdapter<>();
    p.add(prods);
    p.withSelectable(true);
    p.withOnClickListener(new FastAdapter.OnClickListener<ProductUserModel>() {
        @Override
        public boolean onClick(final View v, final IAdapter<ProductUserModel> adapter, final ProductUserModel item, final int position) {
            PopupUtils.getUserInputQuantity(context, item, v);
            return false;
        }
    });

    //fill the recycler view
    Log.i("Temp", "updating list : " + prods.size());
    RecyclerView.LayoutManager layoutManager        = new LinearLayoutManager(context);
    listView.setLayoutManager(layoutManager);
    listView.setAdapter(p);
//        p.notifyAdapterDataSetChanged();
//        p.notifyDataSetChanged();
    listView.invalidate();
}


private static List<ProductUserModel> getProductsUser(String category) {
    List<ProductUserModel> pum                      = new ArrayList<>();

    for(int i = 0; i < TempData.productsUser.size(); i++){
        if(TempData.productsUser.get(i).getCategory().equals(category))
            pum.add(TempData.productsUser.get(i));
    }
    return pum;
}

活动中的部分寻呼机适配器:

private class SectionsPagerAdapter extends android.support.v13.app.FragmentPagerAdapter {

    SectionsPagerAdapter(android.app.FragmentManager fm) {
        super(fm);
    }

    @Override
    public android.app.Fragment getItem(int position) {
        return AnyItemFragment.newInstance(position-1);
    }

    @Override
    public int getCount() {
        // Show 3 total pages.
        return TempData.productCategories.size();
    }

    @Override
    public CharSequence getPageTitle(int position) {
//            switch (position) {
            return TempData.productCategories.get(position).getName();
//                case 0:
//                    return getString(R.string.toys);
//                case 1:
//                    return getString(R.string.stationaries);
//                case 2:
//                    return getString(R.string.books);
//            }
//            return null;
    }

    @Override
    public int getItemPosition(Object object) {
        return POSITION_NONE;
    }
}

更新:我的片段:

public class AnyItemFragment extends Fragment {

    static AnyItemFragment fragment;
    public static Activity context;
    private static String TAG                                  = "AllItemsFragment";


    int selectedPosition = 0;

    @BindView(R.id.listAll)
    RecyclerView listAll;

    private OnFragmentInteractionListener mListener;

    public AnyItemFragment() {
        // Required empty public constructor
    }


    public static AnyItemFragment newInstance(int categoryID) {
        fragment = new AnyItemFragment();

        fragment.selectedPosition = categoryID;
        Log.i(TAG, "sel pos: " + fragment.selectedPosition);

        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View view                                       = inflater.inflate(R.layout.fragment_inv_any_item, container, false);
        ButterKnife.bind(this, view);

        context = getActivity();

        return view;
    }

    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);

        if(!isVisibleToUser) return;
        String cat  = TempData.productCategories.get(fragment.selectedPosition).getName();

    }

    // TODO: Rename method, update argument and hook method into UI event
    public void onButtonPressed(Uri uri) {
        if (mListener != null) {
            mListener.onFragmentInteraction(uri);
        }
    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
    }

    @Override
    public void onDetach() {
        super.onDetach();
        mListener = null;
    }


    interface OnFragmentInteractionListener {
        // TODO: Update argument type and name
        void onFragmentInteraction(Uri uri);
    }


    public static void updateList(String cat, Activity context){

        TempData.setupListForCategory(context, fragment.listAll, cat);
    }
}

1 个答案:

答案 0 :(得分:1)

我认为对于初学者来说,你应该保持流程简单,不要有一个静态片段实例,你一直在调用刷新。

您的代码现在很难阅读和理解。

片段需要注意的一个基本事项是,因为它们已经可以与FragmentStatePagerAdapter一起重复使用,所以几乎不必处理让单个静态实例完成所有工作的麻烦。

我现在发现的问题很少,例如 - 您希望附加多个片段(与类别一样多),以便创建新实例并更新静态字段

public static AnyItemFragment newInstance(int categoryID) {
    fragment = new AnyItemFragment();

    fragment.selectedPosition = categoryID;
    Log.i(TAG, "sel pos: " + fragment.selectedPosition);

    return fragment;
}

现在正在发生的事情是,因为offscreenPageLimit上的默认ViewPager默认为1,所有更新都会转到片段的第二个实例,该实例很可能与类别相关联-2因此在第一个选项卡中没有任何渲染。

您可以通过添加调试断点来确认这一点。

您理想的做法是将类别发送到ViewPagerAdapter,并根据将产品型号列表设置为正确的片段的位置,以便知道如何渲染帖子。

private class SectionsPagerAdapter extends android.support.v13.app.FragmentPagerAdapter {

  private final Map<String, List<ProductUserModel>> mapOfCategoryAndProductUsers;    

  SectionsPagerAdapter(FragmentManager fm, Map<String, List<ProductUserModel>> mapOfCategoryAndProductUsers) {
      super(fm);
      this.mapOfCategoryAndProductUsers = mapOfCategoryAndProductUsers;
  }

  @Override
  public android.app.Fragment getItem(int position) {
      AnyItemFragment fragment = AnyItemFragment.newInstance(position-1);
      // Logic to map position to category...
      String category = TempData.productCategories.get(position)
      fragment.setProductUsers(mapOfCategoryAndProductUsers.get(category))
      return fragment;
  }

  @Override
  public int getCount() {
      // Show 3 total pages.
      return TempData.productCategories.size();
  }
  ...
  ...
}

然后在片段中有渲染逻辑 -

private List<ProductUserModel> productUsers;

public void setProductUsers(List<ProductUserModel> productUsers) {
    this.productUsers = productUsers;
}

@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    setupList()
}

private void setupList() {
  FastItemAdapter<ProductUserModel> p = new FastItemAdapter<>();
  p.add(prods);
  p.withSelectable(true);
  p.withOnClickListener(new FastAdapter.OnClickListener<ProductUserModel>() {
    @Override
    public boolean onClick(final View v, final IAdapter<ProductUserModel> adapter, final ProductUserModel item, final int position) {
        PopupUtils.getUserInputQuantity(context, item, v);
        return false;
    }
  });

  //fill the recycler view
  Log.i("Temp", "updating list : " + prods.size());
  LayoutManager layoutManager = new LinearLayoutManager(context);
  listView.setLayoutManager(layoutManager);
  listView.setAdapter(p);
}
PS:你应该尽量避免使用静态方法,因为它们会使单元测试成为一场噩梦。此外,如果您不事先测试您的代码,我建议您查看单元测试和Espresso进行仪器测试,以便更好地保证您的应用程序正常运行并避免回归蓝调。

如果这有帮助,或者您需要更多解释,请告诉我