18

Я пытаюсь отобразить панель действий на моем экране предпочтений. Для того, чтобы сделать это, я добавил следующий код в моем SettingActivityХранить панель действий, отображаемую при изменении PreferenceScreen

public class PreferencesActivity extends ActionBarActivity { 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.preferences_activity); 
     getFragmentManager().beginTransaction() 
       .replace(R.id.container, new PreferencesFragment()).commit(); 

      getSupportActionBar().setDisplayOptions(ActionBar.DISPLAY_SHOW_TITLE | ActionBar.DISPLAY_SHOW_HOME | ActionBar.DISPLAY_HOME_AS_UP); 
      getSupportActionBar().setDisplayHomeAsUpEnabled(true); 
    } 
} 

то остальная часть моего кода в PreferencesFragment. Это прекрасно работает, но как только я нажимаю на предпочтение предпочтения, экран действия скрыт. Если я вернусь к главному экрану предпочтений, я снова его увижу. Любая идея, как отображать панель действий (и обновляется с помощью метки PreferenceScreen)?

Редактирование: просмотр кода предпочтительного экрана выглядит как полноэкранный диалог открывается при нажатии на экран PreferenceScreen. Поскольку мое предпочтение имеет титул Диалог должен отображать название, а также ... но это не

// Set the title bar if title is available, else no title bar 
    final CharSequence title = getTitle(); 
    Dialog dialog = mDialog = new Dialog(context, context.getThemeResId()); 
    if (TextUtils.isEmpty(title)) { 
     dialog.getWindow().requestFeature(Window.FEATURE_NO_TITLE); 
    } else { 
     dialog.setTitle(title); 
    } 
+0

Возможно, вы имели в виду ActionBar? –

+0

да извините ActionBar – user1026605

+0

@ user1026605 когда-либо решил это? –

ответ

6

я, наконец, удалось найти способ сделать это. Это некрасиво, но оно работает.

Сначала я добавьте тот же Intent к каждому определению PreferenceScreen в моем файле preferences.xml (не забудьте обновить значение дополнительного параметра)

 <PreferenceScreen 
      android:key="pref1" 
      android:summary="Summary1" 
      android:title="Title1" > 
      <intent 
       android:action="android.intent.action.VIEW" 
       android:targetPackage="my.package" 
       android:targetClass="my.package.activity.PreferencesActivity" > 
       <extra android:name="page" android:value="pref1" /> 
      </intent> 
... 

</PreferenceScreen> 

BTW my.package.activity.PreferencesActivity мой текущий Preference активность

Затем добавить пристальный фильтр в Manifest

 <activity 
      android:name=".activity.PreferencesActivity" 
      android:configChanges="keyboardHidden|orientation|screenSize" 
      android:label="@string/settings" > 
      <intent-filter android:label="Pref" > 
       <action android:name="android.intent.action.VIEW" /> 
       <category android:name="android.intent.category.PREFERENCE" /> 
      </intent-filter> 
    </activity> 

добавить код в PreferenceActivity, чтобы справиться с этой

@Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.preferences_activity); 

     this.fragment = new PreferencesFragment(); 
     this.fragment.setActivityIntent(getIntent()); 
     getFragmentManager().beginTransaction() 
       .replace(R.id.container, this.fragment).commit(); 
    } 

Наконец добавить следующий код в моих предпочтениях Класс фрагмента

public void setActivityIntent(final Intent activityIntent) { 
if (activityIntent != null) { 
         if (Intent.ACTION_VIEW.equals(activityIntent.getAction())) { 

         if (intent.getExtras() != null) { 
          final String page = intent.getExtras().getString("page"); 
          if (!TextUtils.isEmpty(page)) { 
           openPreferenceScreen(page); 
          } 
         } 
        } 
    } 

private void openPreferenceScreen(final String screenName) { 
    final Preference pref = findPreference(screenName); 
    if (pref instanceof PreferenceScreen) { 
     final PreferenceScreen preferenceScreen = (PreferenceScreen) pref; 
     ((PreferencesActivity) getActivity()).setTitle(preferenceScreen.getTitle()); 
     setPreferenceScreen((PreferenceScreen) pref); 
    } 
} 
+3

Это работало для меня после небольшой модификации: 'PreferenceManager' PreferencesFragment' не создается, пока не вызывается 'onCreate()', поэтому попытка найти и перейти к правильному экрану в 'setActivityIntent()' не удастся. Вместо этого я использую 'setActivityIntent()' для извлечения и хранения имени 'PreferenceScreen' для использования, а затем в' onCreate() 'я вызываю' openPreferenceScreen() 'для перехода к нему. – josh2112

+2

Я поднял дефект, пожалуйста, проголосуйте за него: https://code.google.com/p/android/issues/detail?id=207718 –

+1

Я просто попробовал это, и он просто открыл еще одну копию моего оригинального PreferenceFragment всякий раз, когда я попытался открыть подэкраны. – CiaranC94

0

Я сделал приложение, которое действительно имеет панель действий в деятельности предпочтений. Кажется, я не вижу ключа к этому, хотя помню, мне потребовалось некоторое время, чтобы прибить его правильно.

Похоже, что наши коды очень похожи. Единственное, что попадает на мое внимание, это импорт: import android.support.v7.app.ActionBarActivity;

Позвольте мне знать, если это помогает любому

public class SettingsActivity extends ActionBarActivity { 


    @Override 
    public void onCreate(Bundle savedInstanceState) { 

     super.onCreate(savedInstanceState); 

     getFragmentManager().beginTransaction().replace(android.R.id.content, new PrefsFragment()).commit(); 
    } // End of onCreate 



    static public class PrefsFragment extends PreferenceFragment { 

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

      addPreferencesFromResource(R.xml.preferences); // Load the preferences from an XML resource 


     } 

    } // end of PrefsFragment 

} 

