详解Dialog(二)——有关列表的构建

详解Dialog(二)——有关列表的构建,第1张

概述上篇给大家讲了Dialog的基本元素的构建方法,今天给大家说说有关列表对话框的构建。本篇讲的所有列表项都是通过系统自带的函数生成的,对于完全自定义对话框的方法,我们会在最后一篇讲。列表对话框主要有四种:普通列表、单选列表、双选列表、自定义视图的列表,下面我们一个个来分析。一、普通列表普通列表的样式是这样的:要实现这样的列表样式,是通过下面的方法来实现的:buil...

上篇给大家讲了Dialog的基本元素的构建方法,今天给大家说说有关列表对话框的构建。本篇讲的所有列表项都是通过系统自带的函数生成的,对于完全自定义对话框的方法,我们会在最后一篇讲。

 

列表对话框主要有四种:普通列表、单选列表、双选列表、自定义视图的列表,下面我们一个个来分析。
 

一、普通列表

普通列表的样式是这样的:

要实现这样的列表样式,是通过下面的方法来实现的:

builder.setItems(CharSequence[] items,DialogInterface.OnClickListener Listener)builder.setItems(int itemsID,DialogInterface.OnClickListener Listener)

这两种方法实现的效果都是一样的,

setItems(CharSequence[] items,DialogInterface.OnClickListener Listener)

这个items传进去的是一个字符串数组;

 

setItems(int itemsID,DialogInterface.OnClickListener Listener)

这个传进去的一个itemsID,是在XML中定义好的一个字符串数组资源的ID;

 

下面,我们一个个看看他们的具体用法:

 

1、字符串数组

下面是上图是实现上图效果的代码:

String[] mItems = {"item0","item1","itme2","item3","itme4","item5","item6"};AlertDialog.Builder builder = new AlertDialog.Builder(MyActivity.this);builder.setIcon(R.drawable.ic_launcher);builder.setTitle("使用列表字符串");builder.setItems(mItems,new DialogInterface.OnClickListener() {    @OverrIDe    public voID onClick(DialogInterface dialog,int which) {        Toast.makeText(MyActivity.this,"clicked:" + which,Toast.LENGTH_LONG).show();    }});builder.create();builder.show();

可以看到首先构造一个mItems数组,然后在buIDler.setItems直接传进去就好了。至于DialogInterface.OnClickListener(){}函数就是对点击事件的监听,which表示当前点击的是哪个ITEM的索引。

 

2、字符串资源ID

首先在xml文件夹下建一个字符串资源XML,命名为:array.xml,位置如图:

 

然后定义一段字符串数组:

<?xml version="1.0" enCoding="utf-8"?><resources>    <string-array name="dialog_items">        <item>王菲</item>        <item>王力宏</item>        <item>帅哥</item>        <item>美女</item>    </string-array></resources>

下面就是利用SetItem来生成列表了:

AlertDialog.Builder builder = new AlertDialog.Builder(MyActivity.this);builder.setIcon(R.drawable.ic_launcher);builder.setTitle("使用Resource ID");builder.setItems(R.array.dialog_items,Toast.LENGTH_LONG).show();    }});builder.create();builder.show();

在这里的SetItems时直接将我们字符串数组的name直接设置进去,出来的效果就是这样的:

 

二、单选列表

单选列表的样式是这样的:

@H_502_94@

要实现单选列表,主要是通过下面四个其中之一来实现的:

方法一:

setSingleChoiceItems(CharSequence[] items,int checkedItem,DialogInterface.OnClickListener Listener)

与上面一样,传进去一个字符串数组,和初始化时选中的ITEM,构造一个单选列表


方法二:

setSingleChoiceItems (int itemsID,DialogInterface.OnClickListener Listener)

同样,与上面的例子相同,这里传进去的是一个字符串数组的资源ID,字符串数组的构造方法与上面相同,就不再赘述

 

方法三:

setSingleChoiceItems (listadapter adapter,DialogInterface.OnClickListener Listener)

这个方法是最难理解的方法,因为这里的listadapter并不能是普通的Adapter,不信你传一个Adapter,保证出来只是你自己的ITEM视图,旁边的单选按钮却出不来,其实这里的Adapter只是重写单选按钮旁的文字的样式,并不支持所有的Adapter,这个我会在本文最后讲述。
 

方法四:

