Как настроить прослушивание кликов для этой кнопки - PullRequest
0 голосов
/ 05 ноября 2018

Я не могу заставить это работать. Я хочу, чтобы у выхода Button на этом preferences экране было ClickListener

Вот как это выглядит:

enter image description here

Вот код и buttonView всегда равен NULL:

class PreferencesFragment : PreferenceFragmentCompat() {

    lateinit var activity: Context

    private var prefs: SharedPreferences = BleApplication.getInstance().getDefaultSharedPreferences()

    override fun onAttach(context: Context?) {
        super.onAttach(context)
        activity = requireActivity()
    }


    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        val buttonView = view.findViewById<View>(R.id.btn_sign_out)

        if (buttonView != null) {
            buttonView.setOnClickListener {
                Toast.makeText(getActivity(), "You clicked me.", Toast.LENGTH_SHORT).show()
            }
        }
        // Hide the divider
/*        setDivider(ColorDrawable(Color.TRANSPARENT))
        setDividerHeight(0)*/
    }

    override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
        addPreferencesFromResource(R.xml.app_prefs)
    }
}

Я также попробовал kotlinx.android.synthetic, но та же проблема там

Вот этот xml

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

    <PreferenceCategory
        android:layout="@layout/pref_category_text"
        android:title="@string/pref_category_remote_battery_title">

        <SwitchPreferenceCompat
            android:key="@string/pref_key_category_remote_battery_switch"
            android:title="@string/pref_category_remote_battery_switch_title"
            android:summary="@string/pref_category_remote_battery_switch_summ"/>

    </PreferenceCategory>

    <PreferenceCategory
        android:layout="@layout/pref_category_text"
        android:title="@string/pref_category_sign_out_title">

        <Preference
            android:key="@string/pref_key_category_signed_out"
            android:widgetLayout="@layout/pref_category_sign_out_button"
            android:title="@string/pref_category_sign_out_button_title"
            android:summary="@string/pref_category_sign_out_buttom_summ"/>

    </PreferenceCategory>

</PreferenceScreen>

Вот макет "@layout/pref_category_sign_out_button"

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <Button
        android:id="@+id/btn_sign_out"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@drawable/buttonshape"
        android:text="@string/pref_category_sign_out_title" />
</LinearLayout>

Ответы [ 2 ]

0 голосов
/ 13 ноября 2018

Как уже упоминалось @ 0X0nosugar, вы можете использовать метод onPreferenceTreeClicked для удобной обработки всех нажатий, например:

@Override
onPreferenceTreeClick(Preference preference){
    if ((preference.getKey().equals(getContext().getString(R.string.pref_key_category_signed_out))){
       // user clicked signout "button"
       // take appropriate actions
       // return "true" to indicate you handled the click
       return true;
    }
    return false;
}

Проблема при использовании настраиваемой кнопки через widgetLayout заключается в том, что когда нажатие кнопки не является щелчком предпочтения, обработчик не может его перехватить. Один из способов обойти эту проблему - просто отключить встроенный щелчок для кнопки, например:

<Button
    android:id="@+id/btn_sign_out"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@drawable/buttonshape"
    android:text="@string/pref_category_sign_out_title"
    android:clickable="false"/>

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

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

0 голосов
/ 05 ноября 2018

Поскольку ваш Fragment расширяется от PreferenceFragmentCompat, вам не следует пытаться установить View.OnClickListener, а вместо этого переопределить PreferenceFragmentCompat.onPreferenceTreeClick(). Согласно документации , этот метод ...

Вызывается при щелчке по предпочтению в дереве с корнем на этом экране предпочтений.

Пример кода на Java:

@Override
onPreferenceTreeClick(Preference preference){
    if(preference.getKey().equals(getContext().getString(R.string.pref_key_category_signed_out))){
       // user clicked signout "button"
       // take appropriate actions
       // return "true" to indicate you handled the click
       return true;
    }
    return false;
}

Пример кода в Kotlin (надеюсь, я могу доверять Android Studio: P)

override fun onPreferenceTreeClick(preferenceScreen: PreferenceScreen, preference: Preference): Boolean {
    return if (preference.key == context.getString(R.string.pref_key_category_signed_out)) {
        // user clicked signout "button"
        // take appropriate actions
        // return "true" to indicate you handled the click
        true
    } else false
}

Это позволит вам отлавливать события щелчка для Preference, но не для Button.

Для этого также можно использовать пользовательский Preference и переопределить onBindViewHolder(PreferenceViewHolder). Поскольку PreferenceViewHolder - аналогично RecyclerView.ViewHolder - имеет поле itemView, которое содержит раздутый макет, у нас есть хорошая возможность установить наш собственный View.OnClickListener.

SignOutPreference расширяется от TwoStatePreference (в библиотеке com.android.support: preference-v7 ), поскольку для замены виджета CheckBox на пользовательский Button требуется только установить android:widgetLayout атрибут, как вы делаете в своем фрагменте кода:

<PreferenceCategory
    android:layout="@layout/pref_category_text"
    android:title="@string/pref_category_sign_out_title">

    <your.package.name.SignOutPreference
        android:key="@string/pref_key_category_signed_out"
        android:widgetLayout="@layout/pref_category_sign_out_button"
        android:title="@string/pref_category_sign_out_button_title"
        android:summary="@string/pref_category_sign_out_buttom_summ"/>

</PreferenceCategory>

SignOutPreference.java

public class SignOutPreference extends TwoStatePreference {
    public SignOutPreference(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    public SignOutPreference(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public SignOutPreference(Context context) {
        super(context);
    }

    @Override
    public void onBindViewHolder(final PreferenceViewHolder holder) {
        super.onBindViewHolder(holder);
        Button button = holder.itemView.findViewById(R.id.btn_sign_out);
        if(button != null){
            button.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Toast.makeText(holder.itemView.getContext(), "CLICKED!", Toast.LENGTH_SHORT).show();
                }
            });
        }
    }
}
...