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