我创建了一个基础片段类,用于处理工具栏标题的设置,片段附加时的注册,菜单图标的设置以及其他一些操作。我的问题是我决定将PreferencesFragmentCompat用于我的设置片段,并且我无法同时扩展BaseFragment和android的PreferencesFragmentCompat。在这里使用接口无济于事,因为我的BaseFragment具有很多功能,并且我不想将其复制到我的每个片段类中。通常,要扩展两个类,您只需在两个单独的文件中执行此操作,但是由于两者都已经扩展了Android的Fragment类,因此我看不到这是怎么可能的。有更好的方法吗?

java - 具有多个不同 fragment 类型的Android BaseFragment类-LMLPHP

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;
    }
}

最佳答案

这是一个很好的示例,您应在其中应用Joshua Bloch"Favor composition over inheritance"习惯用法。

您可以将已应用于BaseFragment的所有逻辑委托给某个类FragmentHelper

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
    }

    ...
}


现在在您的BaseFragment中:

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();
    }
}


同样,这应应用于扩展PreferenceFragment的类。

因此,您可以避免代码重复。

参考:


Joshua Bloch-有效的Java 2nd Edition,项目16。

09-25 21:40