【问题标题】:How to add a button to PreferenceScreen如何将按钮添加到 PreferenceScreen
【发布时间】:2010-04-23 08:43:41
【问题描述】:

有没有什么方法可以在首选项屏幕底部添加一个按钮并使其在滚动时正常工作?

【问题讨论】:

  • 您是否考虑过创建自定义首选项?
  • 对于未来的访问者,虽然 Max 的解决方案有效,但还有一个替代解决方案:stackoverflow.com/a/7251575/802469

标签: android android-preferences


【解决方案1】:

还有另一种自定义首选项外观的解决方案。

使用按钮或您想添加到标准首选项的任何内容设计一个普通的 XML 布局。在您的布局中包含 ListView 并为其指定 ID @android:id/list

假设我们将布局文件称为res/layout/main.xml。它可能看起来像这样:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:orientation="vertical">
    <Button android:text="This is a button on top of all preferences."
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
    <ListView android:id="@android:id/list"
              android:layout_width="match_parent"
              android:layout_height="wrap_content" />
</LinearLayout>

在您的PreferenceActivity 中,将这两行添加到您的onCreate

addPreferencesFromResource(R.xml.preferences);
setContentView(R.layout.main);

然后,您布局中的 ListView 将替换为在 res/xml/preferences.xml 中以通常方式定义的首选项。

【讨论】:

  • 按钮放在列表视图下方时不起作用。当首选项活动使用对话框主题时不起作用。
  • developer.android.com/reference/android/preference/… 上有关使用 PreferenceActivity 的最新文档提到,对于所有新开发,PreferenceFragment 是首选的实现方式。在这种情况下,给定的解决方案似乎不起作用。
  • 它仍然不随列表滚动。
  • 我对这个答案有多少票感到有点困惑,因为它实际上并没有回答原始问题。它不随列表滚动,当按钮放在视图底部时它不起作用,如上面的 cmets 所述。
  • @howettl 只需在 ListView layout_height 中将 fill_parent 更改为 wrap_content
【解决方案2】:

我知道这有点晚了,但我刚刚找到了一个我更喜欢的解决方案,而不是 Max 称赞的解决方案。

您可以简单地向 PreferenceActivity 的 ListView 添加页脚(或者如果您希望按钮位于顶部,则添加页眉),如下所示:

public class MyActivity extends PreferenceActivity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.preferences);
        ListView v = getListView();
        v.addFooterView(new Button(this));
    }
}

我希望这对某人有所帮助。

