javaandroidkotlinandroid-preferencespreferenceactivity

How to handle click events on custom items in the preference(PreferenceFragment)?


I created custom layout for preference in order to add new custom item to it. I add that layout with android:layout property. My custom layout looks like that:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:minHeight="?android:attr/listPreferredItemHeightSmall"
    android:gravity="center_vertical"
    android:paddingStart="?android:attr/listPreferredItemPaddingStart"
    android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
    android:background="?android:attr/selectableItemBackground"
    android:clipToPadding="false"
    android:baselineAligned="false">

    <include layout="@layout/image_frame"/>

    <RelativeLayout
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:paddingTop="16dp"
        android:paddingBottom="16dp">

        <TextView
            android:id="@android:id/title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:singleLine="true"
            android:textAppearance="?android:attr/textAppearanceListItem"
            android:ellipsize="marquee"/>

        <TextView
            android:id="@android:id/summary"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@android:id/title"
            android:layout_alignStart="@android:id/title"
            android:layout_gravity="start"
            android:textAlignment="viewStart"
            android:textColor="?android:attr/textColorSecondary"
            android:maxLines="10"
            style="@style/PreferenceSummaryTextStyle"/>

    </RelativeLayout>

    <ImageView
        android:id="@+id/`preference_info`"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@drawable/ic_info"
        android:layout_marginStart="16dp"
        tools:ignore="ContentDescription" />

    <LinearLayout
        android:id="@android:id/widget_frame"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:gravity="end|center_vertical"
        android:paddingStart="16dp"
        android:paddingEnd="0dp"
        android:orientation="vertical"/>

</LinearLayout>

My new item has preference_info id. How to handle click event on onPreferenceTreeClick to handle simple click events on the whole preference line?


Solution

  • This no straight forward way to grab custom layout views from Preferences, you would have to create a custom Preference that extends Preference from androidx.preference and override either onBindView(view:View) methods, only there can you get hold of the views in your Preference's layout.

     class CustomInfoPreference(context:Context) : Preference(context){
          constructor(context: Context, attrs: AttributeSet): super(context,attrs)
    
          override protected fun onBindView(view:View){ 
            super(view)
          val preferenceInfo = view.findViewById<ImageView>(R.id.preference_info) 
           
           preferenceInfo.setOnClickListener{
               // Perform action!
              }
            }
    
         }
    

    Then in your preference.xml you can use the custom preference like this:

    <PreferenceCategory
    android:title="...." >
    
    <com.example.appname.CustomInfoPreference
            android:key="pref key"
            android:title="your pref title"
            android:summary="your pref summary"
            android:defaultValue=""
            android:layout="@layout/custom_preference_layout" />
    
     </PreferenceCategory>
    

    Also checkout this SO thread: Android Set Custom Preference Layout