Cách thêm nút vào PreferenceScreen


106

Có cách nào để thêm một nút vào cuối màn hình tùy chọn và làm cho chúng hoạt động chính xác khi cuộn không?


2
Bạn đã xem xét việc tạo tùy chọn tùy chỉnh chưa?
Prashast

2
Đối với du khách trong tương lai, trong khi giải pháp Max của công trình, có một giải pháp thay thế: stackoverflow.com/a/7251575/802469
Reed

Câu trả lời:


249

Có một giải pháp khác để tùy chỉnh giao diện của các tùy chọn.

Thiết kế một bố cục XML bình thường với các nút hoặc bất kỳ thứ gì bạn muốn thêm vào các tùy chọn tiêu chuẩn. Bao gồm một ListViewtrong bố cục của bạn và cung cấp cho nó ID@android:id/list .

Giả sử chúng tôi gọi là tệp bố cục res/layout/main.xml. Nó có thể trông giống như sau:

<?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>

Trong của bạn PreferenceActivity, hãy thêm hai dòng sau vào onCreate:

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

Sau đó, ListViewbố cục của bạn sẽ được thay thế bằng các tùy chọn được xác định theo cách thông thường res/xml/preferences.xml.


10
Không hoạt động khi nút được đặt bên dưới chế độ xem danh sách. Không hoạt động khi hoạt động tùy chọn đang sử dụng chủ đề hộp thoại.
Greg Ennis

11
Tài liệu mới nhất về cách sử dụng PreferenceActivity tại developer.android.com/reference/android/preference/… đề cập rằng đối với tất cả các phát triển mới, PreferenceFragment là cách được ưu tiên triển khai. Có vẻ như giải pháp đã cho sẽ không hoạt động trong một tình huống như vậy.
Pankaj

4
Nó vẫn không cuộn với danh sách.
Sudarshan Bhat

7
Tôi hơi bối rối bởi câu trả lời này có bao nhiêu phiếu bầu vì nó không thực sự trả lời câu hỏi ban đầu. Nó không cuộn theo danh sách và nó không hoạt động khi nút được đặt ở cuối chế độ xem, như đã đề cập trong phần nhận xét ở trên.
howettl

1
@howettl chỉ cần thay đổi fill_parent thành wrap_content trong ListView layout_height
Martin Ch

56

Tôi biết điều này là hơi muộn, nhưng tôi vừa tìm thấy một giải pháp tôi thích hơn giải pháp được ca ngợi của Max.

Bạn có thể chỉ cần thêm chân trang (hoặc nếu bạn muốn nút ở trên cùng, đầu trang) vào ListView của PreferenceActivity như sau:

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

Tôi hi vọng điêu nay se giup được ai đo.


2
Ít nhất điều này cảm thấy tốt hơn như là giải pháp của Max vì nó không dựa vào id phần tử. Hãy xem cách ứng xử trong các phiên bản tương lai của Android ...
Daniel F

@DanielF. không qua cầu cho đến khi bạn có được nó;)
jpihl

1
Tôi không thể nhận được ListViewvới PreferenceFragment :(
Michał K

1
Không, nó sẽ không hoạt động theo cách đó (vì PreferenceFragmentcó danh sách riêng của nó), nhưng tôi đã giải quyết nó bằng cách tạo Preferencevà đặt một Intenttrên đó. Không cần để tạo ra một nút (ít nhất là trong trường hợp của tôi)
Michał K

1
Không hoạt động với PreferenceFragmentCompat, vì getListView sẽ thực sự trả về RecyclerView
Mauker

11

Ví dụ dưới đây sẽ hiển thị một nút ở cuối trang (trong trường hợp có ai đó vẫn quan tâm).

Trong trường hợp LinearLayout, bạn cũng có thể áp dụng trọng số; điều này là cần thiết vì Listview được đặt thành * fill_parent *. Tôi thường làm điều này bằng cách thêm * android: layout_weight * của:

<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>

Lời giải thích dưới đây không chắc chắn 100% nhưng nó sẽ giúp bạn hiểu ...

+-- 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
  +--

Bạn cũng có thể nói, bởi vì Nút không có trọng lượng; nút được hiển thị ở độ cao 0dp.

Bây giờ với layout_weigths được thêm vào, nó sẽ cho phép nút hiển thị trong chế độ xem

+-- 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
| +--
+--

Xin lỗi bỏ lỡ các bài viết của @stealthcopter
Ronnie

7

Trên thực tế, có một giải pháp. Đây là một mã, tôi hy vọng, điều này sẽ hữu ích cho bất kỳ ai. Có vẻ như 3 tùy chọn và 2 nút ở dưới cùng của màn hình, độc lập với độ phân giải màn hình (được nhắm mục tiêu xuống 240 là thấp nhất)

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

2

Bạn chỉ cần sử dụng PreferenceFragment bên trong Activity chung và thêm nút vào bố cục hoạt động.

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

nhập mô tả hình ảnh ở đây


Tôi đã làm theo gợi ý này và nó hiển thị nút ở cuối chế độ xem, nhưng nó được xếp chồng lên trên danh sách tùy chọn và không thể nhấp được (tức là nhấp vào nút chỉ kích hoạt mục tùy chọn bên dưới).
iaindownie

Nút onClickListener không được kích hoạt bằng giải pháp này
rdehuyss

@rdehuyss nó vì bạn cần thêm onClickListener vào buttonSave:)
Albert

