Como adicionar um botão a uma tela de preferência?

135

Eu sou muito novo no Android Development e encontrei Preferências. Eu encontrei PreferenceScreene queria criar uma funcionalidade de login com ele. O único problema que tenho é que não sei como adicionar um botão "Login" ao PreferenceScreen.

Aqui está a minha PreferenceScreenaparência:

<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
...
    <PreferenceScreen android:title="@string/login" android:key="Login">
        <EditTextPreference android:persistent="true" android:title="@string/username" android:key="Username"></EditTextPreference>
        <EditTextPreference android:title="@string/password" android:persistent="true" android:password="true" android:key="Password"></EditTextPreference>
    </PreferenceScreen>
...
</PreferenceScreen>

O botão deve estar logo abaixo dos dois EditTextPreferences.

Existe uma solução simples para esse problema? A única solução que encontrei não estava funcionando porque eu uso sub PreferenceScreens.

Atualizar:

Eu descobri que posso adicionar botões desta maneira:

<PreferenceScreen android:title="@string/login" android:key="Login">
        <EditTextPreference android:persistent="true" android:title="@string/username" android:key="Username"></EditTextPreference>
        <EditTextPreference android:title="@string/password" android:persistent="true" android:password="true" android:key="Password"></EditTextPreference>
        <Preference android:layout="@layout/loginButtons" android:key="loginButtons"></Preference>
</PreferenceScreen>

e o arquivo de layout ( loginButtons.xml) fica assim:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_height="wrap_content"
    android:layout_width="fill_parent"
    android:weightSum="10" 
    android:baselineAligned="false" android:orientation="horizontal">
    <Button android:text="Login" android:layout_width="fill_parent"
        android:layout_weight="5" android:layout_height="wrap_content"
        android:id="@+id/loginButton" android:layout_gravity="left"></Button>
    <Button android:text="Password?" android:layout_width="fill_parent"
        android:layout_weight="5" android:layout_height="wrap_content"
        android:id="@+id/forgottenPasswordButton"></Button>
</LinearLayout>

Então agora os botões aparecem, mas não consigo acessá-los no código. Eu tentei com findViewById()isso, mas isso está retornando nulo. Alguma idéia de como eu poderia acessar esses botões?

Van Naaktgeboren
fonte
Veja esta questão stackoverflow.com/questions/2697233/…
Juozas Kontvainis
2
BTW, a resposta @neelabh é mais simples - você pode obter o comportamento necessário especificando a opção de evento no layout xml: basta adicionar android:onClick="method"a cada botão, onde o método é definido na atividade como public void method(View v).
Stan

Respostas:

304

Para o xml:

<Preference android:title="Acts like a button"
                android:key="@string/myCoolButton"
                android:summary="This is a cool button"/>

Então, para o java no seu onCreate()

Preference button = findPreference(getString(R.string.myCoolButton));
button.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
                @Override
                public boolean onPreferenceClick(Preference preference) {   
                    //code for what you want it to do   
                    return true;
                }
            });

Isso parecerá uma preferência normal, com apenas um título e um resumo, portanto parecerá que pertence.

Editar: mudei para usar @string/myCoolButtone getString(R.string.myCoolButton)porque é melhor usar recursos para assistência do compilador, tradução de idiomas e facilidade de alterações de String.

Reed
fonte
7
Muitos dos aplicativos do Google pré-carregados usam essa abordagem e, portanto, é uma boa idéia segui-la! Eu encontrei um botão cinza padrão parece fora de lugar em uma tela de preferências, e graças a você eu encontrei uma boa maneira de fazê-lo parecer padronizados :)
Tom
5
Certifique-se de que android:key="key"e findPreference("key");estão usando a mesma chave.
Reed
4
na verdade, isso não exibe um botão, o que confunde o usuário e não é o que o OP pediu. A resposta correta para realmente mostrar um botão é de Nicolas.
Mutable2112
7
Acabei de perceber que publiquei isso em 2011 às 1:11. Haha
Reed
3
Deveria ter feito isso de 1 mês e 11 dias posteriores: 01/11 / '11 - 01:11 :)
P Kuijpers
43

Suponho que seja tarde demais. Foi o que fiz para uma preferência de botão.

A preferência no arquivo preferência.xml na pasta xml

