简体   繁体   中英

Get different data via Retrofit for the Fragment in FragmentPagerAdapter for the several tablayout tabs

Conditions: I have an Activity and I'm creating PagerAdapter extends FragmentPagerAdapter with one Fragment class. TabLayout includes 10 tabs. I have TabLayout.addOnTabSelectedListener and there in onTabSelected() I am updating some custom variable in app's SharedPreferences which depends on current tab name and tab index. Tab's names are not static - there are loading from server too.

My task: With this value I should make a retrofit2 Call to my server and load values in adapter with recyclerview for my Fragment .

My problem: I am loading the same data for the different tabs, which should contatin different data! I am understand that this happens because in all cases I have the same SharedPreferences variable's value so I am making retrofit Call with same conditions.

setOffscreenPageLimit() can't be setted to 0 - default is 1 according documentation: https://developer.android.com/reference/kotlin/androidx/viewpager/widget/ViewPager#setoffscreenpagelimit;

setUserVisibleHint() on SO I've found this like some variant for solving my problem, but it can't be overrided because is deprecated now.

Solution: I think I should save previous and next tab name in some way and then I can make different parallel retrofit Call s with different conditions. When tab selected I can get current, previous and next tab name. But how, where and when I should make two more retrofit calls?

UPD 08.02.2022: Still thinking about this problem.

Code:

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

}

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

Adapter_Items:

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) {
            
        }
    }

}

First thing,

fragment should contain different data

Saving tab name after tab selected will not work. You should remove this

AppPreferences.setCurrentValueForRetrofit(getApplicationContext(), 
tab.getPosition());

You should call retrofit code inside the fragment with the tabName (Not from sharedPref) to get data for that tab.

For this, make the following changes,

You are already passing the tabName to fragment instance

newInstance(int page, String tabName)

use that tabName and pass to your AsyncTask -> loadData() as

loadData(tabName);

Then you can use that in your retrofit call and get the data.

Note:

setOffscreenPageLimit()

This method will load fragments just before they are completely visible. It would be useful and a great user experience to display data directly rather than fetching only when user selects the tab.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM