android android-fragments android-recyclerview android-tablayout fragmentstatepageradapter

Problema ViewPager+RecyclerView en Android



android-fragments android-recyclerview (3)

Hola, tengo Tablayout con Viewpager y estoy usando Fragment para tablayout. Ahora, en cada fragmento de Tablayout, tengo una vista de Recyclerview y se muestran elementos. Por favor, vea esta respuesta de mi json

http://pastebin.com/nUswad9s

aquí en "typeMaster": matriz tengo categorías "typeName": "Perros", y estoy mostrando nombres de tipo en tablayout tengo 4 tablayout, y dentro de typemaster tengo subcategoreis llamado "catMaster": y estoy tratando de mostrar datos de catmaster en vista de reciclaje, pero el problema está en cada fragmento que muestra los últimos datos "catName": "Vitaminas y minerales",

Actividad

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

Fragmento

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

Salida que estoy obteniendo ahora

Como puede ver, muestra el mismo resultado "Vitaminas y minerales" en todas las pestañas ... Quiero diferentes subcategorías en lugar de las mismas.


Problema:

No hay forma de pasar una lista de ArrayList Serializable en un Bundle . Mira la página de documentos aquí Paquetes de documentos

Solución:

Cambie su SubCategoryModel para implementar Parcelable y luego use bundle.putParcelableArrayList(key, list) y bundle.getParcelableArrayList(key) para pasar ArrayList a FragmentArgs y obtenerlos del Fragment


Veo muchos problemas con su código, pero hagamos que su IU muestre las subcategorías, ya que esa es su principal preocupación.

Cambie el getItem en su adaptador a esto:

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

¿Qué causó el problema?

ArrayList<SubcategoryModel> subct en el ArrayList<SubcategoryModel> subct en su actividad:

Primero su código hizo esto:

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

Entonces, al final de este bucle, el subct se establece en las subcategorías de la última categoría en la filelist de filelist .

Después de eso, hizo otro ciclo para cargar las pestañas, pero usó una variable de subct diferente que se declaró dentro del ciclo y que no tuvo ningún efecto en el campo de subct de su actividad.

Luego creaste tu buscapersonas y adaptador.

En su adaptador de buscapersonas tenía esto:

@Override public Fragment getItem(int position) { Log.v("adapter", "getitem" + String.valueOf(position)+subct.size()); return FirstFragment.create(position,subct); }

Como subct se configuró en las subcategorías de la última categoría del ciclo anterior, cada fragmento creado estaba recibiendo esas subcategorías, sin importar para qué posición (categoría) fuera el fragmento. Todo lo que hice fue cambiar el código para volver a la filelist de filelist y obtener la categoría (y subcategorías) correctas para la posición del fragmento que se está creando.

Cuando escribe código, piensa en lo que quiere que haga el código. Sin embargo, en el punto en el que ejecuta el código y descubre que tiene un problema, debe olvidar lo que quería que hiciera el código, luego pretender que es la computadora y ejecutar el código en su cabeza. Desea comprender qué efecto tiene cada línea de código. Cuando lo haces así, es más fácil encontrar el problema.


esta es la lógica principal de su código, supongo ... Pruébelo y avíseme si necesita más ayuda o le resulta útil ...

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

Nota: Para analizar los datos de la categoría de perros, pasé la posición 0 en la variable thirdJsonobject. Pase 1 para gatos y 2 para caballo y encontrará la salida deseada

Capturas de pantalla: Categoría de perros

Categoría de gatos

Categoría de caballo