....
    <Preference
        android:key="resetBD"
        android:title="@string/ajustes_almacenamiento"
        android:summary="@string/ajustes_almacenamiento_desc"
        android:widgetLayout="@layout/pref_reset_bd_button" 
    ></Preference>
  ...

e pref_reset_bd_button.xml na pasta de layout

 <?xml version="1.0" encoding="utf-8"?>
   <Button
       xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/resetButton" 
        android:text="@string/ajustes_almacenamiento_bt" 
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="resetearBD">

   </Button>
Nicolas
fonte
android:widgetLayouté a conexão perfeita entre fragmentos e preferências (um ou ambos definidos em XML). Muito obrigado. Aqui
peter_the_oak
Olá @Nicolas. Seu código funciona, mas uma pergunta ... Como você pode fazer isso, o botão funciona em uma classe que estende PreferenceActivity
SP
4
Por favor, diga-me como encontrar este botão com o ID "resetButton" obrigado!
Ben Jima
Eu encontrei usando android: layout superior ao android: widgetLayout. Usando widgetLayout, meu botão tornou-se o que eu só posso descrever como layout_alignParentRight = "true", mas que o comportamento foi embora quando se usa android: Disposição vez
JoeHz
1
E eu não consigo fazer isso disparar um manipulador de eventos onPreferenceChange or Click
JoeHz 23/16/16
38

Eu queria adicionar um link Exit às preferências e fui capaz de modificar o código de Jakar para fazê-lo funcionar assim:

<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >   
   <PreferenceCategory android:title="Settings">
       <Preference android:title="Click to exit" android:key="exitlink"/>       
   </PreferenceCategory>    
</PreferenceScreen>

Originalmente, a 'Preferência' era uma 'EditTextPreference' que eu editei manualmente.

Então na classe:

public class MyPreferences extends PreferenceActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    addPreferencesFromResource(R.xml.mypreferences);

    Preference button = (Preference)getPreferenceManager().findPreference("exitlink");      
    if (button != null) {
        button.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
            @Override
            public boolean onPreferenceClick(Preference arg0) {
                finish();   
                return true;
            }
        });     
    }
}
}
Dunfield
fonte
3
Funciona bem. Isso é brilhante !
RRTW
8

Adicionar

setContentView(R.layout.buttonLayout);

Abaixo

addPreferencesFromResource(R.xml.yourPreference);

buttonLayout:

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

<RelativeLayout
        android:id="@+id/top_control_bar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
</RelativeLayout>

<LinearLayout
        android:id="@+id/bottom_control_bar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true">

    <Button
            android:id="@+id/button"
            android:layout_width="match_parent"
            android:layout_height="70dp"
            android:text="@string/saveAlarm"/>
</LinearLayout>

<ListView
        android:id="@android:id/list"
        android:layout_width="fill_parent"
        android:layout_height="0dip"
        android:layout_above="@id/bottom_control_bar"
        android:layout_below="@id/top_control_bar"
        android:choiceMode="multipleChoice">
</ListView>

Botão de acesso por:

Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View v) {
        //Your event
    }
});

Você pode colocar o botão na parte superior ou inferior da tela colocando o botão em RelativeLayout:

  • top_control_bar
  • bottom_control_bar

bottom_control_bar

Isso funcionou para mim. Espero poder ajudar alguém com esse pedaço de código.

Thijs Limmen
fonte
Eu usei isso no meu aplicativo, ele mantém o botão no topo da lista, que parece melhor e é mais amigável para os botões OK e Cancelar. Obrigado.
Grux 3/15
1

Eu não acho que exista uma maneira fácil de adicionar um botão a uma tela de preferências. As preferências são limitadas a:

EditTextPreference
ListPreference
RingtonePreference
CheckboxPreference

Ao usar uma tela de preferências, você está limitado ao uso dessas opções e não há uma "preferência de botão" que possa ser facilmente usada para sua necessidade.

Eu estive procurando por funcionalidades semelhantes, adicionando botões à tela de preferências, mas parece que você precisa criar sua própria tela para isso, gerenciando a alteração nas preferências em sua própria implementação.

