Проблема ViewPager + RecyclerView в android
Привет У меня есть Tablayout
с Viewpager
, и я использую Fragment
для tablayout. Теперь в каждом фрагменте Tablayout у меня есть Recyclerview
и отображение элементов. Пожалуйста, смотрите мой ответ json
http://pastebin.com/nUswad9s
здесь, в "typeMaster": array у меня есть категории "typeName": "Dogs", и я показываю имена типов в tablayout, у меня есть 4 tablayout, а внутри typemaster у меня есть subcategoreis с именем "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
}
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 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();
}
}
Выход я получаю прямо сейчас
![введите описание изображения здесь]()
![введите описание изображения здесь]()
![введите описание изображения здесь]()
Как вы можете видеть, он показывает тот же результат "Витамин и минералы" на всех вкладках. Я хочу, чтобы разные подкатегории вместо них были.
Ответы
Ответ 1
Я вижу много проблем с вашим кодом, но пусть ваш пользовательский интерфейс отобразит подкатегории, так как это ваша главная проблема.
Измените 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
и получить правильную категорию (и подкатегории) для позиции создаваемого фрагмента.
Когда вы пишете код, вы думаете о том, что вы хотите сделать. Однако в тот момент, когда вы запускаете код и обнаруживаете, что у вас есть проблема, вы должны забыть, что вам нужно, чтобы сделать код, а затем притвориться, что вы компьютер, и запустите код в своей голове. Вы хотите понять, какое влияние оказывает каждая строка кода. Когда вы это делаете, легче найти проблему.
Ответ 2
Проблема:
Невозможно передать Serializable
ArrayList
в Bundle
. Посмотрите на страницу документов здесь Документы пакета
Решение:
Измените SubCategoryModel
, чтобы реализовать Parcelable
, а затем используйте bundle.putParcelableArrayList(key, list)
и bundle.getParcelableArrayList(key)
, чтобы передать ArrayList
в FragmentArgs
и получить их из Fragment
Ответ 3
Это основная логика вашего кода, я думаю... Попробуйте и дайте мне знать, если вам нужна дополнительная помощь или вы сочтете это полезным...
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 для лошади, и вы найдете нужный результат
Скриншоты:
категория для собак
Категория кошек
категория лошадей