Проблема с ViewPager + RecyclerView в Android

Привет, у меня есть Tablayout с Viewpager, и я использую Fragment для табуляции. Теперь в каждом фрагменте Tablayout у меня есть Recyclerview и отображаются элементы. Пожалуйста, посмотрите мой ответ json

http://pastebin.com/nUswad9s

здесь, в «typeMaster»: массив, у меня есть категории «typeName»: «Собаки», и я показываю имена типов в tablayout. У меня есть 4 tablayout, а внутри typemaster у меня есть подкатегории с именем «catMaster»: и я пытаюсь отобразить данные catmaster в recyclerview, но проблема в том, что в каждом фрагменте отображаются последние данные "catName": "Витамины и минералы",

Деятельность

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

Вывод, который я получаю прямо сейчас

введите описание изображения здесь

введите описание изображения здесь

введите описание изображения здесь

Как вы можете видеть, он показывает один и тот же результат «Витамины и минералы» на каждой вкладке. Я хочу разные подкатегории, а не одинаковые.


comment
Можем ли мы взглянуть на MyAdapter из вашего кода?   -  person Elvis Chweya    schedule 20.10.2016
comment
@ElvisChweya вот так, сэр   -  person albert    schedule 20.10.2016
comment
Я думаю, проблема в том, что вы передаете ArrayList как Serializable из Activity в Fragment, используя FragmentArgs, когда в Bundle этого нет.   -  person Elvis Chweya    schedule 20.10.2016
comment
о, тогда какое решение   -  person albert    schedule 20.10.2016
comment
Я отправляю ответ; Измените SubCategoryModel для реализации Parcelable и используйте bundle.putParcelableArrayList(key, list) и bundle.getParcelableArrayList(key)   -  person Elvis Chweya    schedule 20.10.2016
comment
любезно покажите, какой результат вы ожидаете в каждом случае   -  person Muhammed Refaat    schedule 22.10.2016
comment
я хочу показать listitem по категориям в recyclerview .. вы видели ответ json?   -  person albert    schedule 22.10.2016


Ответы (3)


Я вижу много проблем с вашим кодом, но давайте сделаем так, чтобы ваш пользовательский интерфейс отображал подкатегории, поскольку это ваша главная задача.

Измените 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<SubcategoryModel> 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 и получить правильную категорию (и подкатегории) для позиции создаваемого фрагмента.

Когда вы пишете код, вы думаете о том, что он должен делать. Однако в тот момент, когда вы запускаете код и обнаруживаете, что у вас есть проблема, вы должны забыть, что вы хотели, чтобы код делал, а затем притвориться, что вы компьютер, и запустить код в своей голове. Вы хотите понять, какой эффект имеет каждая строка кода. Когда вы делаете это таким образом, легче найти проблему.

person kris larson    schedule 23.10.2016
comment
можешь сказать одно?? в чем была ошибка - person albert; 24.10.2016

Проблема:

Невозможно передать Serializable ArrayList в Bundle. Посмотрите страницу документации здесь документы Bundle.

Решение:

Измените свой SubCategoryModel, чтобы реализовать Parcelable, а затем используйте bundle.putParcelableArrayList(key, list) и bundle.getParcelableArrayList(key), чтобы передать ArrayList в FragmentArgs и получить их из Fragment.

person Elvis Chweya    schedule 20.10.2016
comment
Братан, когда я изменяю его с помощью parcalable, как это реализует Parcelable.. он просит меня реализовать метод.. вы можете сказать, что делать - person albert; 20.10.2016
comment
Просто перейдите в «Настройки Android Studio», «Плагины» и установите генератор кода Android Parcelable от Michal Charmas. - person Elvis Chweya; 20.10.2016
comment
После установки вам нужно перезапустить Android Studio, а затем открыть класс, в котором вы хотите реализовать Parcelable. Затем просто нажмите ALT + Insert и выберите Parcelable и вуаля, теперь все просто. - person Elvis Chweya; 20.10.2016
comment
Давайте продолжим обсуждение в чате. - person albert; 20.10.2016

это основная логика вашего кода, я думаю... Попробуйте и дайте мне знать, если вам нужна дополнительная помощь или вы найдете ее полезной...

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

Примечание. Чтобы проанализировать данные для категории собак, я передал 0 позицию в переменной ThirdJsonobject. Пройдите 1 для кошек и 2 для лошадей, и вы найдете желаемый результат

Скриншоты: категория "Собаки"

Категория кошек

Категория лошадей

person Bhavnik    schedule 22.10.2016
comment
какие изменения мне нужно внести в FragmentStatePagerAdapter? - person albert; 24.10.2016
comment
Я просто создал 3 фрагмента с другим списком, или вы можете создать один фрагмент и передать другую модель в соответствии с положением вашего фрагмента. - person Bhavnik; 24.10.2016