我有一个活动,显示存储在数据库中的数据,这些数据存储在以片段形式组织的视图寻呼机中。
当适配器初始化View Pager时,它调用每个片段中的一个方法,将数据库条目的id传递给retrive并显示:
public Fragment getItem(int position) {
switch (position) {
case 0: // Fragment # 0 - This will show FirstFragment different title
firstFragment = Fragment.newInstance(1, "Page # 1");
firstFragment.setID(ctx, id);
return firstFragment;
case 1: // Fragment # 0 - This will show FirstFragment different title
secondFragment = Fragment.newInstance(1, "Page # 2");
secondFragment.setID(ctx, id);
return secondFragment;
case 2: // Fragment # 0 - This will show FirstFragment
thirdtFragment = Fragment.newInstance(1, "Page # 3");
thirdtFragment.setID(context, id);
return thirdtFragment;
default:
return null;
}
}
当调用片段的onCreateView方法时,它会从数据库中检索数据并初始化向用户显示数据的所有视图:
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
DataManager dataManager = new DataManager(mContext);
DataModel data = dataManager.getData(mID);
.....
所有似乎都工作正常,除非用户重新启动应用程序时,例如在此活动内部暂停:当活动重新启动时,我得到一个致命的错误访问数据,就好像包含片段的私有变量一样从垃圾收集器中删除数据的ID。
我的方法是否正确?如何防止活动重新启动时产生的错误?
答案 0 :(得分:1)
在onPause
期间onResume
片段和活动由android管理,因此您可能无法检索成员变量,以便在Fragment的newInstance
方法中克服此问题像
public static Fragment newInstance(int id, String page){
Bundle bundle = new Bundle();
bundle.putString("page", page);
bundle.putInt("ID", page);
setArguments(bundle);
}
并在onCreateView
回调中使用类似
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
int mID = getArguments().getInt("ID");
DataManager dataManager = new DataManager(mContext);
DataModel data = dataManager.getData(mID);
...
答案 1 :(得分:0)
所以,我通过以下方式解决了我的问题:
创建一个包含片段列表及其各自标题的视图寻呼机。此视图寻呼机适配器应具有将片段添加到列表的方法。这是我的代码:
public class ViewPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
private int mItemId;
public ViewPagerAdapter(FragmentManager manager, int id) {
super(manager);
mItemId = id;
}
@Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
@Override
public int getCount() {
return mFragmentList.size();
}
public void addFrag(Fragment fragment, String title) {
Bundle bundle = new Bundle();
bundle.putInt("itemId", mItemId);
fragment.setArguments(bundle);
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
@Override
public CharSequence getPageTitle(int position) {
return mFragmentTitleList.get(position);
}}
现在,在Fragment中,你可以提取额外的包,它可以帮助你从数据库中读取一些数据,例如,如果它是表列的id。这可能是你的片段类:
public class InfoFragment extends Fragment {
private Activity mActivity;
private CustomerDbObject customer;
private int customerId;
public InfoFragment() {
// Required empty public constructor
}
@Override
public void onAttach(Context ctx){
super.onAttach(ctx);
if (ctx instanceof Activity){
this.mActivity = (Activity) ctx;
}
customerId = getArguments().getInt("itemId");
Realm realm = Realm.getInstance(ctx);
RealmQuery<Customer> query = realm.where(Customer.class);
query = query.equalTo("account_id", customerId);
customer = query.findFirst();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.customer_fragment_info, container, false);
ButterKnife.bind(this, view);
return view;
}}
有了这两个部分,我们现在需要的是我们的活动,它将显示带有标签的viewpager!请记住,在同一个活动中,我们向viewpager实例提供额外的(itemId),然后viewpager将按顺序将其传递给片段。
public class CustomerActivity extends AppCompatActivity {
private int mSelectedCustomer = 5; //this value could be extracted for an intent that is passed from a Recyclerviewer etc
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_customer_details);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
final ViewPager mViewPager = (ViewPager) findViewById(R.id.viewPager);
setupViewPager(mViewPager);
TabLayout tabLayout = (TabLayout) findViewById(R.id.tab_layout);
tabLayout.setupWithViewPager(mViewPager);
tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
mViewPager.setCurrentItem(tab.getPosition());
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
}
private void setupViewPager(ViewPager viewPager) {
ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager(), mSelectedCustomer);
adapter.addFrag(new InfoFragment(), getString(R.string.info_tab));
}
}
现在我们将所有部分组合在一起,传递的重要额外(数据)应始终通过viewpager适配器提供给Fragment,后者从活动中获取它。
当我测试它时,它起作用了,我希望它对你也有效。请让我知道它是怎么回事!!