Eric Nordvik
fonte
Tive o mesmo problema, Se você quiser um botão em suas preferências você tem que usar uma tela selfmade pref :(
Janusz
1

Você pode fazer assim para acessar o botão!

 View footerView = ((LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.layoutButtons, null, false);

Não se esqueça de adicionar android:idao LinearLayout que contém o botão no layoutButtons.xml , ou seja, android:id="@+id/mylayout"

 LinearLayout mLayout = (LinearLayout) footerView.findViewById(R.id.mylayout);
 Button login = (Button) footerView.findViewById(R.id.loginButton);
 login.setOnClickListener(this);
 ListView lv = (ListView) findViewById(android.R.id.list);
 lv.addFooterView(footerView);

 // Lines 2 and 3 can be used in the same way for a second Button!

fonte
não se esqueça de marcar esta pergunta como VERDADEIRA se você sentir que a ajudou nela?
Shah
0

Você também pode personalizar o layout de uma preferência substituindo Preference.onCreateView(parent). O exemplo abaixo usa uma classe interna anônima para fazer preferências vermelhas.

    screen.addPreference(
        new Preference(context) {
            @Override
            protected View onCreateView(ViewGroup parent) {
                View view = super.onCreateView(parent);
                view.setBackgroundColor(Color.RED);
                return view;
            }
        });

Você pode usar esta técnica para adicionar um botão à exibição padrão.

Roger Keays
fonte
0

Se alguém instruir o usuário a clicar em um dos itens de Preferências e manipular os cliques e a sua solução se basear PreferenceFragmentCompat, você poderá fazer o seguinte:

<PreferenceScreen
...
>
...
<Preference
    android:key="@string/pref_key_clickable_item"
    android:persistent="false"
    android:title="Can be clicked"
    android:summary="Click this item so stuff will happen"/>
...
</PreferenceScreen>

Java:

@Override
onPreferenceTreeClick(Preference preference) {
    if (preference.getKey().equals(getContext().getString(R.string.pref_key_clickable_item))) {
       // user clicked the item
       // return "true" to indicate you handled the click
       return true;
    }
    return false;
}

Kotlin:

override fun onPreferenceTreeClick(preference: Preference): Boolean {
    if (preference.key == context?.getString(R.string.pref_key_clickable_ite)) {
       // user clicked the item
       // return "true" to indicate you handled the click
       return true
    }
    return false
}
Csaba Toth
fonte
0

Crie um layout personalizado para o SettingsFragment.javaielayout_settings.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".ui.settings.SettingsFragment"
    tools:ignore="NewApi">

    <com.google.android.material.appbar.AppBarLayout
        android:id="@+id/appBarSettings"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/AppBarOverlay">

        <com.google.android.material.appbar.MaterialToolbar
            android:id="@+id/toolbarSettings"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:minHeight="?attr/actionBarSize"
            app:title="@string/fragment_title_settings" />
    </com.google.android.material.appbar.AppBarLayout>

    <!--this works as the container for the SettingsFragment.java
    put the code for the Button above or below this FrameLayout
    according to your requirement-->

    <FrameLayout
        android:id="@android:id/list_container"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
      app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior" />


    <com.google.android.material.button.MaterialButton
        android:id="@+id/btnSample"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|center"
        android:text="@string/button_sample_text" />

</androidx.coordinatorlayout.widget.CoordinatorLayout>

Em seguida, consulte o arquivo de layout em seu styles.xml:

<style name="AppTheme" parent="....">
      ...............
      ...............
      <item name="preferenceTheme">@style/MyPreferenceThemeOverlay</item>
</style>

<style name="MyPreferenceThemeOverlay" parent="PreferenceThemeOverlay">
      <item name="android:layout>@layout/layout_settings</item>
</style>

E então, no onViewCreated()método do seu SettingsFragment.java, você pode usar o botão assim:

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle 
                             savedInstanceState) {

        MaterialButton btnSample = view.findViewById(R.id.btnSample);
        btnSample.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(requireContext(), "Sample Button 
                   clicked!!", Toast.LENGTH_LONG).show();
            }
        });
    }

Exemplo de tela de configurações com botão

cgb_pandey
fonte
-1

experimente android: onClick = "myMethod" funciona como um encanto para eventos simples de onclick

neelabh
fonte
4
Preferencenão tem onClickpropriedade
ercan
A resposta implica android:onClickna visualização do botão anexado, não na preferência em si.
Stan