ViewPager + RecyclerView issue in android
A

3

2

Hi I have Tablayout with Viewpager and i am using Fragment for tablayout. Now in every Tablayout fragments I have Recyclerview and displaying items.Please See this my json response

http://pastebin.com/nUswad9s

here in "typeMaster": array i have categories "typeName": "Dogs", and i am displaying typenames in tablayout i have 4 tablayout, and inside typemaster i have subcategoreis named "catMaster": and i am trying to display catmaster data in recyclerview,but the issue is in every fragment it shows last data "catName": "Vitamins & Minerals",

Activity

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;
        }
    }



}

Fragment

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


}

MyAdapter

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();
    }
}

Output i am getting right now

enter image description here

enter image description here

enter image description here

As you can see it shows same result "Vitamin & Minerals" in every tabs..i want different subcategories instead of same.

Aerosol answered 20/10, 2016 at 8:17 Comment(7)
Can we have a look at MyAdapter from your code?Countermarch
@ElvisChweya there you go sirAerosol
I think the problem is that you are passing an ArrayList as a Serializable from Activity to Fragment using the FragmentArgs, when there's no provision for that in BundleCountermarch
oh then what is the solutionAerosol
I'm posting an answer; Change the SubCategoryModel to implement Parcelable and use bundle.putParcelableArrayList(key, list) and bundle.getParcelableArrayList(key)Countermarch
kindly show what's the output you are expecting in each caseKearns
i want to show listitem as per category in recyclerview..did you see json response ?Aerosol
C
2

I see a lot of problems with your code, but let's get your UI displaying the subcategories since that's your main concern.

Change the getItem in your adapter to this:

        @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);
        }

What caused the problem:

Let's focus on ArrayList<SubcategoryModel> subct in your activity:

First your code did this:

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

So at the end of this loop subct is set the subcategories of the last category in filelist.

After that, you did another loop to load the tabs, but that used a different subct variable that was declared inside the loop, and that had no effect on the subct field of your activity.

Then you created your view pager and adapter.

In your pager adapter you had this:

    @Override
    public Fragment getItem(int position) {

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

Since subct was set to the last category's subcategories from the loop before, every single fragment created was receiving those subcategories, no matter what position (category) the fragment was for. All I did was change the code to go back to filelist and get the correct category (and subcategories) for the position of the fragment being created.

When you're writing code, you think about what you want the code to do. However, at the point where you run the code and discover you have a problem, you have to forget what you wanted the code to do, then pretend you're the computer and run the code in your head. You want to understand what effect every line of code is having. When you do it that way it's easier to find the problem.

Closure answered 23/10, 2016 at 1:58 Comment(1)
can you tell one thing?? what was the mistakeAerosol
C
0

Problem:

There's no way to pass a Serializable ArrayList in a Bundle. Look at the docs page here Bundle docs

Solution:

Change your SubCategoryModel to implement Parcelable and then use bundle.putParcelableArrayList(key, list) and bundle.getParcelableArrayList(key) to pass the ArrayList to the FragmentArgs and get them from the Fragment

Countermarch answered 20/10, 2016 at 8:37 Comment(4)
Bro when i change it with parcalable like this implements Parcelable..it asks me to implement method..can you tell what to doAerosol
Simple, go to Android Studio Settings, Plugins and install Android Parcelable code generator by Michal CharmasCountermarch
Once installed, I you need to restart Android Studio, then open the Class you want to implement Parcelable on. Then, just press ALT + Insert and select Parcelable and voila its easy now.Countermarch
Let us continue this discussion in chat.Aerosol
P
0

this is the main logic of your code I guess... Try it and let me know if you need more help or you find it helpful...

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();
    }
}

Note: To parse data for dogs category I've passed 0 position in variable thirdJsonobject. Pass 1 for cats and 2 for horse and you will find your desired output

Screenshots: Dogs category

Cats category

Horse category

Provitamin answered 22/10, 2016 at 11:33 Comment(2)
what changes do i need to make in FragmentStatePagerAdapter?Aerosol
I simply created 3 fragments with different list or you can create single fragment and pass different model according to position of your fragment.Provitamin

© 2022 - 2024 — McMap. All rights reserved.