zoukankan      html  css  js  c++  java
  • Android开发教程 葵花宝典第六层 控件之 Dialog ListView GridView

    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”按钮。
    *
    */
    publicclass DialogActivity extends Activity {
    Button btn1;
    ProgressDialog p;
    @Override
    protectedvoid onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.diaolg);
    btn1
    = (Button)findViewById(R.id.btnDialog);
    btn1.setOnClickListener(
    new Button.OnClickListener() {
    @Override
    publicvoid 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
    publicvoid onClick(DialogInterface dialog, int which) {
    ShowLoginDialog();
    }
    });
    dialog.setNegativeButton(
    "取消", new DialogInterface.OnClickListener() {
    @Override
    publicvoid onClick(DialogInterface dialog, int which) {
    DialogActivity.
    this.finish();
    }
    });
    dialog.show();
    }
    });
    }
    }

    以上代码是我们第一张对话框的效果实现代码,大家发现是不是挺简单,当我们单击确定按钮后,将调用一个叫做ShowLoginDialog的方法。

    这个方法马上会贴出来,在这里我还是要强调下,大家在写代码的时候一定要有一个良好的编程思想,将功能拆分,降低代码的耦合度,一个方法只做一件事情,不要一股脑的将代码写到一个方法里。希望大家记得。

    privatevoid 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
    publicvoid onClick(DialogInterface dialog, int which) {
    DialogWait();
    }
    });
    builder.setNegativeButton(
    "取消", new DialogInterface.OnClickListener() {
    @Override
    publicvoid onClick(DialogInterface dialog, int which) {
    DialogActivity.
    this.finish();
    }
    });
    builder.show();
    }

    上边被标注的代码是为了让Dialog中的内容部分显示我们自定义的布局文件,通过builder对象的setView方法就可以将R.layout.dialogview这个布局文件绑定到对话框中。

    布局文件代码如下

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation
    ="vertical"
    android:layout_width
    ="fill_parent"
    android:layout_height
    ="fill_parent"
    >
    <TextView
    android:layout_width
    ="fill_parent"
    android:layout_height
    ="wrap_content"
    android:text
    ="账号"
    />
    <EditText
    android:id
    ="@+id/txtUserName"
    android:layout_width
    ="fill_parent"
    android:layout_height
    ="wrap_content"
    android:hint
    ="请输入账号"
    />
    <TextView
    android:layout_width
    ="fill_parent"
    android:layout_height
    ="wrap_content"
    android:text
    ="密码"
    />
    <EditText
    android:id
    ="@+id/txtUserPwd"
    android:layout_width
    ="fill_parent"
    android:layout_height
    ="wrap_content"
    android:password
    ="true"
    android:hint
    ="请输入密码"
    />
    </LinearLayout>

    第三个等待效果的对话框是如何实现的呢?上边我们调用了一个方法叫做 DialogWait

    privatevoid DialogWait()
    {
    p
    = ProgressDialog.show(DialogActivity.this, "正在登录", "请稍后...", true);
    new Thread(){
    publicvoid 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"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation
    ="vertical" android:layout_width="fill_parent"
    android:layout_height
    ="fill_parent" android:scrollbars="vertical">
    <ListView
    android:id
    ="@+id/listCity"
    android:layout_width
    ="fill_parent"
    android:layout_height
    ="fill_parent"
    android:scrollbars
    ="vertical"/>
    </LinearLayout>

    Java代码如下

    privatevoid 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();
    }

    privatevoid GetCity()
    {
    System.out.println(
    "asd");
    ArrayList
    <HashMap<String, String>> listData =new ArrayList<HashMap<String,String>>();
    HashMap
    <String, String> hmItem =new HashMap<String, String>();
    hmItem.put(
    "city", "北京");
    listData.add(hmItem);
    hmItem
    =new HashMap<String, String>();
    hmItem.put(
    "city", "上海");
    listData.add(hmItem);
    hmItem
    =new HashMap<String, String>();
    hmItem.put(
    "city", "深圳");
    listData.add(hmItem);
    hmItem
    =new HashMap<String, String>();
    hmItem.put(
    "city", "天津");
    listData.add(hmItem);
    hmItem
    =new HashMap<String, String>();
    hmItem.put(
    "city", "南京");
    listData.add(hmItem);
    hmItem
    =new HashMap<String, String>();
    hmItem.put(
    "city", "武汉");
    listData.add(hmItem);
    hmItem
    =new HashMap<String, String>();
    hmItem.put(
    "city", "江苏");
    listData.add(hmItem);
    hmItem
    =new HashMap<String, String>();
    hmItem.put(
    "city", "宁波");
    listData.add(hmItem);
    SimpleAdapter sim
    =new SimpleAdapter(this, listData, android.R.layout.simple_list_item_1, new String[]{"city"}, newint[]{android.R.id.text1});
    listCity.setAdapter(sim);
    }

    直接调用ShowLoginDialog方法即可。注意标注的代码,需要先获取ListView。这里已经用到了ListView,如果不太懂下边就将ListView,大家注意看。

    ListView

    上边已经展示过它运行的效果了,这里就不展示运行效果了。

    那么要使用ListView需要哪些步骤呢?举一个例子,可能不太恰当

    冰箱里没有鸡蛋了,我们从家里提了一个篮子去超市买鸡蛋。就是这样的一个过程。我们来分解下这个步骤

    冰箱 == 展示数据 == ListView

    超市里的鸡蛋 == 数据 == ArrayList<E> 泛型集合

    篮子 == 适配器 == SimpleAdapter

    我们应该将 鸡蛋(ArrayList<E>) 装到 篮子里(SimpleAdapter) 然后提回家 放到 冰箱里( ListView)

    分解完步骤后,那么我们看看如何用代码实现这个过程。

    ListView userList; //声明一个ListView对象(冰箱)

    userList = (ListView)findViewById(R.id.listUserInfo); //获取布局文件中的ListView控件赋值给ListView对象

    ArrayList<HashMap<String, String>> listData = new ArrayList<HashMap<String,String>>(); //数据源 (超市装鸡蛋的盒子)

    HashMap<String, String> hmItem = new HashMap<String, String>(); //需要一个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<HashMap<String, String>> listData = new ArrayList<HashMap<String,String>>();
    *
    * 2.使用 一维或多维 动态数组 保存数据;
    * HashMap<String, String> hmItem = new HashMap<String, String>();
    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
    *
    */
    publicclass ListViewActivity extends Activity {

    ListView userList;
    @Override
    protectedvoid onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.listview);
    userList
    = (ListView)findViewById(R.id.listUserInfo);

    ArrayList
    <HashMap<String, String>> listData =new ArrayList<HashMap<String,String>>();

    HashMap
    <String, String> hmItem =new HashMap<String, String>();
    hmItem.put(
    "userName", "张三");
    hmItem.put(
    "userPhone", "1234567890");
    listData.add(hmItem);


    hmItem
    =new HashMap<String, String>();
    hmItem.put(
    "userName", "李四");
    hmItem.put(
    "userPhone", "981234502");
    listData.add(hmItem);




    hmItem
    =new HashMap<String, String>();
    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 =newint[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
    publicvoid onItemClick(AdapterView<?> arg0, View arg1, int arg2,
    long arg3) {
    System.out.println(arg2);
    System.out.println(arg3);
    }
    });

    //列表项选中事件
    userList.setOnItemSelectedListener(new ListView.OnItemSelectedListener() {

    @Override
    publicvoid 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
    publicvoid onNothingSelected(AdapterView<?> arg0) {
    // TODO Auto-generated method stub

    }
    });

    //列表项长按事件
    userList.setOnItemLongClickListener(new ListView.OnItemLongClickListener() {

    @Override
    publicboolean onItemLongClick(AdapterView<?> arg0, View arg1,
    int arg2, long arg3) {
    System.out.println(
    "long---------"+ arg2);
    System.out.println(
    "long---------"+ arg3);
    returntrue;
    }
    });
    }
    }

    上边注释的三句话

    第一句 是我们可以自定义布局文件展示数据

    第二句 我们可以用内置的布局文件来展示

    第三句 和第二句一样,但是效果不一样,大家运行看看就明白了

     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;

    publicclass 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
    protectedvoid onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);
    setContentView(R.layout.gridview);
    GridView gridview
    = (GridView) findViewById(R.id.gridview);
    // 生成动态数组,并且转入数据
    ArrayList<HashMap<String, Object>> lstImageItem =new ArrayList<HashMap<String, Object>>();

    for (int i =0; i <9; i++) {
    HashMap
    <String, Object> map =new HashMap<String, Object>();
    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" }, newint[] {
    R.id.ItemImage, R.id.ItemText });
    gridview.setAdapter(simple);
    }
    }

    好,今天就到这里,源代码已经上传到天圣达网站,大家去下载下来,动手实践下。 http://www.tsdapp.com/android.html

  • 相关阅读:
    一个基于C++11的定时器队列(timerfd,poll实现)
    Mysql学习(一)添加一个新的用户并用golang操作Mysql
    epoll使用详解
    基于C++11实现线程池的工作原理
    ubuntu18.04初始化配置
    muduo网络库学习笔记(五) 链接器Connector与监听器Acceptor
    muduo网络库学习笔记(四) 通过eventfd实现的事件通知机制
    muduo网络库学习笔记(三)TimerQueue定时器队列
    关于 JavaScript 的 null 和 undefined,判断 null 的真实类型
    vue 双向数据绑定原理
  • 原文地址:https://www.cnblogs.com/jasoncc/p/2118734.html
Copyright © 2011-2022 走看看