简体   繁体   English

通过 Retrofit 为 FragmentPagerAdapter 中的 Fragment 获取不同的数据,用于几个 tablayout 选项卡

[英]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.条件:我有一个 Activity,我正在创建PagerAdapter extends FragmentPagerAdapter with one Fragment class。TabLayout 包括 10 个选项卡。 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.我有TabLayout.addOnTabSelectedListener并且在onTabSelected()中我正在更新应用程序的SharedPreferences中的一些自定义变量,这取决于当前选项卡名称和选项卡索引。 Tab's names are not static - there are loading from server too.选项卡的名称不是 static - 也有从服务器加载。

My task: With this value I should make a retrofit2 Call to my server and load values in adapter with recyclerview for my Fragment .我的任务:有了这个值,我应该对我的服务器进行retrofit2 Call ,并使用 recyclerview 为我的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.我知道发生这种情况是因为在所有情况下我都具有相同的SharedPreferences变量值,所以我在相同条件下进行retrofit Call

setOffscreenPageLimit() can't be setted to 0 - default is 1 according documentation: https://developer.android.com/reference/kotlin/androidx/viewpager/widget/ViewPager#setoffscreenpagelimit; setOffscreenPageLimit()不能设置为0 - 根据文档默认为 1: 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. setUserVisibleHint() on SO 我发现这就像解决我的问题的一些变体,但它不能被覆盖,因为现在已被弃用。

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.解决方案:我想我应该以某种方式保存上一个和下一个选项卡名称,然后我可以在不同的条件下进行不同的并行 retrofit Call When tab selected I can get current, previous and next tab name.选择选项卡后,我可以获得当前、上一个和下一个选项卡名称。 But how, where and when I should make two more retrofit calls?但是,我应该如何、何时何地再拨打两个 retrofit 电话呢?

UPD 08.02.2022: Still thinking about this problem. UPD 08.02.2022:还在思考这个问题。

Code:代码:

SomeActivity.java 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: 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:片段_片段.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: 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.您应该使用 tabName(不是来自 sharedPref)调用片段内的 retrofit 代码以获取该选项卡的数据。

For this, make the following changes,为此,进行以下更改,

You are already passing the tabName to fragment instance您已经将 tabName 传递给片段实例

newInstance(int page, String tabName)

use that tabName and pass to your AsyncTask -> loadData() as使用该 tabName 并传递给您的 AsyncTask -> loadData() 作为

loadData(tabName);

Then you can use that in your retrofit call and get the data.然后您可以在 retrofit 调用中使用它并获取数据。

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.直接显示数据而不是仅在用户选择选项卡时才获取数据会很有用,并且会带来很好的用户体验。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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