【讨论】:

  • 至少这感觉不如 Max 的解决方案,因为它不依赖于元素 ID。让我们看看它在未来版本的 Android 中的表现如何......
  • @DanielF。在你到达之前不要过桥;)
  • 我无法使用 PreferenceFragment 获取ListView:(
  • 不,它不会那样工作(因为PreferenceFragment 有自己的列表),但我通过创建一个Preference 并在其上设置一个Intent 来解决它。无需创建按钮(至少在我的情况下)
  • 不适用于 PreferenceFragmentCompat,因为 getListView 实际上会返回一个 RecyclerView
【解决方案3】:

下面的这个示例将在页面底部呈现一个按钮(以防有人仍然感兴趣)。

如果是 LinearLayout,您还可以应用权重;这是必需的,因为 Listview 设置为 *fill_parent*。 我通常通过添加 *android:layout_weight* 来做到这一点:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="fill_parent"
              android:layout_height="fill_parent"
              android:orientation="vertical">
    <ListView android:id="@android:id/list"
              android:layout_width="fill_parent"
              android:layout_height="fill_parent" android:layout_weight="10"/>
    <Button android:text="This is a button on top of all preferences."
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" android:layout_weight="1"/>
</LinearLayout>

下面的解释可能不是 100%,但它会帮助你理解......

+-- View Port (linear layout)
| +-- List View (this is where the preferences will go)
| |
| |
| +--
+--
  +--
  | Button (which was pushed out of view by the fillparent of ListView
  +--

你也可以说,因为 Button 没有重量;按钮以 0dp 高度呈现。

现在添加了 layout_weigths,它将让按钮呈现 inview

+-- View Port (linear layout)
| +-- List View (this is where the preferences will go)
| |
| |
| +--
| +--
| | Button (which was pushed out of view by the fillparent of ListView
| +--
+--

【讨论】:

  • 抱歉错过@stealthcopter 的帖子
【解决方案4】:

其实是有办法的。这是一个代码,我希望这对任何人都有用。 它看起来像屏幕底部的 3 个选项和 2 个按钮,与屏幕分辨率无关(目标为 240 为最低)

package com.myapplication.gui;

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.preference.Preference;
import android.preference.PreferenceActivity;
import android.preference.PreferenceScreen;
import android.view.Display;
import android.view.Gravity;
import android.view.WindowManager;
import android.view.ViewGroup.LayoutParams;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.ScrollView;
import com.myproject.general.HeightListView;

import com.myapplication.R;

public class FilterActivity extends PreferenceActivity {

    private LinearLayout rootView; 
    private LinearLayout buttonView; 
    private Button buttonDone;
    private Button buttonRevert;
    private ListView preferenceView; 
    private LinearLayout gradientView;
    private ScrollView scrollRoot;

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

        Display display = ((WindowManager) getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay(); 
        int height = display.getHeight();
        int width = height > 240 ? display.getWidth() : display.getWidth() - 4;

        scrollRoot = new ScrollView(this);
        scrollRoot.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));

        rootView = new LinearLayout(this); 
        rootView.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT)); 
        rootView.setOrientation(LinearLayout.VERTICAL);

        buttonView = new LinearLayout(this); 
        buttonView.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
        buttonView.setOrientation(LinearLayout.HORIZONTAL);
        buttonView.setGravity(Gravity.BOTTOM);

        gradientView = new LinearLayout(this);
        gradientView.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
        gradientView.setOrientation(LinearLayout.HORIZONTAL);
        gradientView.setBackgroundResource(R.drawable.gradient);
        gradientView.setPadding(0, 5, 0, 0);
        gradientView.setBackgroundResource(R.drawable.gradient);

        buttonDone = new Button(this); 
        buttonDone.setText(R.string.filterButton_Done); 
        buttonDone.setLayoutParams(new LayoutParams(width/2, LayoutParams.WRAP_CONTENT));
        gradientView.addView(buttonDone);

        buttonRevert = new Button(this); 
        buttonRevert.setText(R.string.filterButton_Revert);
        buttonRevert.setLayoutParams(new LayoutParams(width/2, LayoutParams.WRAP_CONTENT));
        gradientView.addView(buttonRevert);

        buttonView.addView(gradientView);

        preferenceView = new HeightListView(this); 
        preferenceView.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT)); 
        preferenceView.setId(android.R.id.list); 

        PreferenceScreen screen = createPreferenceHierarchy(); 
        screen.bind(preferenceView); 
        preferenceView.setAdapter(screen.getRootAdapter()); 
        rootView.addView(preferenceView);
        rootView.addView(buttonView);

        if (height > 240) {
            this.setContentView(rootView);
        }
        else {
            scrollRoot.addView(rootView);
            this.setContentView(scrollRoot);
        }

        setPreferenceScreen(screen); 
    } 

    private PreferenceScreen createPreferenceHierarchy() {        
        PreferenceScreen root = getPreferenceManager().createPreferenceScreen(this);

        PreferenceScreen pref1 = getPreferenceManager().createPreferenceScreen(this);
        pref1.setKey("pref1");
        pref1.setTitle("Title");
        pref1.setSummary("Summary");
        root.addPreference(pref1); 

        PreferenceScreen pref2 = getPreferenceManager().createPreferenceScreen(this);
        pref2.setKey("pref2");
        pref2.setTitle("Title");
        pref2.setSummary("Summary");
        root.addPreference(pref2); 

        PreferenceScreen pref3 = getPreferenceManager().createPreferenceScreen(this);
        pref3.setKey("pref3");
        pref3.setTitle("Title");
        pref3.setSummary("Summary");
        root.addPreference(pref3); 

        return root; 
    } 
}

