通过Retrofit获取FragmentPagerAdapter中多个TabLayout选项卡的不同数据。

5

条件: 我有一个Activity并使用一个Fragment类创建PagerAdapter extends FragmentPagerAdapter。TabLayout包含10个选项卡。我使用TabLayout.addOnTabSelectedListener,在其中的onTabSelected()方法中,我会根据当前选项卡名称和选项卡索引更新应用程序的SharedPreferences中的一些自定义变量。选项卡名称不是静态的 - 它们也是从服务器加载的。

我的任务: 使用这个值,我应该向我的服务器进行retrofit2 Call,并在带有recyclerview的适配器中为我的Fragment加载值。

我的问题: 我为不同的选项卡加载相同的数据,但它们应该包含不同的数据!我知道这是因为在所有情况下,我都有相同的SharedPreferences变量值,因此我正在使用相同的条件进行retrofit Call

setOffscreenPageLimit()不能被设置为0 - 根据文档,默认值为1: https://developer.android.com/reference/kotlin/androidx/viewpager/widget/ViewPager#setoffscreenpagelimit;

setUserVisibleHint() 我在SO上发现这是解决我的问题的某种变体,但它现在已经被弃用,不能重写。

解决方案: 我认为我应该以某种方式保存前一个和下一个选项卡名称,然后我可以使用不同的条件进行不同的并行retrofit Call。当选择选项卡时,我可以获取当前选项卡、上一个选项卡和下一个选项卡的名称。但是,我应该在何时何地进行两个以上的retrofit调用呢?

UPD 08.02.2022: 仍在思考此问题。

代码:

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

适配器项:

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

}
1个回答

0

首先,

片段应包含不同的数据

在选定选项卡后保存选项卡名称将无效。您应该删除此内容。

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

你应该在片段中使用选项卡名称(而不是从 sharedPref 中)调用 Retrofit 代码以获取该选项卡的数据。

为此,请进行以下更改:

您已经将选项卡名称传递给片段实例。

newInstance(int page, String tabName)

使用该tabName并将其传递给您的AsyncTask -> loadData()函数

loadData(tabName);

然后您可以在Retrofit调用中使用它并获取数据。

注意:

setOffscreenPageLimit()

该方法将在片段完全可见之前加载它们。直接显示数据而不仅在用户选择选项卡时提取数据,这对于提高用户体验非常有用。

现在我明白了,也许你是对的,但我的代码和这个解决方案都有很多“但是”。我改变了viewpager解决方案的所有逻辑,现在它可以工作了。稍后我会写一篇文章介绍它。 - danyapd

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接