Я сделал собственную реализацию навигации по фрагментам, используя списки массивов. Все работает отлично, я могу поддерживать историю навигации, используя это. Однако я не уверен, является ли это хорошей идеей или даже очень эффективной. Я надеялся, что кто-нибудь сможет go над этим кодом и дать мне какой-либо отзыв. Было бы очень полезно.
Все мои фрагменты расширяют базовый фрагмент. К какому массиву должен быть добавлен фрагмент, основано на отдельных тегах, которые я храню в своем классе констант.
Также репо git, если кому-то нужен полный код: https://github.com/aztek6699/NavigationComponents/tree/master
Основная активность:
public class MainActivity extends AppCompatActivity {
public final int mContainerId = R.id.frame_container;
ActivityMainBinding binding;
private MyFragmentNavigation fragmentNavigation;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
fragmentNavigation = new MyFragmentNavigation(getSupportFragmentManager(), mContainerId);
initBottomViewNavigation();
}
public MyFragmentNavigation getFragmentNavigation() {
return fragmentNavigation;
}
private void initBottomViewNavigation () {
Bundle b = new Bundle();
b.putInt(Constants.TAG_KEY, Constants.HOME_TAG);
HomeFragment newFragment = new HomeFragment();
newFragment.setArguments(b);
fragmentNavigation.gotoNewFragment(Constants.HOME_TAG, newFragment);
binding.navigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
if (menuItem.getItemId() == R.id.navigation_home) {
if(fragmentNavigation.getNavigationCount(Constants.HOME_TAG) > 0) {
fragmentNavigation.gotoFragment(Constants.HOME_TAG);
}
return true;
} else if (menuItem.getItemId() == R.id.navigation_list) {
if(fragmentNavigation.getNavigationCount(Constants.LIST_TAG) > 0) {
fragmentNavigation.gotoFragment(Constants.LIST_TAG);
} else {
Bundle b = new Bundle();
b.putInt(Constants.TAG_KEY, Constants.LIST_TAG);
ListFragment newFragment = new ListFragment();
newFragment.setArguments(b);
fragmentNavigation.gotoNewFragment(Constants.LIST_TAG, newFragment);
}
return true;
} else if (menuItem.getItemId() == R.id.navigation_random) {
if(fragmentNavigation.getNavigationCount(Constants.RANDOM_TAG) > 0) {
fragmentNavigation.gotoFragment(Constants.RANDOM_TAG);
} else {
Bundle b = new Bundle();
b.putInt(Constants.TAG_KEY, Constants.RANDOM_TAG);
RandomFragment newFragment = new RandomFragment();
newFragment.setArguments(b);
fragmentNavigation.gotoNewFragment(Constants.RANDOM_TAG, newFragment);
}
return true;
} else if (menuItem.getItemId() == R.id.navigation_options) {
if(fragmentNavigation.getNavigationCount(Constants.OPTIONS_TAG) > 0) {
fragmentNavigation.gotoFragment(Constants.OPTIONS_TAG);
} else {
Bundle b = new Bundle();
b.putInt(Constants.TAG_KEY, Constants.OPTIONS_TAG);
OptionsFragment newFragment = new OptionsFragment();
newFragment.setArguments(b);
fragmentNavigation.gotoNewFragment(Constants.OPTIONS_TAG, newFragment);
}
return true;
} else {
return false;
}
}
});
}
public void showBackButton() {
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);
}
public void hideBackButton() {
getSupportActionBar().setDisplayHomeAsUpEnabled(false);
getSupportActionBar().setDisplayShowHomeEnabled(false);
}
@Override
public void onBackPressed()
{
if(fragmentNavigation.getNavigationCount(Constants.HOME_TAG) < 2 &&
fragmentNavigation.getNavigationCount(Constants.LIST_TAG) < 2 &&
fragmentNavigation.getNavigationCount(Constants.RANDOM_TAG) < 2 &&
fragmentNavigation.getNavigationCount(Constants.OPTIONS_TAG) < 2) {
super.onBackPressed();
} else {
BaseFragment fragment = (BaseFragment) getSupportFragmentManager().getFragments().get(0);
if(fragmentNavigation.getNavigationCount(fragment.getFragmentTag()) > 1) {
fragmentNavigation.goBack(fragment.getFragmentTag());
}
}
}
}
MyFragmentNavigation:
public class MyFragmentNavigation {
private ArrayList<BaseFragment> homeNavigation = new ArrayList<>();
private ArrayList<BaseFragment> listNavigation = new ArrayList<>();
private ArrayList<BaseFragment> randomNavigation = new ArrayList<>();
private ArrayList<BaseFragment> optionsNavigation = new ArrayList<>();
private FragmentManager mFragmentManager;
private int mContainerId;
public MyFragmentNavigation(FragmentManager fragmentManager, int containerId) {
mFragmentManager = fragmentManager;
mContainerId = containerId;
}
public void gotoNewFragment(int tag, BaseFragment fragment) {
switch (tag) {
case Constants.HOME_TAG:
homeNavigation.add(fragment);
break;
case Constants.LIST_TAG:
listNavigation.add(fragment);
break;
case Constants.RANDOM_TAG:
randomNavigation.add(fragment);
break;
case Constants.OPTIONS_TAG:
optionsNavigation.add(fragment);
break;
}
gotoFragment(tag);
}
public int getNavigationCount(int tag) {
switch (tag) {
case 0:
return homeNavigation.size();
case 1:
return listNavigation.size();
case 2:
return randomNavigation.size();
case 3:
return optionsNavigation.size();
}
return -1;
}
public void goBack(int tag) {
switch (tag) {
case Constants.HOME_TAG:
homeNavigation.remove(getLastFragment(tag));
break;
case Constants.LIST_TAG:
listNavigation.remove(getLastFragment(tag));
break;
case Constants.RANDOM_TAG:
randomNavigation.remove(getLastFragment(tag));
break;
case Constants.OPTIONS_TAG:
optionsNavigation.remove(getLastFragment(tag));
break;
}
gotoFragment(tag);
}
public void gotoFragment(int tag) {
FragmentTransaction ft = mFragmentManager.beginTransaction();
ft.replace(mContainerId, getLastFragment(tag));
ft.commit();
}
public BaseFragment getLastFragment(int tag) {
switch (tag) {
case 0:
return homeNavigation.get(homeNavigation.size() - 1);
case 1:
return listNavigation.get(listNavigation.size() - 1);
case 2:
return randomNavigation.get(randomNavigation.size() - 1);
case 3:
return optionsNavigation.get(optionsNavigation.size() - 1);
}
return null;
}
}
BaseFragment:
public abstract class BaseFragment extends Fragment {
private int tag = -1;
@Override
public void onAttach(@NonNull Context context) {
super.onAttach(context);
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
tag = getArguments().getInt(Constants.TAG_KEY);
}
public int getFragmentTag() {
return tag;
}
int getNavigationCount() {
return ((MainActivity) getActivity()).getFragmentNavigation().getNavigationCount(tag);
}
@Override
public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
if(((MainActivity) getActivity()).getFragmentNavigation().getNavigationCount(tag) > 1) {
((MainActivity) getActivity()).showBackButton();
} else {
((MainActivity) getActivity()).hideBackButton();
}
}
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
Log.d("homebutton", "onOptionsItemSelected: " + tag);
if(item.getItemId() == android.R.id.home) {
((MainActivity) getActivity()).getFragmentNavigation().goBack(tag);
}
return super.onOptionsItemSelected(item);
}
}
Константы:
public static final String TAG_KEY = "this_is_the_tag_key";
public static final int HOME_TAG = 0;
public static final int LIST_TAG = 1;
public static final int RANDOM_TAG = 2;
public static final int OPTIONS_TAG = 3;