【问题标题】:ViewPager + RecyclerView issue in androidandroid中的ViewPager + RecyclerView问题
【发布时间】:2017-03-02 03:15:07
【问题描述】:

嗨,我有 TablayoutViewpager,我正在使用 Fragment 进行标签布局。现在在每个 Tablayout 片段中,我都有 Recyclerview 并显示项目。请查看我的 json 响应

http://pastebin.com/nUswad9s

在“typeMaster”中:数组我有类别“typeName”:“Dogs”,我在 tablayout 中显示类型名我有 4 个 tablayout,在 typemaster 里面我有名为“catMaster”的子类别:我正在尝试显示recyclerview 中的 catmaster 数据,但问题出在每个片段中,它显示最后一个数据“catName”:“Vitamins & Minerals”,

活动

public class CategoriesActivity extends AppCompatActivity{

    private Header myview;
    private ArrayList<SubcategoryModel> subct;
    private ArrayList<CategoryModel> filelist;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.categoris_activity);


        filelist =  (ArrayList<CategoryModel>)getIntent().getSerializableExtra("categorylist");

        System.out.println("Category list size"+filelist.size());
        myview = (Header) findViewById(R.id.categorisactivity_headerView);
        myview.setActivity(this);
        TabLayout tabLayout = (TabLayout) findViewById(R.id.cat_tab_layout);

        for(int i = 0; i < filelist.size(); i++){


             subct=filelist.get(i).getItems();
            for(int j=0;j<subct.size();j++)
            {


            }
            System.out.println("SubCategory list size"+subct.size());
        }


        for(int i = 0; i < filelist.size(); i++){

            tabLayout.addTab(tabLayout.newTab().setText(filelist.get(i).getCategory_typename()));

            ArrayList<SubcategoryModel> subct=filelist.get(i).getItems();
            for(int j=0;j<subct.size();j++)
            {

            }

        }
        Bundle bundleObject = new Bundle();
        bundleObject.putSerializable("key", filelist);
        FirstFragment ff=new FirstFragment();
        ff.setArguments(bundleObject);
        tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);

        final ViewPager viewPager = (ViewPager) findViewById(R.id.categories_pager);


        CategoriesAdapter  mPagerAdapter = new CategoriesAdapter(getSupportFragmentManager(),tabLayout.getTabCount());
        viewPager.setAdapter(mPagerAdapter);
        viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
        tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
            @Override
            public void onTabSelected(TabLayout.Tab tab) {
                viewPager.setCurrentItem(tab.getPosition());

            }

            @Override
            public void onTabUnselected(TabLayout.Tab tab) {

            }

            @Override
            public void onTabReselected(TabLayout.Tab tab) {

            }
        });

    }



   public class CategoriesAdapter extends FragmentStatePagerAdapter {
        ArrayList<CategoryModel> catlist;
       int numoftabs;

        public CategoriesAdapter(FragmentManager fm, int numoftabs) {
            super(fm);
            this.numoftabs = numoftabs;
        }

        @Override
        public Fragment getItem(int position) {

            Log.v("adapter", "getitem" + String.valueOf(position)+subct.size());
            return FirstFragment.create(position,subct);
        }

        @Override
        public int getCount() {
            return numoftabs;
        }
    }



}

片段

public class FirstFragment extends Fragment {
    // Store instance variables
    public static final String ARG_PAGE = "page";
    private int mPageNumber;
    private Context mContext;
    private int Cimage;
    private ArrayList<SubcategoryModel> subcatlist;
    private RecyclerView rcylervw;
    private  ArrayList<CategoryModel> filelist;
     ArrayList<SubcategoryModel> subct;


    public static FirstFragment create(int pageNumber,ArrayList<SubcategoryModel> subct){
        FirstFragment fragment = new FirstFragment();
        Bundle args = new Bundle();
        args.putInt(ARG_PAGE, pageNumber);
        args.putSerializable("key", subct);
        fragment.setArguments(args);
        return fragment;
    }


    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mPageNumber = getArguments().getInt(ARG_PAGE);


        subct= (ArrayList<SubcategoryModel>) getArguments().getSerializable("key");
        System.out.println("Frag Category list size"+subct.size());

      /*  for(int i = 0; i < filelist.size(); i++){
            subct=filelist.get(i).getItems();
            for(int j=0;j<subct.size();j++)
            {

            }
            System.out.println("Frag SubCategory list size"+subct.size());
        }*/
        // image uri get uri of image that saved in directory of app
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        ViewGroup rootView = (ViewGroup) inflater
                .inflate(R.layout.test, container, false);


        rcylervw=(RecyclerView)rootView.findViewById(R.id.subcategory_recycler_view);
        rcylervw.setHasFixedSize(true);
        MyAdapter adapter = new MyAdapter(subct);
        rcylervw.setAdapter(adapter);

        LinearLayoutManager llm = new LinearLayoutManager(getActivity());
        rcylervw.setLayoutManager(llm);

        return rootView;
    }


// this method is not very important


}

我的适配器

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
    private ArrayList<SubcategoryModel> mDataset;



    public static class MyViewHolder extends RecyclerView.ViewHolder {

        public TextView mTextView;
        public MyViewHolder(View v) {
            super(v);
            mTextView = (TextView) v.findViewById(R.id.subcategory_text);
        }
    }

    // Provide a suitable constructor (depends on the kind of dataset)
    public MyAdapter(ArrayList<SubcategoryModel> myDataset) {
        mDataset = myDataset;
    }

    // Create new views (invoked by the layout manager)
    @Override
    public MyAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent,
                                                     int viewType) {
        // create a new view
        View v = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.list_item_subcategory, parent, false);
        // set the view's size, margins, paddings and layout parameters
        MyViewHolder vh = new MyViewHolder(v);
        return vh;
    }

    @Override
    public void onBindViewHolder(MyViewHolder holder, int position) {
        holder.mTextView.setText(mDataset.get(position).getSubCategory_name());
    }

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