1

Đây sẽ là mã trông như thế nào trong hoạt động tại ví dụ của ronny. Mục đích của tôi là đặt một menu ở phía dưới cùng của màn hình.

/** 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
}

1
 <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>

Tôi tham chiếu @Ronnie, sử dụng RelativeLayout và đặt chiều cao cho layout_height của listview, sau đó đặt layout_alignParentBottom = "true" của nút, Nó có thể hiển thị một nút ở cuối PreferenceScreen; sau đó sử dụng cách của @Max. nó hoạt động cho nhu cầu của tôi.


Đây là một giải pháp hay, nhưng bạn đã quên đặt chế độ xem danh sách phía trên nút. hiện tại, các mục của listview có thể nằm sau nút, điều này không được khuyến khích vì nếu là mục cuối cùng, nó sẽ không bao giờ hiển thị và do đó có thể nhấp được.
nhà phát triển android

Ồ, vâng, bạn nói đúng, tôi quên trường hợp này, vì listview của tôi chỉ có 5 mục, cảm ơn.
Mejonzhan

vui lòng cập nhật câu trả lời của bạn, vì vậy những người khác sẽ không có hành vi này.
nhà phát triển Android

Tôi nghĩ rằng bạn cũng đã quên một số thuộc tính và thẻ kết thúc của relativeLayout.
nhà phát triển Android

Trên thực tế, việc đặt listview_height phù hợp có thể giải quyết được vấn đề bạn đã nói.
Mejonzhan

1

Cũng có thể thêm các nút Hành động vào thanh hành động để có cách tiếp cận tiêu chuẩn 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>

0

Chế độ xem tùy chỉnh trong Hoạt động tùy chọn điều này sẽ giúp thêm chế độ xem tùy chỉnh trong tùy chỉnh trong Android.

Tạo main.xml, quan điểm chỉ cần thiết là một ListView, với 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>

Tạo 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");
        }
}

0

Sau đây là một giải pháp đơn giản để thêm một nút có thể nhấp vào màn hình tùy chọn của bạn. Điều này được thực hiện dễ dàng vì các tùy chọn đã dành sẵn không gian trong android: widgetLayout và nút có thể vượt qua các lần nhấp với android: onClick.

Đầu tiên tạo một button.xml với nội dung

<?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>

Bây giờ trong tùy chọn của bạn. Xml, hãy thêm tùy chọn

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

PreferenceActivity của bạn bây giờ chỉ phải chứa một thành viên 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");
}
}

0

tùy chọn.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) {
                ...
            }
    }

}

0

Tôi thấy tất cả các câu trả lời trên đều không thể sử dụng được vì bất kỳ bố cục nào tôi đã tạo để 'bọc' vùng PreferenceScreenchứa bên trong các bố cục tùy chỉnh (sau đó thêm một nút bên dướiListView ) không thực sự hoạt động.

Chúng chỉ phủ bố cục tùy chỉnh lên đầu danh sách tùy chọn (nổi) và việc nhấp (ví dụ) vào nút tùy chỉnh mới sẽ chỉ gọi tùy chọn bên dưới nút.

Tuy nhiên, tôi thấy giải pháp này hoạt động tốt khi thêm một nút bên dưới vùng chứa danh sách tùy chọn, khi sử dụng PreferenceFragment.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.