具有多种不同片段类型的Android BaseFragment类

时间:2017-04-05 18:04:14

标签: java android android-fragments

我创建了一个基础片段类,用于处理设置工具栏标题,注册片段附加时间,设置菜单图标以及其他一些内容。我的问题是我决定使用PreferencesFragmentCompat作为我的设置片段,我无法扩展我的BaseFragment和androids PreferencesFragmentCompat。在这里使用接口无济于事,因为我的BaseFragment有很多功能,我不想将它复制到我的每个片段类中。通常要扩展两个类,你只需要在两个单独的文件中进行,但因为两个类已经延伸出Androids Fragment类,我不知道这是怎么回事。有没有更好的方法呢?

enter image description here

BaseFragment:

 public abstract class BaseFragment extends Fragment {

    protected View rootView;
    protected AppSettings settings;
    protected LayoutInflater inflater;

    public static void startFragment(Activity activity, BaseFragment newFragment) {
        FragmentManager fragManager = ((AppCompatActivity) activity).getSupportFragmentManager();
        BaseFragment currentFragment = (BaseFragment) fragManager.findFragmentById(R.id.fragment_container);

        // Start the transactions
        FragmentTransaction transaction = fragManager.beginTransaction();
        transaction.replace(R.id.fragment_container, newFragment);

        // If there is already a fragment then we want it on the backstack
        if (currentFragment != null) {
            transaction.addToBackStack(null);
        }

        // Show it
        transaction.commit();
    }

    @TargetApi(21)
    private void lockMode(boolean start) {
        if (android.os.Build.VERSION.SDK_INT >= 16) {
            if (start) {
                getActivity().startLockTask();
            } else {
                getActivity().stopLockTask();
            }
        }
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Get a reference to the app settings
        settings = AppSettings.getInstance(getActivity());

        // Don't want keyboard to stay open between fragments
        hideKeyboard();

        ActionBar actionBar = ((AppCompatActivity) getActivity()).getSupportActionBar();
        if (actionBar != null) {
            if (toolbarElevation()) {
                actionBar.setElevation(4 * getActivity().getResources().getDisplayMetrics().density);
            } else {
                actionBar.setElevation(0);
            }
        }

        setHasOptionsMenu(true);
    }

    @Override
    public void onResume() {
        super.onResume();

        // Set the title up
        Toolbar toolbar = (Toolbar) getActivity().findViewById(R.id.toolbar);
        toolbar.setTitle(getTitle());

        // Enable the home button in the action bar
        ((AppCompatActivity) getActivity()).getSupportActionBar().setDisplayShowHomeEnabled(true);

        // Change the home button icon for menu or back
        if (showUpNavigation()) {
            toolbar.setNavigationIcon(R.drawable.ic_navigation_back_white);
        } else {
            toolbar.setNavigationIcon(R.drawable.ic_menu_white);
        }

        if (isAppInLockTaskMode() == true && pinnedMode() == false) {
            lockMode(false);
        }

        setDrawerMenu();
    }

    public boolean getAuthRequired() {
        return true;
    }

    public boolean isBackAllowed() {
        return true;
    }

    public boolean toolbarElevation() {
        return true;
    }

    public String getTitle() {
        return "ISOPED";
    }

    public boolean pinnedMode() {
        return false;
    }

    public boolean showUpNavigation() {
        return false;
    }

    public void hideKeyboard() {
        InputMethodManager inputManager = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);

        // check if no view has focus:
        View v = getActivity().getCurrentFocus();
        if (v == null) {
            return;
        }

        inputManager.hideSoftInputFromWindow(v.getWindowToken(), 0);
    }

    public void setDrawerMenu() {
        NavigationView navigationView = (NavigationView) getActivity().findViewById(R.id.drawer_navigation);
        Integer menuID = null;
        Integer currentMenuId = null;

        if (settings.isType(AppSettings.TYPES.PERSONAL)) {
            menuID = R.menu.drawer_personal;
        } else if (settings.isType(AppSettings.TYPES.PROFESSIONAL)) {
            if (getAuthRequired() == true) {
                menuID = R.menu.drawer_professional_locked;
            } else {
                menuID = R.menu.drawer_professional_unlocked;
            }
        }

        if (menuID != null) {
            if (navigationView.getTag() != null) {
                currentMenuId = (Integer) navigationView.getTag();
            }

            if (currentMenuId == null || navigationView.getMenu().size() == 0 || currentMenuId != menuID) {
                navigationView.getMenu().clear();
                navigationView.inflateMenu(menuID);
                navigationView.setTag(Integer.valueOf(menuID));
            }
        }
    }

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        super.onCreateOptionsMenu(menu, inflater);
        menu.clear();

        if (settings.isType(AppSettings.TYPES.PROFESSIONAL) && pinnedMode() && false == isAppInLockTaskMode()) {
            inflater.inflate(R.menu.pin_menu, menu);
        }
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        DrawerLayout drawer = (DrawerLayout) getActivity().findViewById(R.id.drawer_layout);

        switch (item.getItemId()) {
            case android.R.id.home:
                if (showUpNavigation()) {
                    getActivity().onBackPressed();
                } else {
                    drawer.openDrawer(GravityCompat.START);
                }
                return true;
            case R.id.menu_pin:
                if (isAppInLockTaskMode()) {
                    PinDialog dialog = new PinDialog((AppCompatActivity) getActivity(), new NavigationCallback((AppCompatActivity) getActivity()) {
                        @Override
                        public void run() {
                            lockMode(false);
                        }
                    });
                    dialog.show();
                } else {
                    lockMode(true);
                }
                return true;
        }
        return super.onOptionsItemSelected(item);
    }

    private boolean isAppInLockTaskMode() {
        ActivityManager activityManager;

        activityManager = (ActivityManager)
                getActivity().getSystemService(Context.ACTIVITY_SERVICE);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            // For SDK version 23 and above.
            return activityManager.getLockTaskModeState()
                    != ActivityManager.LOCK_TASK_MODE_NONE;
        }

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            // When SDK version >= 21. This API is deprecated in 23.
            return activityManager.isInLockTaskMode();
        }

        return false;
    }
}

1 个答案:

答案 0 :(得分:1)

这是一个很好的例子,您应该应用Joshua Bloch "Favor composition over inheritance" 习语。

您可以将已应用于group by的所有逻辑委托给某个班级BaseFragment

FragmentHelper

现在在你的BaseFragment中:

public class FragmentHelper {

    private final Fragment fragment;

    public FragmentHelper(Fragment fragment) {
        this.fragment = fragment;
    }

    public void create(Bundle bundle) {
      // `BaseFragment`'s code goes here
    }

    public void resume() {
      // `BaseFragment`'s code goes here
    }

    ...
}

同样,这应该应用于扩展public class BaseFragment { private FragmentHelper fragmentHelper; @Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); ... fragmentHelper = new FragmentHelper(this); fragmentHelper.create(savedInstanceState); } @Override public void onResume() { fragmentHelper.resume(); } } 的类。

因此,你会逃避代码重复。

参考:

  • Joshua Bloch - Effective Java 2nd edition,Item 16。