I cant get this to work I want the sign out Button
on this preferences
screen to have a ClickListener
This is how it looks like:
Here´s the code and the buttonView
is always 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)
}
}
I also tried the kotlinx.android.synthetic but same problem there
Here´s the 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>
Here is the "@layout/pref_category_sign_out_button"
layout
<?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>
Since your Fragment
extends from PreferenceFragmentCompat
, you should not try to set a View.OnClickListener
but override PreferenceFragmentCompat.onPreferenceTreeClick()
instead. According to the documentation, this method is ...
Called when a preference in the tree rooted at this PreferenceScreen has been clicked.
Code example in 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;
}
Code example in Kotlin (I hope I can trust 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
}
This will enable you to catch click events for the Preference
but not for the Button
.
In order to do that as well, one can use a custom Preference
and override onBindViewHolder(PreferenceViewHolder)
. Since PreferenceViewHolder
- similar to RecyclerView.ViewHolder
- has a field itemView
which contains the inflated layout, here is a good opportunity to set our own View.OnClickListener
.
SignOutPreference
extends from TwoStatePreference
(in the com.android.support:preference-v7 library) because replacing the CheckBox
widget with your custom Button
requires only to set the android:widgetLayout
attribute, just like you do in your code snippet:
<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();
}
});
}
}
}