[转载]Android开发教程 — 葵花宝典第六层 控件之 Dialog ListView GridView – Jason_CC – 博客园.
Hi 大家好!
今天和大家一起来学习三种控件,对话框、列表、网格视图。
这三种控件比较重要,使用率也比较频繁,相对来说也比前面所讲的控件复杂,希望大家多练习,熟练掌握它们。
照例,上笑话。
论坛楼主:帅有个屁用——到头来还不是被卒吃掉!
论坛回复:帅有士陪,有炮打,有马骑,有车坐,有相暗恋……帅怎么不好?!!
Dialog 对话框,它运行起来的效果是什么样呢?如下图
这种是最常用的对话框
当点击了上图的确定后,会弹此对话框,这种对话框属于自定义布局类型
当执行一些比较费时的操作时,用这种对话框是个不错的选择
当我们需要用户进行选择操作,又不能使用下来列表时,可以使用这种自定义布局的对话框
接下来我们就一起来看看这些通过代码是如何实现的?
package TSD.Jason.Example; import android.app.Activity; import android.app.AlertDialog; import android.app.ProgressDialog; import android.app.AlertDialog.Builder; import android.app.Dialog; import android.content.DialogInterface; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.widget.Button; /** * 对话框 * @author Administrator * 常用方法: * setTitle():给对话框设置title. setIcon():给对话框设置图标。 setMessage():设置对话框的提示信息 setItems():设置对话框要显示的一个list,一般用于要显示几个命令时 setSingleChoiceItems():设置对话框显示一个单选的List setMultiChoiceItems():用来设置对话框显示一系列的复选框。 setPositiveButton():给对话框添加”Yes”按钮。 setNegativeButton():给对话框添加”No”按钮。 * */ public class DialogActivity extends Activity { Button btn1; ProgressDialog p; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.diaolg); btn1 = (Button)findViewById(R.id.btnDialog); btn1.setOnClickListener(new Button.OnClickListener() { @Override public void onClick(View v) { Builder dialog = new AlertDialog.Builder(DialogActivity.this); dialog.setTitle("登录提示"); dialog.setIcon(android.R.drawable.ic_dialog_info); dialog.setMessage("是否登录?"); dialog.setPositiveButton("确定", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { ShowLoginDialog(); } }); dialog.setNegativeButton("取消", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { DialogActivity.this.finish(); } }); dialog.show(); } }); } }
以上代码是我们第一张对话框的效果实现代码,大家发现是不是挺简单,当我们单击确定按钮后,将调用一个叫做ShowLoginDialog的方法。
这个方法马上会贴出来,在这里我还是要强调下,大家在写代码的时候一定要有一个良好的编程思想,将功能拆分,降低代码的耦合度,一个方法只做一件事情,不要一股脑的将代码写到一个方法里。希望大家记得。
private void ShowLoginDialog() { Builder builder = new AlertDialog.Builder(DialogActivity.this); builder.setTitle("用户登录"); LayoutInflater factory = LayoutInflater.from(DialogActivity.this); View dialogView = factory.inflate(R.layout.dialogview, null); builder.setView(dialogView); builder.setPositiveButton("确定", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { DialogWait(); } }); builder.setNegativeButton("取消", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { DialogActivity.this.finish(); } }); builder.show(); }
上边被标注的代码是为了让Dialog中的内容部分显示我们自定义的布局文件,通过builder对象的setView方法就可以将R.layout.dialogview这个布局文件绑定到对话框中。
布局文件代码如下
<!--?xml version="1.0" encoding="utf-8"?-->
第三个等待效果的对话框是如何实现的呢?上边我们调用了一个方法叫做 DialogWait
private void DialogWait() { p = ProgressDialog.show(DialogActivity.this, "正在登录", "请稍后...", true); new Thread(){ public void run(){ try { Thread.sleep(2000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally{ p.dismiss();//登录结束后,取消对话框 } } }.start(); }
大家注意,此时的类就不在是AlertDialog,而是ProgressDialog。
上边代码我们为了测试看效果,所以开启了一个线程,并挂起2秒,这在以后项目中是不需要的,如果大家看不太懂,那么这里先跳过。
接下来我们来看看如何在对话框中嵌套一个ListView。
首先,需要一个布局文件,布局文件里只创建一个ListView,如下代码
<!--?xml version="1.0" encoding="utf-8"?-->
Java代码如下
private void ShowLoginDialog() { Builder builder = new AlertDialog.Builder(Tab1Activity.this); builder.setTitle("选择城市"); LayoutInflater factory = LayoutInflater.from(Tab1Activity.this); View dialogView = factory.inflate(R.layout.dialogcity, null); listCity =(ListView)dialogView.findViewById(R.id.listCity); GetCity(); builder.setView(dialogView); builder.show(); } private void GetCity() { System.out.println("asd"); ArrayList> listData = new ArrayList>(); HashMap hmItem = new HashMap(); hmItem.put("city", "北京"); listData.add(hmItem); hmItem = new HashMap(); hmItem.put("city", "上海"); listData.add(hmItem); hmItem = new HashMap(); hmItem.put("city", "深圳"); listData.add(hmItem); hmItem = new HashMap(); hmItem.put("city", "天津"); listData.add(hmItem); hmItem = new HashMap(); hmItem.put("city", "南京"); listData.add(hmItem); hmItem = new HashMap(); hmItem.put("city", "武汉"); listData.add(hmItem); hmItem = new HashMap(); hmItem.put("city", "江苏"); listData.add(hmItem); hmItem = new HashMap(); hmItem.put("city", "宁波"); listData.add(hmItem); SimpleAdapter sim = new SimpleAdapter(this, listData, android.R.layout.simple_list_item_1, new String[]{"city"}, new int[]{android.R.id.text1}); listCity.setAdapter(sim); }
直接调用ShowLoginDialog方法即可。注意标注的代码,需要先获取ListView。这里已经用到了ListView,如果不太懂下边就将ListView,大家注意看。
ListView
上边已经展示过它运行的效果了,这里就不展示运行效果了。
那么要使用ListView需要哪些步骤呢?举一个例子,可能不太恰当
冰箱里没有鸡蛋了,我们从家里提了一个篮子去超市买鸡蛋。就是这样的一个过程。我们来分解下这个步骤
冰箱 == 展示数据 == ListView
超市里的鸡蛋 == 数据 == ArrayList 泛型集合
篮子 == 适配器 == SimpleAdapter
我们应该将 鸡蛋(ArrayList) 装到 篮子里(SimpleAdapter) 然后提回家 放到 冰箱里( ListView)
分解完步骤后,那么我们看看如何用代码实现这个过程。
ListView userList; //声明一个ListView对象(冰箱)
userList = (ListView)findViewById(R.id.listUserInfo); //获取布局文件中的ListView控件赋值给ListView对象
ArrayList> listData = new ArrayList>(); //数据源 (超市装鸡蛋的盒子)
HashMap hmItem = new HashMap(); //需要一个HashMap键值对 (每一个鸡蛋)
hmItem.put(“userName”, “张三”);
hmItem.put(“userPhone”, “1234567890”);
listData.add(hmItem); //将鸡蛋装到数据源中
String[] s = new String[2]; //列 和键值对中的键 一一对应 每个键值对应该是一样的列数
s[0] = “userName”;
s[1] = “userPhone”;
int[] i = new int[2]; //用什么控件来装载上边String集合中的列 和上边的String数组也是一一对应的
i[0] = Android.R.id.text1;
i[1] = Android.R.id.text2;
SimpleAdapter sim = new SimpleAdapter(this, listData, Android.R.layout.simple_list_item_1, s, i); //这就是我们的篮子
userList.setAdapter(sim); //将篮子中的鸡蛋装到冰箱中 🙂
完整的代码如下
package TSD.Jason.Example; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import android.app.Activity; import android.os.Bundle; import android.view.View; import android.widget.AdapterView; import android.widget.ListView; import android.widget.SimpleAdapter; /** * ListView基本使用方法 * * 使用ListView的基本步骤 * 1.准备ListView要显示的数据 ; * ArrayList> listData = new ArrayList>(); * * 2.使用 一维或多维 动态数组 保存数据; * HashMap hmItem = new HashMap(); hmItem.put("userName", "张三"); hmItem.put("userPhone", "1234567890"); * 3.构建适配器 , 简单地来说, 适配器就是 Item数组 , 动态数组 有多少元素就生成多少个Item; * SimpleAdapter simpleAdapter; * 数据绑定的类 * 参数解释 * * 第一个context,很明显大家根据英文可以知道是上下文的意思,它官方的意思是:SimpleAdapter所要运行关联到的视图,这个是什么呢?就是你这个SimpleAdapter所在的Activity(一般而言),所以这个参数一般是this 第二个是一个泛型只要是一个List就行,这一般会想到是ArrayList,而他内部存储的则是Map或者继承自Map的对象,比如HashMap,这些语法都是Java的基本语法,不再详述了!这里呢是作为数据源,而且每一个ArraList中的一行就代表着呈现出来的一行,Map的键就是这一行的列名,值也是有列名的。 第三个资源文件,就是说要加载这个两列所需要的视图资源文件,你可以左边一个TextView右边一个TextView,目的在于呈现左右两列的值! 第四个参数是一个数组,主要是将Map对象中的名称映射到列名,一一对应 第五个是将第四个参数的值一一对象的显示(一一对应)在接下来的int形的id数组中,这个id数组就是LayOut的xml文件中命名id形成的唯一的int型标识符 * context 关联SimpleAdapter运行着的视图的上下文。 data 一个Map的列表。在列表中的每个条目对应列表中的一行,应该包含所有在from中指定的条目 resource 一个定义列表项目的视图布局的资源唯一标识。布局文件将至少应包含哪些在to中定义了的名称。 from 一个将被添加到Map上关联每一个项目的列名称的列表 to 应该在参数from显示列的视图。这些应该全是TextView。在列表中最初的N视图是从参数from中最初的N列获取的值。 * * 4.把 适配器 添加到ListView,并显示出来。 * @author Administrator * */ public class ListViewActivity extends Activity { ListView userList; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.listview); userList = (ListView)findViewById(R.id.listUserInfo); ArrayList> listData = new ArrayList>(); HashMap hmItem = new HashMap(); hmItem.put("userName", "张三"); hmItem.put("userPhone", "1234567890"); listData.add(hmItem); hmItem = new HashMap(); hmItem.put("userName", "李四"); hmItem.put("userPhone", "981234502"); listData.add(hmItem); hmItem = new HashMap(); hmItem.put("userName", "王五"); hmItem.put("userPhone", "5622435566221"); listData.add(hmItem); //SimpleAdapter simpleAdapter = new SimpleAdapter(this, listData, R.layout.textviewitem, new String[]{"userName","userPhone"}, new int[]{R.id.txtUserName,R.id.txtUserPhone}); //SimpleAdapter simpleAdapter = new SimpleAdapter(this, listData, android.R.layout.simple_list_item_1, new String[]{"userName","userPhone"}, new int[]{android.R.id.text1,android.R.id.text2}); //SimpleAdapter simpleAdapter = new SimpleAdapter(this, listData, android.R.layout.simple_list_item_2, new String[]{"userName","userPhone"}, new int[]{android.R.id.text1,android.R.id.text2}); String[] s = new String[2]; s[0] = "userName"; s[1] = "userPhone"; int[] i = new int[2]; i[0] = android.R.id.text1; i[1] = android.R.id.text2; SimpleAdapter sim = new SimpleAdapter(this, listData, android.R.layout.simple_list_item_1, s, i); userList.setAdapter(sim); //列表项单击事件 userList.setOnItemClickListener(new ListView.OnItemClickListener() { @Override public void onItemClick(AdapterView<!--?--> arg0, View arg1, int arg2, long arg3) { System.out.println(arg2); System.out.println(arg3); } }); //列表项选中事件 userList.setOnItemSelectedListener(new ListView.OnItemSelectedListener() { @Override public void onItemSelected(AdapterView<!--?--> arg0, View arg1, int arg2, long arg3) { // TODO Auto-generated method stub System.out.println("selected----------" +arg2); System.out.println("selected----------" +arg3); } @Override public void onNothingSelected(AdapterView<!--?--> arg0) { // TODO Auto-generated method stub } }); //列表项长按事件 userList.setOnItemLongClickListener(new ListView.OnItemLongClickListener() { @Override public boolean onItemLongClick(AdapterView<!--?--> arg0, View arg1, int arg2, long arg3) { System.out.println("long---------" + arg2); System.out.println("long---------" + arg3); return true; } }); } }
上边注释的三句话
第一句 是我们可以自定义布局文件展示数据
第二句 我们可以用内置的布局文件来展示
第三句 和第二句一样,但是效果不一样,大家运行看看就明白了
GridView
类似与手机主菜单中展示的效果,如图
网格视图控件和我们的ListView 操作很像,上边已经解释过了,这里直接贴代码了
package TSD.Jason.Example; import java.util.ArrayList; import java.util.HashMap; import android.app.Activity; import android.os.Bundle; import android.widget.GridView; import android.widget.SimpleAdapter; public class GridViewActivity extends Activity { // 定义整型数组 即图片源 private Integer[] mImageIds = { R.drawable.img1, R.drawable.img2, R.drawable.img3, R.drawable.img4, R.drawable.img5, R.drawable.img6, R.drawable.img7, R.drawable.img8, R.drawable.img1, }; @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); setContentView(R.layout.gridview); GridView gridview = (GridView) findViewById(R.id.gridview); // 生成动态数组,并且转入数据 ArrayList> lstImageItem = new ArrayList>(); for (int i = 0; i < 9; i++) { HashMap map = new HashMap(); map.put("ItemImage", mImageIds[i]);// 添加图像资源的ID map.put("ItemText", "NO." + String.valueOf(i));// 按序号做ItemText lstImageItem.add(map); } SimpleAdapter simple = new SimpleAdapter(this, lstImageItem, R.layout.gridviewitem, new String[] { "ItemImage", "ItemText" }, new int[] { R.id.ItemImage, R.id.ItemText }); gridview.setAdapter(simple); } }
好,今天就到这里,源代码已经上传到天圣达网站,大家去下载下来,动手实践下。 http://www.bj-stl.com/android.html