有时候系统提供给我们的preference并不能满足我们的要求,所以有的时候需要我们自定义Preferece,下面的例子就是我个人自定义的一个简单的带图标的Preference。
首先是xml布局文件,就是你想实现的布局。
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+android:id/widget_frame"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:minHeight="?android:attr/listPreferredItemHeight"
- android:gravity="center_vertical"
- android:paddingRight="?android:attr/scrollbarSize">
- <RelativeLayout
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginLeft="18dip"
- android:layout_marginRight="6dip"
- android:layout_marginTop="6dip"
- android:layout_marginBottom="6dip"
- android:layout_weight="1">
- <TextView
- android:id="@+android:id/title"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:singleLine="true"
- android:textAppearance="?android:attr/textAppearanceLarge"
- android:ellipsize="marquee"
- android:fadingEdge="horizontal" />
- <TextView
- android:id="@+android:id/summary"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_below="@android:id/title"
- android:layout_alignLeft="@android:id/title"
- android:textAppearance="?android:attr/textAppearanceSmall"
- android:maxLines="2" />
- </RelativeLayout>
- <ImageView
- android:id="@+id/icon"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginLeft="6dip"
- android:layout_marginRight="6dip"
- android:layout_gravity="center" />
- </LinearLayout>
下面是自定义的preference的java文件:
- import com.android.mms.R;
-
- import android.content.Context;
- import android.graphics.drawable.Drawable;
- import android.preference.Preference;
- import android.util.AttributeSet;
- import android.view.View;
- import android.widget.ImageView;
-
- public class IconListPreference extends Preference{
- private Drawable mIcon;
-
- public IconListPreference(final Context context, final AttributeSet attrs, final int defStyle) {
- super(context, attrs);
-
- this.setLayoutResource(R.layout.icon_list_preference);
-
-
- this.mIcon = context.getResources().getDrawable(R.drawable.ycz20_black);
- }
-
- public IconListPreference(final Context context, final AttributeSet attrs) {
- this(context, attrs, 0);
- }
-
- @Override
- protected void onBindView(final View view) {
- super.onBindView(view);
- final ImageView imageView = (ImageView)view.findViewById(R.id.icon);
- if ((imageView != null) && (this.mIcon != null)) {
- imageView.setImageDrawable(this.mIcon);
- }
- }
-
-
-
-
-
-
- public void setIcon(final Drawable icon) {
- if (((icon == null) && (this.mIcon != null)) || ((icon != null) && (!icon.equals(this.mIcon)))) {
- this.mIcon = icon;
- this.notifyChanged();
- }
- }
- public void setIcon(int iconRes) {
- if(R.drawable.ycz20_black!=iconRes){
- this.mIcon = getContext().getResources().getDrawable(iconRes);
- this.notifyChanged();
- }
- }
-
-
-
-
-
-
- public Drawable getIcon() {
- return this.mIcon;
- }
- }
比如你想更改ImageView里面的图标,就是以使用setIcon()方法。
因为自己完成的功能比较简单,所以重写的方法就比较少,大家 可以根据自己的需要来添加更多的方法。
上面只是实现一个perference,但是点击以后没有响应事件,我们可以定义一个一个Dialog,Dialog选项里面需要有图片,文字说明,后面还需要一个单选按钮,所以自己写了一个demo,效果图如下:
功能的完成是使用Dialog的addView()方法,把一个ListView添加进去。ListView控件里面使用了ImageView和CheckedTextView控件,CheckedTextView是一个提供文字和选择框的控件。如果对于CheckedTextView不熟悉,请自己查下文档,在这里就不在多说。
主要功能代码如下:
- public class ListViewActivityextends Activity {
-
-
-
- @Override
-
- public void onCreate(Bundle savedInstanceState){
-
- super.onCreate(savedInstanceState);
-
- setContentView(R.layout.main);
-
- Button button=(Button)findViewById(R.id.button);
-
-
-
- final LayoutInflater factory = LayoutInflater.from(ListViewActivity.this);
-
- final View view = factory.inflate(
-
- R.layout.listview,null);
-
- final ListView list = (ListView) view.findViewById(R.id.ListView01);
-
-
-
- ArrayList<HashMap<String,Object>> listItem =newArrayList<HashMap<String, Object>>();
-
- for(int i=0;i<5;i++)
-
- {
-
- if(i==0){
-
- HashMap<String,Object> map =new HashMap<String,Object>();
-
- map.put("ItemImage", R.drawable.checked);
-
- map.put("ItemTitle", "1");
-
- listItem.add(map);
-
- }else if(i==1){
-
- HashMap<String,Object> map =new HashMap<String,Object>();
-
- map.put("ItemImage", R.drawable.c);
-
- map.put("ItemTitle", "2");
-
- listItem.add(map);
-
- }else if(i==2){
-
- HashMap<String,Object> map =new HashMap<String,Object>();
-
- map.put("ItemImage", R.drawable.d);
-
- map.put("ItemTitle", "3");
-
- listItem.add(map);
-
- }else if(i==3){
-
- HashMap<String,Object> map =new HashMap<String,Object>();
-
- map.put("ItemImage", R.drawable.d);
-
- map.put("ItemTitle", "4");
-
- listItem.add(map);
-
- }else{
-
- HashMap<String,Object> map =new HashMap<String,Object>();
-
- map.put("ItemImage", R.drawable.e);
-
- map.put("ItemTitle", "5");
-
- listItem.add(map);
-
- }
-
- }
-
-
-
- SimpleAdapter listItemAdapter =new SimpleAdapter(this,listItem,
-
- R.layout.item,
-
- new String[] {"ItemImage","ItemTitle"},
-
- new int[] {R.id.imageView,R.id.checkedTextView}
-
- );
-
-
-
- list.setAdapter(listItemAdapter);
-
- list.setOnItemClickListener(new OnItemClickListener(){
-
-
-
- public void onItemClick(AdapterView<?>arg0, View arg1,int arg2,
-
- long arg3) {
-
-
-
- for(int i=0;i<arg0.getCount();i++)
-
- {
- View v = list.getChildAt(i);
-
- CheckedTextViewcheckText=(CheckedTextView)v.findViewById(R.id.checkedTextView);
-
- checkText.setChecked(false);
-
- }
-
- CheckedTextViewcheck=(CheckedTextView)arg1.findViewById(R.id.checkedTextView);
- check.setChecked(true);
- }
- });
-
- final AlertDialog.Builder builder=new AlertDialog.Builder(ListViewActivity.this);
- button.setOnClickListener(new View.OnClickListener() {
- public void onClick(View v) {
- builder.setTitle("Dialog");
- builder.setView(list);
- builder.setNegativeButton("cencel",null);
- builder.create().show();
- }
- });
- }
- }
其中item.xml代码如下
- <?xml version="1.0"encoding="utf-8"?>
-
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-
- android:orientation="horizontal"
-
- android:layout_width="fill_parent"
-
- android:layout_height="fill_parent"
-
- >
-
- <ImageView
-
- android:id="@+id/imageView"
-
- android:layout_width="wrap_content"
-
- android:layout_height="wrap_content"
-
- />
-
- <CheckedTextView xmlns:android="http://schemas.android.com/apk/res/android"
-
- android:id="@+id/checkedTextView"
-
- android:layout_width="match_parent"
-
- android:layout_height="?android:attr/listPreferredItemHeight"
-
- android:textAppearance="?android:attr/textAppearanceLarge"
-
- android:gravity="center_vertical"
-
- android:checkMark="?android:attr/listChoiceIndicatorSingle"
-
- android:paddingLeft="6dip"
-
- android:paddingRight="6dip"
-
- />
-
- </LinearLayout>
Listview.xml文件如下
- <?xml version="1.0"encoding="utf-8"?>
-
- <ListView xmlns:android="http://schemas.android.com/apk/res/android"
-
- android:layout_width="wrap_content"
-
- android:layout_height="wrap_content"
-
- android:id="@+id/ListView01"
-
- />
应该特别注意listview.xml不要把他写在一个父控件下如:LinearLayout等,如果这样会出现错误,。还有就是如果你listview添加过多选项,当单击的时候会出现空指针异常。
另外,Demo源代码可以在此下载。
http://download.csdn.net/source/3494251
2012年7月19号补充:
当listView中含有超过一屏幕的时候,采用以上方法会有空指针异常,是因为未显示的View为空,但是上面代码中要遍历所有代码,所以为空。如何优化,可以参考
ListView Item 选择问题解决之道
这篇文章。
这篇文章原文是在https://gist.github.com/515681。主要是代码,没有其他文字说明,转到这里来,希望对看到的人有用。
下面是用到的xml布局文件。
- <?xml version="1.0" encoding="UTF-8"?>
-
- <LinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+android:id/widget_frame"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:minHeight="?android:attr/listPreferredItemHeight"
- android:gravity="center_vertical"
- android:paddingRight="?android:attr/scrollbarSize">
- <ImageView
- android:id="@+id/icon"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginLeft="6dip"
- android:layout_marginRight="6dip"
- android:layout_gravity="center" />
- <RelativeLayout
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginLeft="2dip"
- android:layout_marginRight="6dip"
- android:layout_marginTop="6dip"
- android:layout_marginBottom="6dip"
- android:layout_weight="1">
- <TextView
- android:id="@+android:id/title"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:singleLine="true"
- android:textAppearance="?android:attr/textAppearanceLarge"
- android:ellipsize="marquee"
- android:fadingEdge="horizontal" />
- <TextView
- android:id="@+android:id/summary"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_below="@android:id/title"
- android:layout_alignLeft="@android:id/title"
- android:textAppearance="?android:attr/textAppearanceSmall"
- android:maxLines="2" />
- </RelativeLayout>
- <CheckBox
- android:id="@+android:id/checkbox"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginRight="4dip"
- android:layout_gravity="center_vertical"
- android:focusable="false"
- android:clickable="false" />
- </LinearLayout>
下面是用到的java类文件。
- import android.content.Context;
- import android.graphics.drawable.Drawable;
- import android.preference.CheckBoxPreference;
- import android.util.AttributeSet;
- import android.view.View;
- import android.widget.ImageView;
- import com.jakewharton.wakkawallpaper.R;
-
- public class IconCheckBoxPreference extends CheckBoxPreference {
- private Drawable mIcon;
-
- public IconCheckBoxPreference(final Context context, final AttributeSet attrs, final int defStyle) {
- super(context, attrs, defStyle);
-
- this.setLayoutResource(R.layout.icon_checkbox_preference);
-
- this.mIcon = context.obtainStyledAttributes(attrs, R.styleable.IconPreference, defStyle, 0).getDrawable(R.styleable.IconPreference_icon);
- }
-
- public IconCheckBoxPreference(final Context context, final AttributeSet attrs) {
- this(context, attrs, 0);
- }
-
- @Override
- protected void onBindView(final View view) {
- super.onBindView(view);
-
- final ImageView imageView = (ImageView)view.findViewById(R.id.icon);
- if ((imageView != null) && (this.mIcon != null)) {
- imageView.setImageDrawable(this.mIcon);
- }
- }
-
-
-
-
-
-
- public void setIcon(final Drawable icon) {
- if (((icon == null) && (this.mIcon != null)) || ((icon != null) && (!icon.equals(this.mIcon)))) {
- this.mIcon = icon;
- this.notifyChanged();
- }
- }
-
-
-
-
-
-
-
- public Drawable getIcon() {
- return this.mIcon;
- }
- }
如果有需要做类似功能的朋友们可以参照此例进行修改。