通过AppCompatPreferenceActivity向PreferenceActivity添加工具栏会导致重叠

时间:2015-10-05 16:15:53

标签: android

我经历了How to add toolbars to AppCompatPreferenceActivity?

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

在使用AppCompayPreferenceActivity之前,我的PreferenceActivity会在没有工具栏的情况下显示以下内容。

enter image description here

没有工具栏

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初始化代码后,结果如下所示

enter image description here

结果与预期不符: -

  1. ToolbarPreferenceFragment
  2. 重叠
  3. 触及Toolbar时,PreferenceFragment将使用该事件。这意味着,当您触摸工具栏时,将触摸“表格标题”首选项。
  4. 使用工具栏

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

    我的工具栏是

    toolbar.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重叠

1 个答案:

答案 0 :(得分:3)

经过一些研究并从Ian Lake获得建议后,我设法通过

使其工作
  1. AppCompatPreferenceActivity更改为AppCompatActivity + PreferenceFragmentCompat
  2. 以下解决方案适用于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. DialogPreference替换为ListPreference。 (我不确定ListPreference替换是否是正确的方法。无论如何都可行。)
    3. PreferenceDialogFragmentCompat的{​​{1}}中手动显示PreferenceFragmentCompat
    4. JStockPreferenceFragment.java

      onPreferenceDisplayDialog

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

      的preferences.xml

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

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

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

      关于主题的一些错误

      然而,主题还不完美 - PreferenceFragmentCompat requires preferenceTheme to be set

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

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