setSingleChoiceItems (Cursor cursor,String labelColumn,DialogInterface.OnClickListener Listener)

这里通过传进去一个Cursor来构造对应的字符串数组,可以是数据库Cursor,也可以其它系统自带的数据Cursor,但基本上用不到,就不再讲了
好了,关于方法三,因为下面会接着讲SetAdapter的知识,所以这部分我留在最后再讲,这里先讲下方法一和方法二:

 

方法一和方法二,与上例没什么区别,下面我就以方法一以例来讲讲上面的效果图是怎么实现的吧:

代码如下:

String[] mItems = {"攻","受","全能型","不告诉你"};AlertDialog.Builder builder = new AlertDialog.Builder(MyActivity.this);builder.setIcon(R.drawable.ic_launcher);builder.setTitle("你懂的");builder.setSingleChoiceItems(mItems,int which) {        // Todo auto-generated method stub        Toast.makeText(MyActivity.this,Toast.LENGTH_LONG).show();    }});builder.create();builder.show();

很简单,构造一个mItems的String字符串,然后直接传进去setSingleChoiceItems中,默认选中第一个,即索引是0的项。

  三、多选列表

先看看效果图:

自带的多选构造函数有如下几个:

方法一:

setMultiChoiceItems (CharSequence[] items,boolean[] checkedItems,DialogInterface.OnMultiChoiceClickListener Listener)

一样,传进去一个ITEMS数组和对应的项目的选中与否状态的数组;

 

方法二:

 setMultiChoiceItems (int itemsID,DialogInterface.OnMultiChoiceClickListener Listener)

这里传进去的是一个字符串数组,与第一部分相同

 

方法三:

setMultiChoiceItems (Cursor cursor,String isCheckedColumn,DialogInterface.OnMultiChoiceClickListener Listener)

同样,这里传进去的是一个CURSOR,可以是数据库的指针,也可以是系统自带数据的指针,基本不怎么用,就不讲了

 

下面以方法一为例看看多选列表的构造过程:

String[] mItems = {"经常犯二","傻叉一枚","逗逼","小清纯","沉稳大叔","有时可爱"};AlertDialog.Builder builder = new AlertDialog.Builder(MyActivity.this);builder.setIcon(R.drawable.ic_launcher);builder.setTitle("性格类型");builder.setMultiChoiceItems(mItems,new boolean[]{false,false,false},new DialogInterface.OnMultiChoiceClickListener() {             @OverrIDe            public voID onClick(DialogInterface dialog,int which,boolean isChecked) {                Toast.makeText(MyActivity.this,Toast.LENGTH_LONG).show();            }        });builder.show();

这里构造了两个数组,一个是字符串数组,另一个每项对应是否选中的boolean数组

String[] mItems = {"经常犯二","有时可爱"};

对应的选中项的布尔值数组:

new boolean[]{false,false}
四、自定义列表项

 

这节我带大家自定义列表项的实现,故名思义,就是每个ITEM都是我们自己来定义,使用我们自己的Adapter,先看看效果:

要实现自定义列表主要是造下面这个函数来实现的:

setAdapter (listadapter adapter,DialogInterface.OnClickListener Listener)

直接将我们构造好的Adapter设置进去。

下面就带大家实现下图示中的视图:

1、构造Adapter

有关派生自BaseAdapter来构造ListVIEwAdapter的过程就不再细讲了,大家可以参考我以前的两篇文章:

首先是单个Item的布局:(List_item.xml)

很简单,采用水平布局,左边一个图像,右边一个对应的TEXT,这里只是基本实现功能,大家完全可以在理解这篇文章的基础上派生出更复杂的视图

<?xml version="1.0" enCoding="utf-8"?><linearLayout xmlns:androID="http://schemas.androID.com/apk/res/androID"    androID:orIEntation="horizontal"    androID:layout_wIDth="wrap_content"    androID:layout_height="match_parent">    <ImageVIEw        androID:ID="@+ID/item_imagevIEw"        androID:layout_wIDth="80dip"        androID:layout_height="80dip"        androID:scaleType="fitCenter"/>    <TextVIEw        androID:ID="@+ID/item_text"        androID:layout_wIDth="wrap_content"        androID:layout_height="match_parent"        androID:gravity="center_vertical|left"        androID:textSize="20sp"/></linearLayout>

对应的视图类:

private class VIEwHolder{    public TextVIEw mTvTitle;    public ImageVIEw mImageVIEw;}

其中有两个变量,一个存储对应的TextVIEw,另一个存储对应的ImageVIEw;

 

现在我们还需要一个类来存储视图类中TextVIEw的标题字符串,和对应ImageVIEw的图片资源的ID值,这就是我们的数据类:

public static class DataHolder{    public String Title;    public int ImageID;    public DataHolder(String Title,int imageID){        this.Title = Title;        this.ImageID = imageID;    }}

我们先阶段性的看看我们的ListVIEwAdapter:

 

首先是派生自BaseAdapter,然后是构造函数,我们传进去一个DataHolder的列表,用来存储每个Item应该显示的内容

public class ListItemAdapter extends BaseAdapter {    private List<DataHolder> mDataList = new ArrayList<DataHolder>();    private LayoutInflater mInflater;     public ListItemAdapter(Context context,ArrayList<DataHolder> dataList) {        if (dataList != null && dataList.size() > 0) {            mDataList.addAll(dataList);        }        mInflater = LayoutInflater.from(context);    }    ………………}

然后是最关键的getVIEw部分:

public VIEw getVIEw(int position,VIEw convertVIEw,VIEwGroup vIEwGroup) {    VIEwHolder holder = null;    if (convertVIEw == null) {        holder=new VIEwHolder();        convertVIEw = mInflater.inflate(R.layout.List_item,null);        holder.mTvTitle = (TextVIEw)convertVIEw.findVIEwByID(R.ID.item_text);        holder.mImageVIEw = (ImageVIEw)convertVIEw.findVIEwByID(R.ID.item_imagevIEw);        convertVIEw.setTag(holder);     }else {        holder = (VIEwHolder)convertVIEw.getTag();    }    holder.mImageVIEw.setimageResource(mDataList.get(position).ImageID);    holder.mTvTitle.setText(mDataList.get(position).Title);     return convertVIEw;}
holder.mImageVIEw.setimageResource(mDataList.get(position).ImageID);holder.mTvTitle.setText(mDataList.get(position).Title);

最后返回convertVIEw,让系统去做绘图
到这里ListVIEwAdapter的构造过程就基本完成了,下面是完整的代码:

/** * Created by harvic * date 2015-1-11 * */public class ListItemAdapter extends BaseAdapter {    private List<DataHolder> mDataList = new ArrayList<DataHolder>();    private LayoutInflater mInflater;    public ListItemAdapter(Context context,ArrayList<DataHolder> dataList){        if (dataList != null && dataList.size()>0){            mDataList.addAll(dataList);        }        mInflater = LayoutInflater.from(context);    }    @OverrIDe    public int getCount() {        return mDataList.size();    }     @OverrIDe    public Object getItem(int position) {        return mDataList.get(position);    }     @OverrIDe    public long getItemID(int position) {        return position;    }     @OverrIDe    public VIEw getVIEw(int position,VIEwGroup vIEwGroup) {        VIEwHolder holder = null;        if (convertVIEw == null) {             holder=new VIEwHolder();             convertVIEw = mInflater.inflate(R.layout.List_item,null);            holder.mTvTitle = (TextVIEw)convertVIEw.findVIEwByID(R.ID.item_text);            holder.mImageVIEw = (ImageVIEw)convertVIEw.findVIEwByID(R.ID.item_imagevIEw);            convertVIEw.setTag(holder);         }else {            holder = (VIEwHolder)convertVIEw.getTag();        }        holder.mImageVIEw.setimageResource(mDataList.get(position).ImageID);        holder.mTvTitle.setText(mDataList.get(position).Title);         return convertVIEw;    }     private class VIEwHolder{        public TextVIEw mTvTitle;        public ImageVIEw mImageVIEw;    }    public static class DataHolder{        public String Title;        public int ImageID;        public DataHolder(String Title,int imageID){            this.Title = Title;            this.ImageID = imageID;        }    }}
2、构造列表

在MainActivity中,首先是初始化我们的ListVIEwAdapter,要初始化Adapter,就要首先传进去一个DataHolder的数组,所有要先构造一个DataHolder的数组

private ArrayList<ListItemAdapter.DataHolder> initDataHolder(){    ArrayList<ListItemAdapter.DataHolder> dataList = new ArrayList<ListItemAdapter.DataHolder>();    ListItemAdapter.DataHolder data_1 = new ListItemAdapter.DataHolder("可爱萌宠1",R.drawable.animal1);    ListItemAdapter.DataHolder data_2 = new ListItemAdapter.DataHolder("可爱萌宠2",R.drawable.animal2);    ListItemAdapter.DataHolder data_3 = new ListItemAdapter.DataHolder("可爱萌宠3",R.drawable.animal3);    ListItemAdapter.DataHolder data_4 = new ListItemAdapter.DataHolder("可爱萌宠4",R.drawable.animal4);    dataList.add(data_1);    dataList.add(data_2);    dataList.add(data_3);    dataList.add(data_4);    return dataList;}

在构造完成数据列表之后,下面就是构造我们的自定义的列表了,我把整个对话框显示过程整合成了一个函数createCustomList,代码如下:

private voID createCustomList() {    ArrayList<ListItemAdapter.DataHolder> dataHolders = initDataHolder();    ListItemAdapter adapter = new ListItemAdapter(MyActivity.this,dataHolders);    AlertDialog.Builder builder = new AlertDialog.Builder(MyActivity.this);    builder.setIcon(R.drawable.ic_launcher);    builder.setTitle("可爱萌宠");    builder.setAdapter(adapter,new DialogInterface.OnClickListener() {        @OverrIDe        public voID onClick(DialogInterface dialogInterface,int which) {            Toast.makeText(MyActivity.this,Toast.LENGTH_LONG).show();        }    });    builder.create();    builder.show();}

OK啦,到这,整个自列表项的内容就讲完了,下面再回过来给大家说说上面我们提到的有关单选列表自定义Adapter的问题。
 

五、有关单选列表自定义Adapter

这里主要讲的函数是第二部分单选列表中的方法三:

setSingleChoiceItems (listadapter adapter,DialogInterface.OnClickListener Listener)

在第四部分,我们构造了一个listadapter,这里需要的也是同样的一个listadapter,那我们直接将第四部分中的Adapter传进去,会是什么效果呢?

 

也就是利用下面的代码:

我们直接在createCustomList()上面改一下,即把builder.setAdapter()直接换成setSingleChoiceItems() ,传进去Adpter,看看在我们定义的视图后面会不会出现一个单选按钮呢?
 

private voID createCustomList() {    ArrayList<ListItemAdapter.DataHolder> dataHolders = initDataHolder();    ListItemAdapter adapter = new ListItemAdapter(MyActivity.this,dataHolders);    AlertDialog.Builder builder = new AlertDialog.Builder(MyActivity.this);    builder.setIcon(R.drawable.ic_launcher);    builder.setTitle("可爱萌宠");    builder.setSingleChoiceItems(adapter,Toast.LENGTH_LONG).show();        }    });    builder.create();    builder.show();}

