通过AppCompatPreferenceActivity将工具栏添加到PreferenceActivity导致重叠

Che*_*eng 5 android

我经历过如何将工具栏添加到AppCompatPreferenceActivity?

我正在使用appcompat-v7:23.0.1support-v4:23.0.1

在使用之前AppCompayPreferenceActivity,我PreferenceActivity在没有工具栏的情况下看起来如下。

在此处输入图片说明

没有工具栏

public class JStockPreferenceActivity extends PreferenceActivity {

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

        if (savedInstanceState == null) {
            // Display the fragment as the main content.
            JStockPreferenceFragment jStockPreferenceFragment = JStockPreferenceFragment.newInstance();
            jStockPreferenceFragment.setArguments(this.getIntent().getExtras());
            this.getFragmentManager().beginTransaction().replace(android.R.id.content, jStockPreferenceFragment).commit();
    }
}
Run Code Online (Sandbox Code Playgroud)

使用AppCompayPreferenceActivityToolbar初始化代码后,结果如下所示

在此处输入图片说明

结果与预期不符:-

  1. Toolbar具有交叠PreferenceFragment
  2. 触摸时Toolbar,事件将被消耗PreferenceFragment。这意味着,当您触摸工具栏上的时,将改为触摸“表头”首选项。

带工具栏

public class JStockPreferenceActivity extends AppCompatPreferenceActivity {
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        if (savedInstanceState == null) {
            // Display the fragment as the main content.
            JStockPreferenceFragment jStockPreferenceFragment = JStockPreferenceFragment.newInstance();
            jStockPreferenceFragment.setArguments(this.getIntent().getExtras());
            this.getFragmentManager().beginTransaction().replace(android.R.id.content, jStockPreferenceFragment).commit();
        }
        initToolbar();
    }

    private void initToolbar() {
        Toolbar toolbar;

        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
            ViewGroup root = (ViewGroup) findViewById(android.R.id.list).getParent().getParent().getParent();
            toolbar = (Toolbar) LayoutInflater.from(this).inflate(R.layout.toolbar, root, false);
            root.addView(toolbar, 0);
        } else {
            toolbar = null;
        }

        setSupportActionBar(toolbar);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    }
}
Run Code Online (Sandbox Code Playgroud)

我的工具栏是

工具栏

<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/toolbar"
    android:layout_height="wrap_content"
    android:layout_width="match_parent"
    android:minHeight="?attr/actionBarSize"
    android:background="?attr/colorPrimary"
    android:elevation="4dp"
    app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
    app:popupTheme="@style/ThemeOverlay.AppCompat.Light" >

    <!-- android:elevation="4dp" is used due to http://www.google.com/design/spec/what-is-material/elevation-shadows.html#elevation-shadows-elevation-android- -->

</android.support.v7.widget.Toolbar>
Run Code Online (Sandbox Code Playgroud)

我想知道我做错了什么,导致ToolbarPreferenceFragment

Che*_*eng 3

经过一些研究并得到Ian Lake的建议后,我设法让它发挥作用

  1. AppCompatPreferenceActivity, 更改为AppCompatActivity+PreferenceFragmentCompat

以下解决方案适用于 API 10 及更高版本。


JStockPreferenceActivity.java

public class JStockPreferenceActivity extends AppCompatActivity {

    @SuppressWarnings("deprecation")
    @SuppressLint("NewApi")
    @Override
    public void onCreate(Bundle savedInstanceState) {            
        super.onCreate(savedInstanceState);

        setContentView(R.layout.jstock_preference_activity);

        initToolbar();

        if (savedInstanceState == null) {
            // Display the fragment as the main content.
            JStockPreferenceFragment jStockPreferenceFragment = JStockPreferenceFragment.newInstance();
            jStockPreferenceFragment.setArguments(this.getIntent().getExtras());
            this.getSupportFragmentManager().beginTransaction().replace(R.id.content, jStockPreferenceFragment).commit();
        }
    }
Run Code Online (Sandbox Code Playgroud)

JStockPreferenceFragment.java

public class JStockPreferenceFragment extends PreferenceFragmentCompat implements SharedPreferences.OnSharedPreferenceChangeListener, PreferenceFragmentCompat.OnPreferenceDisplayDialogCallback {