【讨论】:

    【解决方案5】:

    您只需要在通用 Activity 中使用 PreferenceFragment 并将按钮添加到 Activity 布局中即可。

    public class SettingActivity extends Activity {
    
        UserProfileViewModel userProfileViewModel = null;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
            setContentView(R.layout.activity_setting);
            getFragmentManager().beginTransaction()
                    .replace(R.id.content, new SettingsFragment())
                    .commit();
    
        }
    
        private class SettingsFragment extends PreferenceFragment {
            public SettingsFragment() {
            }
    
            @Override
            public void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
    
                // Load the preferences from an XML resource
                addPreferencesFromResource(R.xml.pref_main);
    
            }
        }
    }
    

    SettingActivity.java

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <FrameLayout
            android:id="@+id/content"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_above="@+id/buttonSave"/>
    
        <Button
            android:id="@+id/buttonSave"
            android:text="Save"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:layout_alignParentLeft="true"
            android:layout_alignParentStart="true" />
    </RelativeLayout>
    

    activity_setting

    【讨论】:

    • 我遵循了这个建议,它确实在视图底部显示了按钮,但是它叠加在首选项列表的顶部并且无法单击(即单击按钮只会激活下面的首选项)。
    • 使用此解决方案不会触发 onClickListener 按钮
    • @rdehuyss 因为你需要将 onClickListener 添加到buttonSave :)
    【解决方案6】:

    还可以将操作按钮添加到操作栏以实现 android 标准方法。

    public class PrefActivity extends PreferenceActivity{
    
      @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
        }
    
      @Override
      public boolean onCreateOptionsMenu(Menu menu) {
          // Inflate the menu items for use in the action bar
          MenuInflater inflater = getMenuInflater();
          inflater.inflate(R.menu.preference_header_menu, menu);
          return super.onCreateOptionsMenu(menu);
      }
    
    }
    
    
        <?xml version="1.0" encoding="utf-8"?>
           <menu xmlns:android="http://schemas.android.com/apk/res/android">
           <item android:id="@+id/action_add"
               android:icon="@drawable/ic_menu_add_dark"
               android:title="@string/menu_action_add_title"
               android:showAsAction="always"  />
    
       </menu>
    

    【讨论】:

      【解决方案7】:

      这将是 ronny 示例中活动中的代码的样子。 我的意图是在屏幕底部放置一个菜单。

      /** Called when the activity is first created. */
      @Override
      public void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.prefs);
          addPreferencesFromResource(R.xml.prefs);
      
         /* LayoutInflater CX = getLayoutInflater();
          CX.inflate(R.layout.main,null);*/
          // TODO Auto-generated method stub
      }
      

      【讨论】:

        【解决方案8】:
         <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
            android:layout_width="match_parent"
            android:layout_height="match_parent" >
        
            <ListView
                android:id="@android:id/list"
                android:layout_width="match_parent"
                android:layout_height="@dimens/listview_height" />
        
            <Button
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentBottom="true"
                android:text="This is a button on top of all preferences." />
        </RelativeLayout>
        

        我参考@Ronnie,使用RelativeLayout,给listview的layout_height设置一个高度,然后设置按钮的layout_alignParentBottom = "true",可以在PreferenceScreen底部渲染一个按钮; 然后使用@Max的方式。它可以满足我的需要。

        【讨论】:

        • 这是一个不错的解决方案,但是您忘记在按钮上方设置列表视图。目前,列表视图的项目可能位于按钮后面,不建议这样做,因为如果它是最后一个项目,它将永远不可见,因此是可点击的。
        • 哦,是的,你是对的,我忘记了这个案例,因为我的列表视图只有 5 个项目,谢谢。
        • 请更新您的答案,以免其他人有此行为。
        • 我想你也忘记了 relativeLayout 的一些属性和结束标签。
        • 其实设置正确的listview_height就可以解决你说的问题。
        【解决方案9】:

        以下是向您的偏好屏幕添加可点击按钮的简单解决方案。这很容易,因为首选项已经在 android:widgetLayout 中保留了空间,并且按钮可以通过 android:onClick 传递点击。

        首先创建一个包含内容的button.xml

        <?xml version="1.0" encoding="utf-8"?>
        <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <Button
            android:text="BUTTON"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/button"
            android:onClick="onButtonClick"/>
        </LinearLayout>
        

        现在在您的preferences.xml 中,添加首选项

        <Preference
            android:key="button"
            android:title="Title"
            android:summary="Summary"
            android:widgetLayout="@layout/button" />
        

        您的 PreferenceActivity 现在只需包含一个 onButtonClick 成员

        public class MainActivity extends PreferenceActivity {
        
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
        
            addPreferencesFromResource(R.xml.main_preferences);
        
        
        }
        
        public void onButtonClick(View v) {
            Log.d("Button", "Yeah, button was clicked");
        }
        }
        

        【讨论】:

          【解决方案10】:

          preferences.xml:

              <Preference
                  android:key="clearAllData"
                  android:title="@string/settings_clear_all_data">
              </Preference>
          

          SettingsFragment.java:

          public class SettingsFragment extends PreferenceFragment {
          
              @Override
              public void onCreate(Bundle savedInstanceState) {
                  super.onCreate(savedInstanceState);
                  addPreferencesFromResource(R.xml.settings);
          
                  Preference clearAllData = (Preference) findPreference("clearAllData");
          
                  // setup buttons
                  final Context context = getActivity();
                  clearAllData.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
          
                      @Override
                      public boolean onPreferenceClick(Preference preference) {
                          ...
                      }
              }
          
          }
          

          【讨论】:

            【解决方案11】:

            Custom view in Preference Activity 这将有助于在 Android 的 PreferenceActivity 中添加自定义视图。

            创建main.xml,唯一需要的视图是ListView,id:android:id="@android:id/list"

            <?xml version="1.0" encoding="utf-8"?>
            <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
                    android:orientation="vertical" android:layout_width="fill_parent"
                    android:layout_height="fill_parent" android:weightSum="1">
                    <ListView 
                        android:id="@android:id/list" 
                        android:layout_weight="1"
                        android:layout_width="fill_parent"
                            android:layout_height="0dp">
                    </ListView>
                    <TextView
                    android:id="@+id/textView"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content" />
            </LinearLayout>
            

            创建 CustomPreferenceActivity.java

            public class CustomPreferenceActivity extends PreferenceActivity {
                    @Override
                    protected void onCreate(Bundle savedInstanceState) {
                            super.onCreate(savedInstanceState);
                            setContentView(R.layout.main);
                            addPreferencesFromResource(R.xml.settings);
            
                            //setup any other views that you have
                            TextView textView = (TextView) findViewById(R.id.textView);
            textView.setText("View Added");
                    }
            }
            

            【讨论】:

              【解决方案12】:

              我发现上述所有答案都无法使用,因为我创建的任何布局将PreferenceScreen 容器“包装”在自定义布局中(然后在ListView 下方添加一个按钮)实际上都不起作用。

              它们仅将自定义布局覆盖在首选项列表顶部(浮动),并且单击(例如)新的自定义按钮只会调用按钮下方的首选项。

              但是,我发现this solution 在使用PreferenceFragment 时可以在首选项列表容器下方添加一个按钮。

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2013-05-24
                • 1970-01-01
                • 2014-02-07
                • 2014-05-13
                • 2018-07-01
                • 1970-01-01
                相关资源
                最近更新 更多