运行一下,效果是这样的:

看见了没,毛也没有,坑爹玩意,那这个函数到底是用来做什么的呢,在源码中有这样一个文件:

地址在:$androID_sdk_home/platforms/androID-x.x/data/res/layout/simple_List_item_single_choice.xml
文件内容是这样的:
 

<CheckedTextVIEw xmlns:androID="http://schemas.androID.com/apk/res/androID"    androID:ID="@+ID/single_List_item"    androID:layout_wIDth="match_parent"    androID:layout_height="?androID:attr/ListPreferredItemHeightSmall"    androID:textAppearance="?androID:attr/textAppearanceListItemSmall"    androID:gravity="center_vertical"    androID:checkmark="?androID:attr/ListChoiceIndicatorSingle"    androID:paddingStart="?androID:attr/ListPreferredItempaddingStart"    androID:paddingEnd="?androID:attr/ListPreferredItempaddingEnd"  />

利用这个玩意是可以实现效果的,我们来试一下。

1、新建Adapter

新建一个布局文件,来保存ListVIEw的每项的Item,代码如下:

<CheckedTextVIEw xmlns:androID="http://schemas.androID.com/apk/res/androID"    androID:ID="@+ID/single_List_item"    androID:layout_wIDth="match_parent"    androID:layout_height="?androID:attr/ListPreferredItemHeightSmall"    androID:textAppearance="?androID:attr/textAppearanceListItemSmall"    androID:gravity="center_vertical"    androID:checkmark="?androID:attr/ListChoiceIndicatorSingle"    androID:paddingStart="?androID:attr/ListPreferredItempaddingStart"    androID:paddingEnd="?androID:attr/ListPreferredItempaddingEnd"  />