Дополнение: у вас есть это в вашем styles.xml?

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> 
</style> 
+0

Как объяснили в моем вопросе у меня уже есть панель действий, отображаемая на главном экране настройки. Проблема в том, что он исчезает, как только я нажимаю на предпочтение «PreferenceScreen». Я хочу сохранить его и обновить отображение панели действий с именем префикса PreferenceScreen, который был нажат – user1026605

+0

@Bruno Carrier, поддерживается 'PreferenceFragment' для уровня API <' Honey Comb' –

+0

Это так, но это не работает точно так же. См. Это сообщение для тщательного ответа: http://stackoverflow.com/questions/10186697/preferenceactivity-android-4-0-and-earlier –

0

, но как только я нажимаю на предпочтения PreferenceScreen, то ActionBar скрыта. Если я вернусь к главному экрану предпочтений, я снова его увижу.

Я предполагаю, что вы запускаете новую операцию при нажатии на предпочтения

Ваш фрагмент Предпочтение должно выглядеть следующим образом

public static class PreferencesFragment extends PreferenceFragment { 

    public PlaceholderFragment() { 
    } 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     addPreferencesFromResource(R.xml.your_preferences); 
    } 
} 

Затем пробы your_preferences, как показано ниже

<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" 
android:layout_height="fill_parent" 
android:layout_width="fill_parent" > 

<PreferenceCategory 
    android:title="@string/pref_category_title"> 
    <PreferenceScreen 
     android:title="@string/title" 
     android:summary="@string/summary"> 

     <intent 
      android:targetClass="com.your.package.Youractivity " 
      android:targetPackage="com.your.package"/> 

    </PreferenceScreen> 
    <PreferenceScreen 
     android:title="@string/another_title"> 
     <intent 
      android:targetClass="com.your.package.activity2" 
      android:targetPackage="com.your.package.activity"/> 
    </PreferenceScreen> 
</PreferenceCategory> 

И, наконец, главное Youractivity должен простираться от ActionBarActivity

public class Youractivity extends ActionBarActivity { 
} 

Приведенный выше код работает для меня.

+0

Нет, я не. Я просто использую стандартный файл preference.xml res с некоторым стандартным префиксом PreferenceScreen, как объяснялось в моем вопросе. Я не начинаю другое действие с PreferenceScreen. Я просто встраиваю другие настройки в теги PreferenceScreen – user1026605

0

Как вы упомянули в вопросе, может возникнуть проблема с полноэкранным Dialog.

Попробуйте изменить Dialog стиль:

<style name="Theme.Holo.Dialog"> 

или стиль, который имеет следующие свойства:

<item name="windowActionBar">true</item> 
<item name="windowNoTitle">false</item> 

Here вы можете прочитать, как получить ссылку на Dialog.

0

Примечание: Только для API> = 14

Source1 и Source2

PreferenceActivity1.java

public class PreferenceActivity1 extends android.preference.PreferenceActivity { 
@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    addPreferencesFromResource(R.xml.pref1); 

} 

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

PreferenceActivity2.java

public class PreferenceActivity2 extends android.preference.PreferenceActivity { 
@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    addPreferencesFromResource(R.xml.pref2); 
} 
@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(); 
     } 
    }); 
} 
} 

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/app_name" 
/> 

pref1.xml (XML)

<?xml version="1.0" encoding="utf-8"?> 
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" 
android:theme="@android:style/Theme.Light" > 

