android - 以有效的方式管理 android 片段创建?
问题描述
我有一个ViewPager
里面有 4 个标签fragments
。以前在应用程序启动时,fragments
默认情况下它只是先加载两个。有道理,但问题是每次我导航到第 4 个选项卡并返回第一个选项卡时,都必须重新创建它。为了让我fragments
只创建一次,我使用了这种方法:
mViewPager.setOffscreenPageLimit(3);
所以现在之前的问题已经解决了,我可以浏览所有内容,fragments
而无需再次创建它们。但是新的问题是,随着应用程序的启动,所有的fragments
东西都是一次创建的。由于我在每个中都有网络调用,fragment
因此会发生多个网络调用,这可能会导致问题(根据我的应用程序设计,这也不合逻辑)。现在我需要找到解决问题的方法。帮助表示赞赏。
编辑:
viewPager.addOnPageChangeListener()
正如@Ferran 提供的那样,一种解决方案是在其中使用和放置网络调用。听起来不错!但我面临另一个问题。当在fragment
中选择 a 时onPageSelected(int position)
,它的所有视图字段都是空的,尽管我已经在onCreateView()
方法中定义了它们(因为所有这些fragments
都是在应用程序启动时创建的,这些视图字段不应该为空)并且我无法处理网络调用结果并设置视图中的数据。我得到fragments
这个代码:
Fragment fragment = adapter.getItem(position);
请注意,fragment
对象本身不为空。
这是我使用的典型片段:
公共类 TabFragmentPayment 扩展 Fragment 实现 View.OnClickListener {
private LinearLayout llError, llLoading, llNoItem;
private LinearLayout llPaymentRecords, llImageUpload;
private Button btnTryAgain; //here it just works for transaction get.
private RecyclerView rcv;
private ImageView ivPic, ivNationalCardPreview, ivSelect, ivAddAccount;
private TextView tvUploadPic, tvRequestPayment, tvNationalCardMessage;
private Spinner spBankAccounts;
private View view;
private ArrayList<Transaction> paymentRecordList = new ArrayList<>();
private ArrayList<Bank> bankList = new ArrayList<>();
private long minToPay = -1;
public static boolean checkAccounts = false;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_payment, null);
setWidgetReferences();
setClickListeners();
setupActivity();
return view;
}
private void setWidgetReferences() {
ivPic = view.findViewById(R.id.ivfpPic);
ivSelect = view.findViewById(R.id.ivfpSelect);
ivAddAccount = view.findViewById(R.id.ivfpAddAccount);
tvUploadPic = view.findViewById(R.id.tvfpUpload);
tvRequestPayment = view.findViewById(R.id.tvfpRequestPayment);
spBankAccounts = view.findViewById(R.id.spfpSelectAccount);
llError = view.findViewById(R.id.llError);
llLoading = view.findViewById(R.id.llLoading);
llNoItem = view.findViewById(R.id.llNoItem);
btnTryAgain = view.findViewById(R.id.btnReload);
rcv = view.findViewById(R.id.rcvfpTransactions);
ivNationalCardPreview = view.findViewById(R.id.ivfpNationalCardPreview);
tvNationalCardMessage = view.findViewById(R.id.tvfpNationalCardMessage);
llPaymentRecords = view.findViewById(R.id.llfpPayment);
llImageUpload = view.findViewById(R.id.llfpImageUpload);
}
private void setClickListeners() {
ivSelect.setOnClickListener(this);
ivPic.setOnClickListener(this);
ivAddAccount.setOnClickListener(this);
tvUploadPic.setOnClickListener(this);
tvRequestPayment.setOnClickListener(this);
btnTryAgain.setOnClickListener(this);
}
}
这是我尝试在 parent 中获取片段的方法Activity
:
@Override
public void onPageSelected(int position) {
Fragment fragment = adapter.getItem(position);
if (fragment instanceof TabFragmentPayment) {
TabFragmentPayment fr = (TabFragmentPayment) fragment;
}
}
名为 fr 的结果片段有空视图字段,这对我来说很奇怪。
解决方案
第一。
setOffscreenPageLimit(4)
告诉适配器在创建第一个页面时再创建 4 个页面。因此,您可以浏览 5 个页面而无需重新加载。在你的情况下,我认为没有必要使用它。
为确保您的网络调用不会在每次创建时被调用,您可以这样做
将您的网络调用放在每个片段的单独方法中并将其公开。
然后用这个
viewPager.setAdapter(adapter);
viewPager.setOffscreenPageLimit(4);
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int i, float v, int i1) {
}
@Override
public void onPageSelected(int i) {
// here you can call tour public fragment method
// i = page index
Fragment page = getSupportFragmentManager().findFragmentByTag("android:switcher:" + R.id.viewpager + ":" + viewPager.getCurrentItem());
// replace R.id.viewpager with your viewpager id
// then call your public method
((YourFragmentClass)page).your_public_method();
}
@Override
public void onPageScrollStateChanged(int i) {
}
});
第一次,onPageSelected
没有被触发,因为没有选择页面,只是创建了页面,但是onPageScrolled
确实如此。因此,请使用这两种方法来调用您的片段方法。
推荐阅读
- c++ - 如何在运行时检查方法签名
- python-3.x - RASA 聊天机器人框架在训练时出错:fit() 为关键字参数“batch_size”获得了多个值
- elasticsearch-5 - Elassandra 搜索复制数据
- r - 如何使用列名更改表的值
- javascript - Angular 7 Universal:不渲染内部组件
- python - 使用flask爬取图片和美汤过程不退出
- javascript - 将 Creative Tim 的 Material Kit Pro React 前端与 React-Redux-Firebase 生成器后端集成
- jmeter - 如何在jmeter中获取当前失败url的父url?
- python-3.x - FileNotFoundError:[Errno 2] 没有这样的文件或目录:'synonyms.yaml'
- java - Android 富文本 Mark Down