    public static JStockPreferenceFragment newInstance() {
        return new JStockPreferenceFragment();
    }
Run Code Online (Sandbox Code Playgroud)

然而,这样做有一个缺点。您以前的习惯DialogPreference不再有效。为了解决这个问题,你需要

  1. DialogPreference用。。。来代替PreferenceDialogFragmentCompat
  2. DialogPreference在 XML 中替换为ListPreference. (我不太确定ListPreference替换是否是正确的方法。无论如何它都有效)
  3. 手动显示PreferenceDialogFragmentCompat,在PreferenceFragmentCompats onPreferenceDisplayDialog

JStockPreferenceFragment.java

public class JStockPreferenceFragment extends PreferenceFragmentCompat implements SharedPreferences.OnSharedPreferenceChangeListener, PreferenceFragmentCompat.OnPreferenceDisplayDialogCallback {

    public static JStockPreferenceFragment newInstance() {
        return new JStockPreferenceFragment();
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////
    // Showing custom dialog preference.
    private void showPreferenceDialogFragmentCompat(PreferenceDialogFragmentCompat preferenceDialogFragmentCompat) {
        preferenceDialogFragmentCompat.setTargetFragment(this, 0);
        preferenceDialogFragmentCompat.show(this.getFragmentManager(), "android.support.v7.preference.PreferenceFragment.DIALOG");
    }

    private void showCurrencySymbolPreferenceDialogFragmentCompat(Preference preference) {
        CurrencySymbolPreferenceDialogFragmentCompat currencySymbolPreferenceDialogFragmentCompat = CurrencySymbolPreferenceDialogFragmentCompat.newInstance(preference.getKey());
        showPreferenceDialogFragmentCompat(currencySymbolPreferenceDialogFragmentCompat);
    }

    // Showing custom dialog preference.
    ////////////////////////////////////////////////////////////////////////////////////////////////

    ////////////////////////////////////////////////////////////////////////////////////////////////
    // Callback when we are using custom dialog preference.
    @Override
    public Fragment getCallbackFragment() {
        return this;
    }

    @Override
    public boolean onPreferenceDisplayDialog(PreferenceFragmentCompat preferenceFragmentCompat, Preference preference) {
        final String key = preference.getKey();

        if (_CURRENCY_SYMBOL_OPTIONS.equals(key)) {
            showCurrencySymbolPreferenceDialogFragmentCompat(preference);
            return true;
        }

        return false;
    }
    // Callback when we are using custom dialog preference.
    ////////////////////////////////////////////////////////////////////////////////////////////////
Run Code Online (Sandbox Code Playgroud)

CurrencySymbolPreferenceDialogFragmentCompat.java

public class CurrencySymbolPreferenceDialogFragmentCompat extends PreferenceDialogFragmentCompat {

    public CurrencySymbolPreferenceDialogFragmentCompat() {
    }

    public static CurrencySymbolPreferenceDialogFragmentCompat newInstance(String key) {
        CurrencySymbolPreferenceDialogFragmentCompat fragment = new CurrencySymbolPreferenceDialogFragmentCompat();
        Bundle b = new Bundle(1);
        b.putString("key", key);
        fragment.setArguments(b);
        return fragment;
    }

    @Override
    public void onDialogClosed(boolean positiveResult) {
        if (positiveResult) {
            ...
            this.getPreference().setSummary(getSummary());
            ...
        }
    } 
}
Run Code Online (Sandbox Code Playgroud)

首选项.xml

<android.support.v7.preference.ListPreference
    android:title="@string/preference_currency_symbol_title"
    android:key="_CURRENCY_SYMBOL_OPTIONS" />  
Run Code Online (Sandbox Code Playgroud)

请注意,您需要在主题中添加以下项目。

<item name="preferenceTheme">@style/PreferenceThemeOverlay</item>
Run Code Online (Sandbox Code Playgroud)

关于主题的一些错误

然而,主题还不完美 - PreferenceFragmentCompat 需要设置preferenceTheme

这是一个已知问题:https://code.google.com/p/android/issues/detail?id =183376

有建议的解决方法/sf/answers/2247590761/但是,该解决方法仅适用于 v14 及更高版本,不适用于 v7 及更高版本。