在Adapter中,同样,用来保存ITEM视图的VIEwHolder类,如下:

    private class VIEwHolder{        public TextVIEw  mname;    }

因为在布局中只有一个TextVIEw,所以在VIEwHolder中也只需要一个TextVIEw与其对应,至于类似上面的承载对应数据的DataHolder,因为我们只需要一个String字符串数组就足够了,所以就没必要再新建一个类来承载这些数据了,所以我们要构造Adapter时,传进来一个字符串数组就好了:

 

所以简单的构造函数为:

在构造时,传进来我们每项要显示的标题的字符串数组String[] items,并将其直接添加到我们的List<String> mList中。
 

public class SingleChoiceAdapter extends BaseAdapter {    private LayoutInflater mInflater;    private List<String> mList = new ArrayList<String>();     public SingleChoiceAdapter(Context context,String[] items) {        mInflater = LayoutInflater.from(context);        if (items == null || items.length <= 0) {            return;        }        for (String item : items) {            mList.add(item);        }    }     …………}

然后是最关键的getVIEw()部分:

public VIEw getVIEw(int position,VIEwGroup vIEwGroup) {    VIEwHolder holder = null;    if (convertVIEw == null) {         holder=new VIEwHolder();         convertVIEw = mInflater.inflate(R.layout.single_choice_item,null);        holder.mname = (TextVIEw)convertVIEw.findVIEwByID(R.ID.single_List_item);        convertVIEw.setTag(holder);     }else {        holder = (VIEwHolder)convertVIEw.getTag();    }    holder.mname.setText(mList.get(position));     return convertVIEw;}

