在子屏幕首选项中的操作栏中显示“显示”按钮

12

我已经按照官方指南所示实现了我的偏好设置。

我有一个PreferenceActivity,它创建了如下的PreferenceFragment:

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

      Bundle extras = getIntent().getExtras();
      if (extras != null) 
      {
          Bundle bundle = new Bundle();
          _widgetID = extras.getInt(GlobalSettings.EXTRA_WIDGET_ID); 
          bundle.putInt(GlobalSettings.EXTRA_WIDGET_ID, _widgetID);

          WidgetSettingsFragment fragment = new WidgetSettingsFragment();
          fragment.setArguments(bundle);

          getFragmentManager().beginTransaction().replace(android.R.id.content,
                        fragment).commit();
      }

 }

PreferenceFragment会从资源中加载偏好设置,它们包含一个像这样的偏好子屏幕:

<PreferenceScreen  xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- opens a subscreen of settings -->
    <PreferenceScreen
        android:key="button_voicemail_category_key"
        android:title="@string/voicemail"
        android:persistent="false">
        <ListPreference
            android:key="button_voicemail_provider_key"
            android:title="@string/voicemail_provider" ... />
        <!-- opens another nested subscreen -->
        <PreferenceScreen
            android:key="button_voicemail_setting_key"
            android:title="@string/voicemail_settings"
            android:persistent="false">
            ...
        </PreferenceScreen>
        <RingtonePreference
            android:key="button_voicemail_ringtone_key"
            android:title="@string/voicemail_ringtone_title"
            android:ringtoneType="notification" ... />
        ...
    </PreferenceScreen>
    ...
</PreferenceScreen>

到目前为止这个功能运行良好,但是现在我想在首选项子界面中显示一个 上一步按钮在 actionBar 中。有什么办法可以实现吗?

我已经在我的 activity 中尝试设置 setDisplayHomeAsUpEnabled(true), 但是上一步按钮只会在主首选项中显示(那里不应该有)而不会在子屏幕中显示。

我想知道即使在官方文档中,子屏幕也没有活动的上一步按钮:

Setting subscreens

文档链接:设置

任何帮助都非常欢迎。


据我所知,根据谷歌的设计建议,在这种情况下,系统后退按钮比向上导航更可取。否则,如果您创建自己的新活动,则可以使用getActionBar()。setDisplayHomeAsUpEnabled(true)来处理*特定子屏幕活动。 - webuster
有一个几乎完全相同的问题:https://dev59.com/MmfWa4cB1Zd3GeqPfk_j - Mdlc
2
问题在于我只有一个PreferenceFragment,它显示了偏好设置并自动显示了偏好设置的子屏幕。我没有为子屏幕创建活动或片段类。我不知道如何检查是否显示了子屏幕,以便调用setDisplayHomeAsUpEnabled(true),因为我不知道是否存在此接口或回调。 - user1567896
3个回答

13

我终于让它工作了 :D。虽然方法有些hacky,但它确实起作用。

问题在于,在xml布局中使用子屏幕会导致一些“代码魔法”。 一个新的活动/对话框将为子屏幕启动,您无法直接访问它。

要获取操作栏和主页/向上按钮的OnClickListener,您需要获取对PreferenceScreen的引用,并获取其父对话框以访问操作栏及其主页/向上按钮。

这是我在PreferenceFragment内部执行此操作的方法:

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

 final PreferenceScreen preferenceScreen = (PreferenceScreen) findPreference(getString(R.string.keyPrefScreenDynamicWidgetDetails));
  preferenceScreen.setOnPreferenceClickListener(new OnPreferenceClickListener() 
  {
       public boolean onPreferenceClick(Preference preference) 
       {
           preferenceScreen.getDialog().getActionBar().setDisplayHomeAsUpEnabled(true);
           final Dialog dialog = preferenceScreen.getDialog();

           View homeBtn = dialog.findViewById(android.R.id.home);
           if (homeBtn != null) 
           {
               OnClickListener dismissDialogClickListener = new OnClickListener()
               {
                   @Override
                   public void onClick(View v) 
                   {
                      dialog.dismiss();
                   }
               };

               // Prepare yourselves for some hacky programming
               ViewParent homeBtnContainer = homeBtn.getParent();

               // The home button is an ImageView inside a FrameLayout
               if (homeBtnContainer instanceof FrameLayout) {
                   ViewGroup containerParent = (ViewGroup) homeBtnContainer.getParent();

                   if (containerParent instanceof LinearLayout) {
                       // This view also contains the title text, set the whole view as clickable
                       ((LinearLayout) containerParent).setOnClickListener(dismissDialogClickListener);
                   } else {
                       // Just set it on the home button
                       ((FrameLayout) homeBtnContainer).setOnClickListener(dismissDialogClickListener);
                   }
               } else {
                   // The 'If all else fails' default case
                   homeBtn.setOnClickListener(dismissDialogClickListener);
               }                   
           }
           return true;
       }
  });
...

}

以下链接为我提供了最后解决问题所需的线索和代码:

Action Bar Home Button not functional with nested PreferenceScreen


1
聪明但是不太正规,可能也不具备可移植性。它依赖于你无法控制的对话框的实现细节。 - Eric Woodruff

3
我按照Android文档中的"支持旧版本的首选项标题"部分进行操作,http://developer.android.com/guide/topics/ui/settings.html#BackCompatHeaders。使用传统的PreferenceActivity,您可以在xml中指定一个Preference,该Preference会启动同一PreferenceActivity类的意图。该活动检查意图操作并确定它是否嵌套(以显示向上按钮)以及要在屏幕中充气的哪个优先顺序XML。
当然,我也打算支持旧设备。我发现PreferenceFragment仅适用于使用首选项标题的大型平板电脑。
为了在手机和平板电脑之间重复使用首选项,我提出了这个解决方案https://dev59.com/3W435IYBdhLWcg3wnBZ8#20806812

-5

为启用向上操作,请执行以下操作:

getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayUseLogoEnabled(true);

这将为您提供图标。

然后添加

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        // Respond to the action bar's Up/Home button
        case android.R.id.home:
            finish();
            return true;
    }
    return super.onOptionsItemSelected(item);
}

您可以更改此内容以达到您需要的目的地。作为另一种选择,您可以使用navigateUpTo(Intent intent)和onSupportNavigateUpTo(Intent intent)方法,并指定要返回的意图。


谢谢您的回答,但这并不是我问题的答案。 - user1567896

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接