Condiciones: tengo una actividad y estoy creando PagerAdapter extends FragmentPagerAdapter con una clase Fragment. TabLayout incluye 10 pestañas. Tengo TabLayout.addOnTabSelectedListener y allí en onTabSelected() estoy actualizando algunas variables personalizadas en SharedPreferences de la aplicación que depende del nombre de la pestaña actual y el índice de la pestaña. Los nombres de las pestañas no son estáticos, también se cargan desde el servidor.
Mi tarea: con este valor, debo hacer una Call retrofit2 a mi servidor y cargar valores en el adaptador con recyclerview para mi Fragment .
Mi problema: estoy cargando los mismos datos para las diferentes pestañas, ¡que deberían contener datos diferentes! Entiendo que esto sucede porque en todos los casos tengo el mismo valor de la variable SharedPreferences , por lo que realizo una Call de retrofit con las mismas condiciones.
setOffscreenPageLimit() no se puede establecer en 0 ; el valor predeterminado es 1 según la documentación: https://developer.android.com/reference/kotlin/androidx/viewpager/widget/ViewPager#setoffscreenpagelimit;
setUserVisibleHint() en SO Encontré esto como una variante para resolver mi problema, pero no se puede anular porque ahora está obsoleto.
Solución: creo que debería guardar el nombre de la pestaña anterior y siguiente de alguna manera y luego puedo hacer diferentes Call de actualización paralelas con diferentes condiciones. Cuando se selecciona la pestaña, puedo obtener el nombre de la pestaña actual, anterior y siguiente. Pero, ¿cómo, dónde y cuándo debo hacer dos llamadas de actualización más?
UPD 08.02.2022: Sigo pensando en este problema.
Código:
AlgunaActividad.java
public class SomeActivity extends BaseActivity { private String TAG="SomeActivity"; private Context context; private TabLayout tabs; private ViewPager viewpager; private ProgressBar PBLoading; private PagerAdapter_SomePAdapter adapter; List<String> names = new ArrayList<>(); private String[] tabTitles; public String previousTabName; public String nextTabName; public int counterForPreviousTabName; public int counterForNextTabName; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_layout); context = getApplicationContext(); String categories = AppPreferences.getCategories(context); tabTitles = categories.split(";"); tabs = findViewById(R.id.tabs); viewpager = findViewById(R.id.viewpager); PBLoading = findViewById(R.id.PBLoading); tabs.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() { @Override public void onTabUnselected(TabLayout.Tab tab) { } @Override public void onTabReselected(TabLayout.Tab tab) { } @Override public void onTabSelected(TabLayout.Tab tab) { Log.d(TAG, "onTabSelected"); AppPreferences.setCurrentValueForRetrofit(getApplicationContext(), tab.getPosition()); counterForPreviousTabName = tmpTab.getPosition() - 1; counterForNextTabName = tmpTab.getPosition() + 1; //here I can get tab names. } }); adapter = new PagerAdapter_SomePAdapter(getSupportFragmentManager(), SomeActivity.this); viewpager.setAdapter(adapter); adapter.updateTitleData(tabTitles); tabs.setupWithViewPager(viewpager); adapter.notifyDataSetChanged(); } }PagerAdapter_AlgúnPAdapter.java:
public class PagerAdapter_SomePAdapter extends FragmentPagerAdapter { int PAGE_COUNT = 2; private String[] tabTitles = new String[] { "", ""}; private Context mContext; Fragment_fragment fragment_fragment; String TAG = "PagerAdapter_SomePAdapter"; public PagerAdapter_SomePAdapter(FragmentManager fm, Context context) { super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT); mContext = context; fragment_fragment = new Fragment_fragment(); } @Override public int getCount() { return PAGE_COUNT; } @Override public Fragment getItem(int position) { return fragment_fragment.newInstance(position + 1, tabTitles[position]); } @Override public CharSequence getPageTitle(int position) { return tabTitles[position]; } public void updateTitleData(String[] tabTitlesNew) { tabTitles = tabTitlesNew; PAGE_COUNT = tabTitlesNew.length; notifyDataSetChanged(); } }Fragmento_fragmento.java:
public class Fragment_fragment extends Fragment { private String TAG = "Fragment_fragment"; private static final String ARG_PAGE = "ARG_PAGE"; private int mPage; private View rootView; private RecyclerView RV; private Adapter_Items adapter; public static Fragment_fragment newInstance(int page, String tabName) { Bundle args = new Bundle(); args.putInt(ARG_PAGE, page); Fragment_fragment fragment = new Fragment_fragment(); fragment.setArguments(args); return fragment; } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (getArguments() != null) { mPage = getArguments().getInt(ARG_PAGE); } } @Override public void onAttach(@NonNull Context context) { super.onAttach(context); mContext=context; } @SuppressLint("ClickableViewAccessibility") @Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { rootView = inflater.inflate(R.layout.content_list, container, false); RV = rootView.findViewById(R.id.recycler_view); new loadDataAS().execute(); return rootView; } private void loadData(){ //retrofit call code; } class loadDataAS extends AsyncTask<Void, Void, Void> { final ProgressDialog progress = new ProgressDialog(mContext); @Override protected void onPreExecute() { super.onPreExecute(); } @Override protected Void doInBackground(Void... arg0) { loadData(); return null; } @Override protected void onPostExecute(Void result) { super.onPostExecute(result); adapter = new Adapter_Items(arguments, arguments2, arguments3); RV.setAdapter(adapter); adapter.notifyDataSetChanged(); } } }Adaptador_artículos:
public class Adapter_Items extends RecyclerView.Adapter<Adapter_Items.ViewHolder>{ private LayoutInflater mInflater; private Context mContext; private static String TAG = "Adapter_Items"; public Adapter_Items(List<Integer>arguments, List<String>arguments2, List<String>arguments3){ //initializing arguments } // inflates the row layout from xml when needed @NotNull @Override public ViewHolder onCreateViewHolder(@NotNull ViewGroup parent, int viewType) { View view = mInflater.inflate(R.layout.recycle_item, parent, false); return new ViewHolder(view); } @Override public void onBindViewHolder(@NonNull ViewHolder holder, int position) { //setting view's information } @Override public int getItemCount() { return arguments.size(); } public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { ViewHolder(View itemView) { super(itemView); itemView.setOnClickListener(this); } @Override public void onClick(View view) { } } }Lo primero,
el fragmento debe contener datos diferentes
Guardar el nombre de la pestaña después de la pestaña seleccionada no funcionará. Deberías quitar esto
AppPreferences.setCurrentValueForRetrofit(getApplicationContext(), tab.getPosition());Debe llamar al código de actualización dentro del fragmento con tabName (no de sharedPref) para obtener datos para esa pestaña.
Para ello, realice los siguientes cambios,
Ya está pasando tabName a la instancia de fragmento
newInstance(int page, String tabName)use ese tabName y pase a su AsyncTask -> loadData() como
loadData(tabName);Luego puede usar eso en su llamada de actualización y obtener los datos.
Nota:
setOffscreenPageLimit()Este método cargará fragmentos justo antes de que sean completamente visibles. Sería útil y una excelente experiencia para el usuario mostrar los datos directamente en lugar de obtenerlos solo cuando el usuario selecciona la pestaña.