Фрагмент навигации с использованием списков массивов - PullRequest
0 голосов
/ 13 февраля 2020

Я сделал собственную реализацию навигации по фрагментам, используя списки массивов. Все работает отлично, я могу поддерживать историю навигации, используя это. Однако я не уверен, является ли это хорошей идеей или даже очень эффективной. Я надеялся, что кто-нибудь сможет 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;
...