【问题标题】:Adding toolbar to PreferenceActivity via AppCompatPreferenceActivity causes overlapping通过 AppCompatPreferenceActivity 将工具栏添加到 PreferenceActivity 会导致重叠
【发布时间】:2015-10-18 01:20:18
【问题描述】:

我已经通过How to add toolbars to 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();
    }
}

使用AppCompayPreferenceActivity后,加上一些Toolbar的初始化代码,结果如下所示

结果不如预期:-

  1. ToolbarPreferenceFragment 重叠
  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);
    }
}

我的工具栏是

工具栏.xml

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

我在想,我做错了什么,导致ToolbarPreferenceFragment 重叠

【问题讨论】:

    标签: android


    【解决方案1】:

    经过一些研究并从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();
            }
        }
    

    JStockPreferenceFragment.java

    public class JStockPreferenceFragment extends PreferenceFragmentCompat implements SharedPreferences.OnSharedPreferenceChangeListener, PreferenceFragmentCompat.OnPreferenceDisplayDialogCallback {
    
        public static JStockPreferenceFragment newInstance() {
            return new JStockPreferenceFragment();
        }
    

    但是,这样做有一个缺点。您之前的自定义 DialogPreference 不再有效。要解决这个问题,您需要

    1. DialogPreference 替换为PreferenceDialogFragmentCompat
    2. 将 XML 中的 DialogPreference 替换为 ListPreference。 (我不确定ListPreference 作为替代品是否是正确的方法。它仍然有效)
    3. PreferenceFragmentCompatonPreferenceDisplayDialog 中手动显示PreferenceDialogFragmentCompat

    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.
        ////////////////////////////////////////////////////////////////////////////////////////////////
    

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

    preferences.xml

    <android.support.v7.preference.ListPreference
        android:title="@string/preference_currency_symbol_title"
        android:key="_CURRENCY_SYMBOL_OPTIONS" />  
    

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

    <item name="preferenceTheme">@style/PreferenceThemeOverlay</item>
    

    关于主题的一些错误

    但是,主题化还不完美 - PreferenceFragmentCompat requires preferenceTheme to be set

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

    有建议的解决方法https://stackoverflow.com/a/32108439/72437 但是,该解决方法仅适用于 v14 及更高版本,不适用于 v7 及更高版本。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-02
      相关资源
      最近更新 更多