<PreferenceCategory android:title="Main Preferences" > 
    <CheckBoxPreference 
     android:key="wifi enabled" 
     android:title="WiFi" /> 
</PreferenceCategory> 

<PreferenceScreen 
    android:key="key1" 
    android:summary="" 
    android:title="Wifi Settings" > 
    <intent 
     android:action="android.intent.action.VIEW" 
     android:targetClass="com.example.PreferenceActivity2" 
     android:targetPackage="com.example" /> 
</PreferenceScreen> 

</PreferenceScreen> 

pref2.xml (XML)

<?xml version="1.0" encoding="utf-8"?> 
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" 
android:theme="@android:style/Theme.Light" > 

<PreferenceCategory android:title="Wifi Settings" > 
    <CheckBoxPreference 
     android:key="prefer wifi" 
     android:title="Prefer WiFi" /> 
</PreferenceCategory> 

</PreferenceScreen> 

Manifest

<application 
    android:icon="@drawable/ic_launcher" 
    android:label="@string/app_name" > 
    <activity 
     android:name="com.example.PreferenceActivity1" 
     android:label="@string/app_name" > 
     <intent-filter> 
      <action android:name="android.intent.action.MAIN" /> 
      <category android:name="android.intent.category.LAUNCHER" /> 
     </intent-filter> 
    </activity> 
    <activity 
     android:name="com.example.PreferenceActivity2" 
     android:label="@string/app_name" > 
     <intent-filter> 
      <action android:name="android.intent.action.VIEW" /> 
      <category android:name="android.intent.category.DEFAULT" /> 
     </intent-filter> 
    </activity> 
</application> 

Результат
enter image description here
enter image description here

+0

, как объясняется в моем вопросе, проблема заключается не в том, чтобы отобразить панель действий на главном экране предпочтения. Что произойдет, когда вы нажмете настройки WiFi? Отображается ли панель действий? BTW my min sdk is 14 – user1026605

+0

Невозможно заставить его работать с помощью ActionBar по умолчанию? – user1026605

+0

Я так не думаю, Это всего лишь обходной путь –

6

Если бы sa я вопрос. Вложенный PreferenceScreen s не имеет ActionBar. После прохождения кода он, по-видимому, вызван конфликтом между AppCompatActivity и PreferenceScreen.

С одной стороны, AppCompatActivity предлагает свою собственную панель действий, и поэтому требуется тема, спускающаяся с Theme.AppCompat, где-то указывается windowNoTitle = true (не удалось точно определить, где именно). С другой стороны - PreferenceScreen использует платформу Dialog с темой деятельности (а не подтемой, например, dialogTheme). Может быть ошибка.

Если вы не заботитесь о Theme.AppCompat, вот простое решение, которое работает на API 21+:

  • использования android.preference.PreferenceActivity в качестве базового класса для вашей деятельности
  • создать тему для этой деятельности:

    <!-- This theme is used to show ActionBar on sub-PreferenceScreens --> 
    <style name="PreferenceTheme" parent=""> 
        <item name="android:windowActionBar">true</item> 
        <item name="android:windowNoTitle">false</item> 
    </style> 
    
  • указать android:theme="@style/PreferenceTheme" для этой деятельности в AndroidManifest.xml

То, что вы получите, больше похоже на стандартный заголовок окна, чем полный ActionBar. Я еще не понял, как добавить обратную кнопку и т. Д.

Если вы хотите оставаться совместимым с AppCompatActivity и смежными темами, вам нужно будет запросить FEATURE_NO_TITLE в окне активности. В противном случае на верхнем уровне PreferenceScreen вы получите две панели действий (встроенная сверху и поддержка внизу).

1

Поскольку Google, к сожалению, не не зафиксировал его до сих пор, на самом деле один гораздо проще решение:

  1. Установить класс SettingsActivity продлить от всего «деятельности».

    public class SettingsActivity extends Activity { ...

  2. Создать новую тему в вашей v21/папки стилей для SettingsActivty и установить родителя "Theme.Material. *"

    <style name="CustomThemeSettings" parent="android:Theme.Material"> <item name="android:colorPrimary">@color/...</item> <item name="android:colorPrimaryDark">@color/...</item> <item name="android:colorAccent">@color/...</item> </style>

  3. Установить новую тему в ваш манифест.XML-файл:

    <activity android:name=".SettingsActivity" android:label="@string/title_activity_settingsactivity" android:theme="@style/CustomThemeSettings" > </activity>

  4. Он просто работает :)

  5. (Необязательно) Если вы хотите, чтобы обеспечить поддержку подбора материала для старых устройств
    вы можете поставить SettingsActivity в v21 + папку и создать a другой SettingsActivity для старых устройств с родительским AppCompat.

Смежные вопросы