这段代码难度不大,就是每次绘图时,将TextVIEw的内容设置为我们指定的字符串:

holder.mname.setText(mList.get(position));

下面是SingleChoiceAdapter完整的代码:

/** * Created by harvic * date 2015-1-11 */public class SingleChoiceAdapter extends BaseAdapter {    private LayoutInflater mInflater;    private List<String> mList = new ArrayList<String>();    public SingleChoiceAdapter(Context context,String[] items){        mInflater = LayoutInflater.from(context);        if (items == null || items.length<=0){            return;        }        for(String item:items){            mList.add(item);        }    }    @OverrIDe    public int getCount() {        return mList.size();    }     @OverrIDe    public Object getItem(int position) {        return mList.get(position);    }     @OverrIDe    public long getItemID(int position) {        return position;    }     @OverrIDe    public VIEw getVIEw(int position,VIEwGroup vIEwGroup) {        VIEwHolder holder = null;        if (convertVIEw == null) {             holder=new VIEwHolder();             convertVIEw = mInflater.inflate(R.layout.single_choice_item,null);            holder.mname = (TextVIEw)convertVIEw.findVIEwByID(R.ID.single_List_item);            convertVIEw.setTag(holder);         }else {            holder = (VIEwHolder)convertVIEw.getTag();        }        holder.mname.setText(mList.get(position));         return convertVIEw;    }     private class VIEwHolder{        public TextVIEw  mname;    }}

然后就是使用的阶段了

2、构造单选列表

 

这里首先构造SingleChoiceAdapter的实例,然后将其传入setSingleChoiceItems中,代码如下:

String[] mItems = {"攻","不告诉你"};SingleChoiceAdapter adapter = new SingleChoiceAdapter(MyActivity.this,mItems);AlertDialog.Builder builder = new AlertDialog.Builder(MyActivity.this);builder.setIcon(R.drawable.ic_launcher);builder.setTitle("可爱萌宠");builder.setSingleChoiceItems(adapter,new DialogInterface.OnClickListener() {    @OverrIDe    public voID onClick(DialogInterface dialogInterface,Toast.LENGTH_LONG).show();    }});builder.create();builder.show();

运行出来的效果如图:

看到没,这里效果是出来了,可见,在单选按钮中,定义Adapter并不是随便定义的,只能定义CheckedTextVIEw的视图,其它是不支持的!!!!

 

好了,到这里本篇就结束了,下篇给大家讲讲有关自定义对话框的内容。

总结

以上是内存溢出为你收集整理的详解Dialog(二)——有关列表的构建全部内容,希望文章能够帮你解决详解Dialog(二)——有关列表的构建所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/1089434.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-27
下一篇 2022-05-27

发表评论

登录后才能评论

评论列表(0条)

保存