android - Custom layout for ListPreference -


i using preferenceactivity setting of app. want add new preference allow user select icon. task want use listpreference, want show icon in list.

i tried customize listpreference use custom layout, problem once list items not clickable (it show custom layout , use default value current selection).

i tested on different emulator version , on galaxy s2. when pressing item see effect of pressed/unpressed, onclick method not called.

i followed instruction on android: checkable linear layout adding custom layout (i tried option describe in how customize list preference radio button, same result).

icontypepreference.java (copied listpreference , modified):

public class icontypepreference extends dialogpreference {     private icontype value;     private int      clickeddialogindex;     private boolean  valueset;      @targetapi(build.version_codes.lollipop)     public icontypepreference(context context, attributeset attrs, int defstyleattr, int defstyleres) {         super(context, attrs, defstyleattr, defstyleres);     }      public icontypepreference(context context, attributeset attrs, int defstyleattr) {         super(context, attrs, defstyleattr);     }      public icontypepreference(context context, attributeset attrs) {         super(context, attrs);     }      @targetapi(build.version_codes.lollipop)     public icontypepreference(context context) {         super(context);     }      public void setvalue(string value) {         // persist/notify first time.         final boolean changed = !textutils.equals(getvaluetext(), value);         if (changed || !valueset) {             if (value == null) {                 this.value = null;             } else {                 this.value = icontype.valueof(value);             }             valueset = true;             persiststring(value);             if (changed) {                 notifychanged();             }         }     }      public void setvalueindex(int index) {         setvalue(icontype.values()[index].tostring());     }      public icontype getvalue() {         return value;     }      public string getvaluetext() {         return (value == null ? null : value.tostring());     }      public int findindexofvalue(string value) {         icontype[] values = icontype.values();         (int = values.length - 1; >= 0; i--) {             if (values[i].tostring().equals(value)) {                 return i;             }         }         return -1;     }      private int getvalueindex() {         return findindexofvalue(getvaluetext());     }      @override     protected void onpreparedialogbuilder(alertdialog.builder builder) {         super.onpreparedialogbuilder(builder);          clickeddialogindex = getvalueindex();         builder.setsinglechoiceitems(new icontypeadapter(getcontext()), clickeddialogindex,                                      new dialoginterface.onclicklistener() {                                          public void onclick(dialoginterface dialog, int which) {                                              clickeddialogindex = which;                                              icontypepreference.this.onclick(dialog, dialoginterface.button_positive);                                              dialog.dismiss();                                          }                                      });         /*          * typical interaction list-based dialogs have          * click-on-an-item dismiss dialog instead of user having          * press 'ok'.          */         builder.setpositivebutton(null, null);     }      @override     protected void ondialogclosed(boolean positiveresult) {         super.ondialogclosed(positiveresult);          if (positiveresult && clickeddialogindex >= 0) {             string value = icontype.values()[clickeddialogindex].tostring();             if (callchangelistener(value)) {                 setvalue(value);             }         }     }      @override     protected object ongetdefaultvalue(typedarray a, int index) {         return a.getstring(index);     }      @override     protected void onsetinitialvalue(boolean restorevalue, object defaultvalue) {         setvalue(restorevalue ? getpersistedstring(getvaluetext()) : (string)defaultvalue);     }      @override     protected parcelable onsaveinstancestate() {         final parcelable superstate = super.onsaveinstancestate();         if (ispersistent()) {             // no need save instance state since it's persistent             return superstate;         }          final savedstate mystate = new savedstate(superstate);         mystate.value = getvaluetext();         return mystate;     }      @override     protected void onrestoreinstancestate(parcelable state) {         if (state == null || !state.getclass().equals(savedstate.class)) {             // didn't save state in onsaveinstancestate             super.onrestoreinstancestate(state);             return;         }          savedstate mystate = (savedstate)state;         super.onrestoreinstancestate(mystate.getsuperstate());         setvalue(mystate.value);     }      private static class savedstate extends basesavedstate {         string value;          public savedstate(parcel source) {             super(source);             value = source.readstring();         }          @override         public void writetoparcel(parcel dest, int flags) {             super.writetoparcel(dest, flags);             dest.writestring(value);         }          public savedstate(parcelable superstate) {             super(superstate);         }          public static final parcelable.creator<savedstate> creator =                 new parcelable.creator<savedstate>() {                     public savedstate createfromparcel(parcel in) {                         return new savedstate(in);                     }                      public savedstate[] newarray(int size) {                         return new savedstate[size];                     }                 };     }      private static class icontypeadapter extends arrayadapter<icontype> {         private final string[]       icontypetext;         private       layoutinflater inflater;          public icontypeadapter(context context) {             super(context, r.layout.icon_type_item, icontype.values());             this.inflater = layoutinflater.from(context);             icontypetext = context.getresources().getstringarray(r.array.icon_type);         }          @override         public view getview(int position, view convertview, viewgroup parent) {             if (convertview == null) {                 convertview = inflater.inflate(r.layout.icon_type_item, parent, false);             }             ((textview)convertview.findviewbyid(r.id.text)).settext(icontypetext[position]);             convertview.setclickable(true);             // todo: set view text             return convertview;         }          @override         public boolean hasstableids() {             return true;         }          @override         public long getitemid(int position) {             return position;         }     } } 

checkablelinearlayout.java

public class checkablelinearlayout extends linearlayout implements checkable {     private checkable checkable;      public checkablelinearlayout(context context) {         super(context);     }      public checkablelinearlayout(context context, attributeset attrs) {         super(context, attrs);     }      @targetapi(build.version_codes.honeycomb)     public checkablelinearlayout(context context, attributeset attrs, int defstyleattr) {         super(context, attrs, defstyleattr);     }      @targetapi(build.version_codes.lollipop)     public checkablelinearlayout(context context, attributeset attrs, int defstyleattr, int defstyleres) {         super(context, attrs, defstyleattr, defstyleres);     }      @override     protected void onfinishinflate() {         super.onfinishinflate(); //        setdescendantfocusability(viewgroup.focus_block_descendants);         checkable = getcheckable(this);         if (checkable == null) {             throw new runtimeexception("missing checkable component");         }     }      private checkable getcheckable(viewgroup viewgroup) {         view v;         int childcount = viewgroup.getchildcount();         (int = 0; < childcount; ++i) {             v = getchildat(i);             if (v instanceof checkable) {                 return (checkable)v;             } else if (v instanceof viewgroup) {                 checkable result = getcheckable((viewgroup)v);                 if (result != null) {                     return result;                 }             }         }         return null;     }      @override     public void setchecked(boolean checked) {         checkable.setchecked(checked);     }      @override     public boolean ischecked() {         return checkable.ischecked();     }      @override     public void toggle() {         checkable.toggle();     } } 

icon_type_item.xml

<?xml version="1.0" encoding="utf-8"?> <com.utils.ui.widget.checkablelinearlayout xmlns:android="http://schemas.android.com/apk/res/android"                                                           android:layout_width="match_parent"                                                           android:layout_height="wrap_content"                                                           android:orientation="horizontal">     <textview android:id="@+id/text"               android:layout_width="0dp"               android:layout_height="wrap_content"               android:layout_weight="1"               android:focusable="false"               android:focusableintouchmode="false"/>     <radiobutton android:layout_width="wrap_content"                  android:layout_height="wrap_content"                  android:clickable="false"                  android:focusable="false"                  android:focusableintouchmode="false"/> </com.utils.ui.widget.checkablelinearlayout> 

added settings.xml

<com.utils.ui.preference.icontypepreference         android:key="icon_type"         android:defaultvalue="type_b"         android:title="@string/icon_type_preference_title"/> 

edit

there bug in checkablelinearlayout.java

replace getcheckable method this:

private checkable getcheckable(viewgroup viewgroup) {     view v;     int childcount = viewgroup.getchildcount();     (int = 0; < childcount; ++i) {         v = viewgroup.getchildat(i);         if (v instanceof checkable) {             return (checkable)v;         } else if (v instanceof viewgroup) {             checkable result = getcheckable((viewgroup)v);             if (result != null) {                 return result;             }         }     }     return null; } 

found solution problem.

the problem in getview method of adapter: changed

convertview.setclickable(true); 

to

convertview.setclickable(false); 

Comments

Popular posts from this blog

java - UnknownEntityTypeException: Unable to locate persister (Hibernate 5.0) -

python - ValueError: empty vocabulary; perhaps the documents only contain stop words -

ubuntu - collect2: fatal error: ld terminated with signal 9 [Killed] -