У меня проблемы, и я не знаю, как это исправить.
Все работает хорошо и должным образом, но если приложение было в стеке, а ОС требовались ресурсы, это убивает приложение, и я получаю проблему.
У меня есть одно действие с FAB, Tabs и ViewPager, которое содержит 2 фрагмента.
FAB зависит от того, какие текущие Tab вызывает методы Fragments, я использую интерфейс для него, а мои методы используют context во Fragments.
Схема активности
public class MyActivity extends AppCompatActivity {
private MyInterface mMyInterface;
private FloatingActionButton mFab;
private Toolbar mToolbar;
private DrawerLayout mDrawerLayout;
private NavigationView mNavigationView;
private ViewPager mViewPager;
private TabLayout mTabLayout;
private PagerAdapter mAdapter;
private FirstFragment mFirstFrg;
private SecondFragment mSecondFrg;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initToolbar();
initComponent();
}
private void initToolbar() {
mToolbar = (Toolbar) findViewById(R.id.toolbar);
mToolbar.setNavigationIcon(R.drawable.ic_menu);
setSupportActionBar(mToolbar);
getSupportActionBar().setTitle("My App");
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
private void initComponent() {
mDrawerLayout = (DrawerLayout)findViewById(R.id.drawer);
mNavigationView = (NavigationView) findViewById(R.id.navigation);
mViewPager = (ViewPager) findViewById(R.id.view_pager);
setupViewPager(mViewPager);
mTabLayout = (TabLayout) findViewById(R.id.tab_layout);
mTabLayout.setupWithViewPager(mViewPager);
mFirstFrg = (FirstFragment) mAdapter.getItem(0);
mSecondFrg = (SecondFragment) mAdapter.getItem(1);
mFab = (FloatingActionButton)findViewById(R.id.fab);
mNavigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(MenuItem item) {
if(item.getItemId() == R.id.drawer_one) {
showToast("Menu one");
}else{
showToast("Menu two");
}
item.setChecked(true);
mDrawerLayout.closeDrawers();
return true;
}
});
mViewPager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
@Override
public void onPageSelected(int position) {
changeFabIcon(position);
super.onPageSelected(position);
}
});
mFab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
switch (mViewPager.getCurrentItem()) {
case 0: {
showToast("Test!!!");
}
break;
}
case 1: {
if(mSecondFrg.getContext() == null){
showToast("context is Null!");
}
mMyInterface.doSomething();
break;
}
}
}
});
}
private void setupViewPager(ViewPager viewPager) {
FirstFragment firstFragment = new FirstFragment();
SecondFragment secondFragment = new SecondFragment();
this.mMyInterface = secondFragment;
mAdapter = new PagerAdapter(getSupportFragmentManager());
mAdapter.addFragment(firstFragment, "One");
mAdapter.addFragment(secondFragment, "Two");
viewPager.setAdapter(mAdapter);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if(item.getItemId() == android.R.id.home)
{
mDrawerLayout.openDrawer(GravityCompat.START);
return true;
}
return super.onOptionsItemSelected(item);
}
private void changeFabIcon(final int index) {
mFab.hide();
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
switch (index) {
case 0: {
mFab.setImageResource(R.drawable.ic_plus);
break;
}
case 1: {
mFab.setImageResource(R.drawable.ic_text);
break;
}
}
mFab.show();
}
}, 300);
}
private void showToast(String message){
Toast.makeText(this, message, Toast.LENGTH_LONG).show();
}}
Фрагмент второй схемы
public class SecondFragment extends Fragment implements MyInterface {
private RecyclerView mRecycler;
private Context mContext;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View fragmentView = inflater.inflate(R.layout.fragment_second, container, false);
mRecycler = (RecyclerView) placeView.findViewById(R.id.recycler);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(mContext);
linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
mRecycler.setLayoutManager(linearLayoutManager);
return fragmentView;
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
mContext = context;
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
private void getData(){// Some action and Update the UI
}
@Override
public void doSomething(){
getData();
}}
Проблема в том, что каждый раз, когда Система удаляет приложение в стеке, я получаю нулевые методы Context, а Fragment не работает :(
Я проверяю это там
if(mSecondFrg.getContext() == null){
showToast("context is Null!");
}
mMyInterface.doSomething();
Также мой код адаптера
public class PagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
public PagerAdapter(FragmentManager manager) {
super(manager);
}
@Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
@Override
public int getCount() {
return mFragmentList.size();
}
public void addFragment(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
@Override
public CharSequence getPageTitle(int position) {
return mFragmentTitleList.get(position);
}}
Спасибо за любые подсказки или помощь
Обновление и исправление
Я это исправил, проблема была в адаптере
Пожалуйста, прочитайте это из документации
Вызов метода startUpdate (ViewGroup) в PagerAdapter указывает, что содержимое ViewPager собирается измениться. Последуют один или несколько обращений к instantiateItem (ViewGroup, int) и / или destroyItem (ViewGroup, int, Object), и об окончании обновления будет сигнализироваться вызовом finishUpdate (ViewGroup).
я удалил весь код создания фрагмента в Activity и добавил это
mAdapter.startUpdate(mViewPager);
mFirstFrg = (FirstFragment) mAdapter.instantiateItem(mViewPager,0);
mSecondFrg = (SecondFragment) mAdapter.instantiateItem(mViewPager,1);
mAdapter.finishUpdate(mViewPager);
Обновление класса адаптера
public class PagerAdapter extends FragmentPagerAdapter {
public PagerAdapter(FragmentManager manager) {
super(manager);
}
@Override
public Fragment getItem(int position) {
if (position == 0) {
return new FirstFragment();
}else {
return new SecondFragment();
}
}
@Override
public int getCount() {
return 2;
}
@Override
public CharSequence getPageTitle(int position) {
if (position == 0){
return "One";
}else {
return "Two";
}
}
Также вы можете использовать FragmentStatePagerAdapter, вы можете прочитать об этом там Разница между FragmentPagerAdapter и FragmentStatePagerAdapter