【问题标题】:Android nested PreferenceScreen with ActionBar带有 ActionBar 的 Android 嵌套 PreferenceScreen
【发布时间】:2015-05-22 09:02:41
【问题描述】:

我的 Android 应用中有一个 SettingsActivity。本来是没有Actionbar的,所以我实现了这个:

settings_toolbar.xml

<?xml version="1.0" encoding="utf-8"?>
<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"
    app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:minHeight="?attr/actionBarSize"
    app:navigationContentDescription="@string/abc_action_bar_up_description"
    android:background="?attr/colorPrimary"
    app:navigationIcon="?attr/homeAsUpIndicator"
    app:title="@string/action_settings"
    />

SettingsActivity.java

public class SettingsActivity extends PreferenceActivity {

    @Override
    protected void onPostCreate(Bundle savedInstanceState) {
        super.onPostCreate(savedInstanceState);

        LinearLayout root = (LinearLayout)findViewById(android.R.id.list).getParent().getParent().getParent();
        Toolbar bar = (Toolbar) LayoutInflater.from(this).inflate(R.layout.settings_toolbar, root, false);
        root.addView(bar, 0); // insert at top
        bar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();
            }
        });
    }
}

效果很好,但仅适用于第一个 PreferenceScreen。如果我有一个嵌套的 PreferenceScreen,那么就没有 ActionBar。 我怎样才能做到这一点,在嵌套的 PreferenceScreen 上也有一个带有后退按钮的 ActionBar?

应该兼容API15+和AppCombat

原帖:How to add Action Bar from support library into PreferenceActivity?

【问题讨论】:

  • 您已经找到解决方案了吗?
  • 没有。我用一些 ListView 和 CheckBoxes 创建了自己的片段,没有 PreferenceScreen。它工作得很好,看起来像 PreferencesScreen ......在我尝试让 PreferenceScreen 工作之前,我应该早点完成这项工作
  • stackoverflow.com/a/27455363/2247612这个答案对支持库有一个完美的解决方案

标签: android android-actionbar preferenceactivity


【解决方案1】:

除了使用嵌套的 PreferenceScreen 之外,我们还可以使用一个简单的可点击 Preference 并使其像“嵌套的 Header”一样工作;这将显示通常的 ActionBar,因为它启动了 PreferenceActivity 实例,因此还将保持单窗格/双窗格导航样式。 下面是一些简化的示例代码,其中包括 ActionBar 的后退导航按钮设置:

ma​​in_preferences.xml

<PreferenceScreen 
xmlns:android="http://schemas.android.com/apk/res/android"
android:orderingFromXml="true">
    <Preference      
    android:key="a_preference" />

    <!-- this is our "nested header", a simple Preference -->
    <Preference
    android:key="subscreen_preference" />

    <Preference       
    android:key="another_ preference" />

</PreferenceSreen>

subscreen_preference.xml

<PreferenceScreen 
xmlns:android="http://schemas.android.com/apk/res/android"
android:orderingFromXml="true">
    <Preference      
    android:key="sub_preference" />

    <!-- etc -->

</PreferenceSreen>

MyPreferenceActivity.class

public class MyPreferenceActivity extends AppCompatPreferenceActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //display back button. Fragments will handle its behavior (see below)
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}

@Override
public void onBuildHeaders(List<Header> target) {
    loadHeadersFromResource(R.xml.pref_headers, target);
}

@Override
protected boolean isValidFragment(String fragmentName) {
    return MainPreferenceFragment.class.getName().equals(fragmentName) ||
           SubscreenFragment.class.getName().equals(fragmentName);
}


public static class MainPreferenceFragment extends PreferenceFragment {

    @Override
    public void onCreate(Bundle savedInstanceState) {

        //let the fragment intercept the ActionBar buttons:
        setHasOptionsMenu(true);

        addPreferencesFromResource(R.xml.main_preferences);

        findPreference("subscreen_preference").setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {

            @Override
            public boolean onPreferenceClick(Preference preference) {
                //we create a Header manually:
                Header header = new Header();
                //mandatory fragment name:
                header.fragment = "com.foo.MyPreferenceActivity$SubscreenFragment";
                //subscreen title to be shown in the ActionBar
                header.titleRes = R.string.settings_fragment_title;
                //this will do the trick, no further action required:
                //we can ignore the second parameter
                ((MyPreferenceActivity)getActivity()).onHeaderClick(header, 0);
                return true;
            }
        });
    }

    //this will make the ActionBar back navigation button
    // behave like the system back button
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();
        if (id == android.R.id.home) {
            if (!super.onOptionsItemSelected(item)) {
                getActivity().onBackPressed();
            }
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
}

public static class SubscreenFragment extends PreferenceFragment {
    //usual implementation
    }
}

重要提示:如果你使用Proguard,记得添加以下规则,否则isInvalidFragment()会返回false:

-keepnames class com.foo.MyPreferenceActivity$SubscreenFragment

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-04-26
    • 1970-01-01
    • 2015-03-07
    • 1970-01-01
    • 2017-03-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多