我现在得到的输出

如您所见,它在每个选项卡中显示相同的结果“维生素和矿物质”..我想要不同的子类别而不是相同的。

【问题讨论】:

  • 我们可以看看你的代码中的MyAdapter吗?
  • @ElvisChweya 先生,你去吧
  • 我认为问题在于您使用 FragmentArgs 将 ArrayList 作为可序列化从 Activity 传递到 Fragment,而 Bundle 中没有相关规定
  • 哦,那么解决办法是什么
  • 我正在发布答案;更改SubCategoryModel 以实现Parcelable 并使用bundle.putParcelableArrayList(key, list)bundle.getParcelableArrayList(key)

标签: android android-fragments android-recyclerview android-tablayout fragmentstatepageradapter


【解决方案1】:

我发现您的代码存在很多问题,但让我们让您的 UI 显示子类别,因为这是您的主要关注点。

将适配器中的 getItem 更改为:

        @Override
        public Fragment getItem(int position) {

            ArrayList<SubcategoryModel> subcategories = filelist.get(position).getItems();
            Log.v("adapter", "getitem" + String.valueOf(position)+subcategories.size());
            return FirstFragment.create(position,subcategories);
        }

导致问题的原因:

让我们在你的活动中关注ArrayList&lt;SubcategoryModel&gt; subct

首先你的代码是这样做的:

    for(int i = 0; i < filelist.size(); i++){
        ArrayList<SubcategoryModel> subct=filelist.get(i).getItems();
        // for(int j=0;j<subct.size();j++) ...
    }

所以在这个循环的最后,subct 被设置为filelist 中最后一个类别的子类别。

之后,您执行了另一个循环来加载选项卡,但它使用了在循环内声明的不同 subct 变量,这对您的活动的 subct 字段没有影响。

然后您创建了视图寻呼机和适配器。

在您的寻呼机适配器中,您有这个:

    @Override
    public Fragment getItem(int position) {

        Log.v("adapter", "getitem" + String.valueOf(position)+subct.size());
        return FirstFragment.create(position,subct);
    }

由于subct 被设置为之前循环中的最后一个类别的子类别,因此创建的每个片段都接收这些子类别,无论片段用于哪个位置(类别)。我所做的只是更改代码以返回 filelist 并为正在创建的片段的位置获取正确的类别(和子类别)。

当您编写代码时,您会考虑您希望代码做什么。然而,当你运行代码并发现你有问题时,你必须忘记你想让代码做什么,然后假装你是计算机并在你的头脑中运行代码。您想了解每一行代码的作用。当你这样做时,更容易找到问题。

【讨论】:

  • 你能说一件事吗?出了什么问题
【解决方案2】:

我猜这是你代码的主要逻辑......试试看,如果你需要更多帮助或者你觉得它有帮助,请告诉我......

private void parseJsonData() {
    try {
        listDogs.clear();
        JSONArray jsonArray = new JSONArray(loadJSONFromAsset());
        JSONObject firstJsonobject = jsonArray.optJSONObject(0);
        JSONArray itemListJsonArray = firstJsonobject.optJSONArray("itemList");
        JSONObject secondJsonobject = itemListJsonArray.optJSONObject(0);
        JSONArray typeMasterArray = secondJsonobject.optJSONArray("typeMaster");
        JSONObject thirdJsonobject = typeMasterArray.optJSONObject(0);
        JSONArray catMasterArray = thirdJsonobject.optJSONArray("catMaster");
        for(int i=0; i<catMasterArray.length(); i++) {
            JSONObject jsonObject = catMasterArray.optJSONObject(i);
            ModelClass modelClass = new ModelClass();
            modelClass.setTypeId(jsonObject.optString("catID"));
            modelClass.setTypeName(jsonObject.optString("catName"));
            listDogs.add(modelClass);
        }
        RecyclerViewAdapter recyclerViewAdapter = new RecyclerViewAdapter(getActivity(), listDogs);
        recyclerView.setAdapter(recyclerViewAdapter);
    } catch (JSONException e) {
        e.printStackTrace();
    }
}

注意:为了解析狗类别的数据,我在变量 thirdJsonobject 中传递了 0 位置。通过 1 为猫和 2 为马,你会找到你想要的输出

截图: Dogs category

Cats category

Horse category

【讨论】:

  • 我需要在 FragmentStatePagerAdapter 中进行哪些更改?
  • 我只是创建了 3 个具有不同列表的片段,或者您可以创建单个片段并根据片段的位置传递不同的模型。
【解决方案3】:

问题:

没有办法在Bundle 中传递Serializable ArrayList。在这里查看文档页面Bundle docs

解决方案:

将您的SubCategoryModel 更改为实现Parcelable,然后使用bundle.putParcelableArrayList(key, list)bundle.getParcelableArrayList(key)ArrayList 传递给FragmentArgs 并从Fragment 获取它们

【讨论】:

  • 兄弟,当我用 Parcalable 更改它时,像这样实现 Parcelable..它要求我实现方法..你能告诉我该怎么做
  • 简单,进入 Android Studio Settings, Plugins 并安装 Michal Charmas 的 Android Parcelable 代码生成器
  • 安装后,我需要重启Android Studio,然后打开你要实现的Class Parcelable on。然后,只需按ALT + Insert 并选择Parcelable,现在就很容易了。
猜你喜欢
  • 2016-05-07
  • 1970-01-01
  • 2017-08-29
  • 2016-07-23
  • 2021-03-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多