[英]Pass data from Activity to Fragment of ViewPager via FragmentPagerAdapter
[英]Get different data via Retrofit for the Fragment in FragmentPagerAdapter for the several tablayout tabs
條件:我有一個 Activity,我正在創建PagerAdapter extends FragmentPagerAdapter
with one Fragment class。TabLayout 包括 10 個選項卡。 我有TabLayout.addOnTabSelectedListener
並且在onTabSelected()
中我正在更新應用程序的SharedPreferences
中的一些自定義變量,這取決於當前選項卡名稱和選項卡索引。 選項卡的名稱不是 static - 也有從服務器加載。
我的任務:有了這個值,我應該對我的服務器進行retrofit2
Call
,並使用 recyclerview 為我的Fragment
在適配器中加載值。
我的問題:我正在為不同的選項卡加載相同的數據,這些選項卡應該包含不同的數據! 我知道發生這種情況是因為在所有情況下我都具有相同的SharedPreferences
變量值,所以我在相同條件下進行retrofit
Call
。
setOffscreenPageLimit()
不能設置為0 - 根據文檔默認為 1: https://developer.android.com/reference/kotlin/androidx/viewpager/widget/ViewPager#setoffscreenpagelimit;
setUserVisibleHint()
on 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();
}
}
片段_片段.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) {
}
}
}
首先,
片段應包含不同的數據
選擇選項卡后保存選項卡名稱將不起作用。 你應該刪除這個
AppPreferences.setCurrentValueForRetrofit(getApplicationContext(),
tab.getPosition());
您應該使用 tabName(不是來自 sharedPref)調用片段內的 retrofit 代碼以獲取該選項卡的數據。
為此,進行以下更改,
您已經將 tabName 傳遞給片段實例
newInstance(int page, String tabName)
使用該 tabName 並傳遞給您的 AsyncTask -> loadData() 作為
loadData(tabName);
然后您可以在 retrofit 調用中使用它並獲取數據。
筆記:
setOffscreenPageLimit()
此方法將在片段完全可見之前加載片段。 直接顯示數據而不是僅在用戶選擇選項卡時才獲取數據會很有用,並且會帶來很好的用戶體驗。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.