• Android控件开发——ListView


    上篇博客解决了Android客户端通过WebService与服务器端程序进行交互的问题,这篇博客重点关注两个问题,一个是Android应用程序如何与本机文件型数据库SQLite进行交互,另一问题则是如何在ListView中按照我们想要的界面效果进行展示。限于篇幅这篇重点讲ListView,下篇博客重点阐述SQLite。

    ListView是一个常用的数据显示控件,假设我们要做一个简单的界面,如图所示。

    这张图是我直接从Android平板电脑(Android 4.2.2)上面截图下来的,就是一个普通的列表,能够点击报名按钮获取到对应行的信息。

    这里面显示的数据是我从SQLite数据库中查询出来的,封装的类的代码如下:

    public class MyDatabaseHelper extends SQLiteOpenHelper {
     
        private static final String name = "mydb.db";// SQLite数据库文件名
        private static final int version = 1;// SQLite数据库版本号
     
        public MyDatabaseHelper(Context context) {
            super(context, name, null, version);
        }
     
        @SuppressLint("SimpleDateFormat")
        @Override
        public void onCreate(SQLiteDatabase db) {
            try {
                // 开启事务
                db.beginTransaction();
                String sql = "create table jobInfo (name varchar(20),"
                        + "num integer," + "date varchar(10),"
                        + "description text)";
                db.execSQL(sql);
     
                //测试插入10条数据
                for (int i = 0; i < 10; i++) {
                    db.execSQL(
                            "insert into jobInfo(name,num,date,description)values(?,?,?,?)",
                            new Object[] {
                                    "name" + i,
                                    i,
                                    new SimpleDateFormat("yyyy-MM-dd")
                                            .format(new Date()), "description" + i });
                }
     
                // 标识事务成功
                db.setTransactionSuccessful();
            } finally {
                // 结束事务
                db.endTransaction();
            }
        }
     
        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
            //数据库升级操作
        }
    }

    在需要创建数据库、插入数据的地方都可以实例化MyDatabaseHelper这个类,关于更多的SQLite的细节下篇博客将会进行详细的说明。

     activity_main.xml布局文件:

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingBottom="@dimen/activity_vertical_margin"
        android:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:paddingTop="@dimen/activity_vertical_margin" >
     
        <LinearLayout
            android:id="@+id/head"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal" >
     
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="岗位名称"
                android:textSize="24sp"
                android:width="150dip" />
     
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="岗位数量"
                android:textSize="24sp"
                android:width="150dip" />
     
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="发布日期"
                android:textSize="24sp"
                android:width="150dip" />
     
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="岗位描述"
                android:textSize="24sp"
                android:width="550dip" />
        </LinearLayout>
     
        <ListView
            android:id="@id/android:list"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@+id/head" >
        </ListView>
     
    </RelativeLayout>

    可以看到这是一个相对布局,里面有一个线性布局,线性布局里面又放置了4个TextView作为ListView数据的标题。下面直接是一个ListView控件,由于这是相对布局,为了让ListView显示在“表头”下面,我们设置了layout_below属性。此外要注意ListView的id的写法。

    接着按照界面的要求,我们准备一下ListView加载布局文件的内容,我们起名为:list_item.xml。

    list_item.xml:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal" >
     
        <TextView
            android:id="@+id/name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="24sp"
            android:width="150dip" />
     
        <TextView
            android:id="@+id/num"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="24sp"
            android:width="150dip" />
     
        <TextView
            android:id="@+id/date"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="24sp"
            android:width="150dip" />
     
        <TextView
            android:id="@+id/description"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="24sp"
            android:width="550dip" />
     
        <Button
            android:id="@+id/btn"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:focusable="false"
            android:focusableInTouchMode="false"
            android:text="报名"
            android:width="150dip"
            android:textSize="24sp" />
     
    </LinearLayout>

    这也是一个普通的线性布局,设置orientation为horizontal(水平)。

    布局文件准备好,下面我们准备写代码了。

    我们让MainActivity这个类继承自ListActivity,完整的代码如下:

    public class MainActivity extends ListActivity {
     
        List<Map<String, Object>> list;
     
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
     
            list = new ArrayList<Map<String, Object>>();
            //初始化SQLite数据库操作类对象
            MyDatabaseHelper dbHelper = new MyDatabaseHelper(MainActivity.this);
            
            //查询数据库返回Cursor(游标)对象
            Cursor cursor = dbHelper.getReadableDatabase().query("jobInfo",
                    new String[] { "name", "num", "date", "description" }, null,
                    null, null, null, "name");
            
            //将结果集封装到List<Map<String,Object>>数据结构当中
            while (cursor.moveToNext()) {
                Map<String, Object> map = new HashMap<String, Object>();
                map.put("name", cursor.getString(0));
                map.put("num", cursor.getInt(1));
                map.put("date", cursor.getString(2));
                map.put("description", cursor.getString(3));
                map.put("btn", R.drawable.ic_launcher);
                list.add(map);
            }
            //查询完毕,记得及时关闭数据库链接
            cursor.close();
            MyButtonAdapter adapter = new MyButtonAdapter(MainActivity.this, list,
                    R.layout.list_item, new String[] { "name", "num", "date",
                            "description", "btn" }, new int[] { R.id.name,
                            R.id.num, R.id.date, R.id.description, R.id.btn });
     
            //给ListView设置数据填充适配器
            ListView listView = (ListView) findViewById(android.R.id.list);
            listView.setAdapter(adapter);
        }
     
        @Override
        protected void onListItemClick(ListView l, View v, int position, long id) {
            //ListView的
            @SuppressWarnings("unchecked")
            Map<String, Object> map = (HashMap<String, Object>) l
                    .getItemAtPosition(position);
            Toast.makeText(MainActivity.this,
                    "您点击了:" + map.get("name").toString() + "岗位!",
                    Toast.LENGTH_SHORT).show();
        }
        
        public class MyButtonAdapter extends BaseAdapter {
     
            private class ButtonViewHolder {
                TextView name;
                TextView num;
                TextView date;
                TextView description;
                Button btn;
            }
     
            private Context mContext;
            private List<Map<String, Object>> mList;
            private ButtonViewHolder holder;
            private LayoutInflater mInflater;
            private String[] keyString;
            private int[] valueViewID;
     
            // 构造函数初始化变量
            public MyButtonAdapter(Context context, List<Map<String, Object>> list,
                    int resource, String[] from, int[] to) {
                this.mContext = context;
                this.mList = list;
     
                // 获得布局文件对象
                mInflater = (LayoutInflater) context
                        .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                keyString = new String[from.length];
                valueViewID = new int[to.length];
     
                // 复制数组
                System.arraycopy(from, 0, keyString, 0, from.length);
                System.arraycopy(to, 0, valueViewID, 0, to.length);
            }
     
            @Override
            public int getCount() {
                return list.size();
            }
     
            @Override
            public Object getItem(int position) {
                return list.get(position);
            }
     
            /**
             * 从list中移除某一项
             * 
             * @param position
             */
            public void removeItem(int position) {
                list.remove(position);
                // 通知数据集已改变,请求自刷新
                this.notifyDataSetChanged();
            }
     
            @Override
            public long getItemId(int position) {
                return position;
            }
     
            @Override
            public View getView(int position, View convertView, ViewGroup parent) {
                if (convertView != null) {
                    holder = (ButtonViewHolder) convertView.getTag();
                } else {
                    convertView = mInflater.inflate(R.layout.list_item, null);
                    holder = new ButtonViewHolder();
                    holder.name = (TextView) convertView
                            .findViewById(valueViewID[0]);// 岗位名称
                    holder.num = (TextView) convertView
                            .findViewById(valueViewID[1]);// 岗位数量
                    holder.date = (TextView) convertView
                            .findViewById(valueViewID[2]);// 发布日期
                    holder.description = (TextView) convertView
                            .findViewById(valueViewID[3]);// 岗位描述
                    holder.btn = (Button) convertView.findViewById(valueViewID[4]);// 报名按钮
                    convertView.setTag(holder);
                }
                Map<String, Object> appInfo = mList.get(position);
                if (appInfo != null) {
                    String aname = (String) appInfo.get(keyString[0]);
                    Integer anum = (Integer) appInfo.get(keyString[1]);
                    String adate = (String) appInfo.get(keyString[2]);
                    String adescription = (String) appInfo.get(keyString[3]);
                    holder.name.setText(aname);
                    holder.num.setText(anum + "");
                    holder.date.setText(adate);
                    holder.description.setText(adescription);
     
                    // 报名按钮事件
                    holder.btn.setOnClickListener(new lvButtonListener(position));
                }
                return convertView;
            }
     
            class lvButtonListener implements OnClickListener {
                private int position;
     
                lvButtonListener(int pos) {
                    position = pos;
                }
     
                @Override
                public void onClick(View v) {
                    int vid = v.getId();
                    if (vid == holder.btn.getId()) {
                        String result = "" + "岗位名称:"
                                + list.get(position).get("name") + "
    " + "岗位人数:"
                                + list.get(position).get("num") + "
    " + "发布日期:"
                                + list.get(position).get("date") + "
    " + "岗位描述:"
                                + list.get(position).get("description") + "
    ";
     
                        new AlertDialog.Builder(MainActivity.this)
                                .setTitle("提示")
                                .setIcon(R.drawable.ic_launcher)
                                .setMessage(result + "
    " + "您确定要申请该岗位吗?")
                                .setPositiveButton(R.string.positive,
                                        new DialogInterface.OnClickListener() {
                                            @Override
                                            public void onClick(
                                                    DialogInterface dialog,
                                                    int which) {
                                                Toast toast = Toast
                                                        .makeText(
                                                                MainActivity.this,
                                                                "您点击了"
                                                                        + getResources()
                                                                                .getString(
                                                                                        R.string.positive)
                                                                        + "按钮,申请了"
                                                                        + list.get(
                                                                                position)
                                                                                .get("name")
                                                                        + "的岗位!",
                                                                Toast.LENGTH_SHORT);
                                                toast.setGravity(Gravity.CENTER, 0,
                                                        0);
                                                toast.show();
                                            }
                                        })
                                .setNegativeButton(R.string.negative,
                                        new DialogInterface.OnClickListener() {
                                            @Override
                                            public void onClick(
                                                    DialogInterface dialog,
                                                    int which) {
                                                Toast toast = Toast
                                                        .makeText(
                                                                MainActivity.this,
                                                                "您点击了"
                                                                        + getResources()
                                                                                .getString(
                                                                                        R.string.negative)
                                                                        + "按钮",
                                                                Toast.LENGTH_SHORT);
                                                toast.setGravity(Gravity.CENTER, 0,
                                                        0);
                                                toast.show();
                                            }
                                        }).create().show();
                        // 如果要删除行,可以调用此方法
                        // removeItem(position);
                    }
                }
            }
        }
    }

    上面的代码有几个知识点需要注意:

     1、SQLite数据库的查询操作

    我们通过getReadableDatabase().query方法执行了查询操作,返回Cursor(游标,与JDBC中的ResultSet类似)对象。

    2、ListView控件使用(重点)

    我们参考了SimpleAdapter默认的构造函数的方法,创建了自定义的MyButtonAdapter类,在显示数据的同时,能够给每一行的按钮绑定点击事件。

    3、弹出提示框

    弹出提示框的代码很长,完全可以封装到一个方法中,简化代码。这里完整的列出来,目的就是体验一下设计思路。经过观察我们发现,这就是所谓的“链式编程”,可以通过连续的".",设置参数(控制显示效果)。

    strings.xml:

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <string name="positive">确定</string>
        <string name="negative">取消</string>
    </resources>

    最终在pad上面的执行效果如下:

  • 相关阅读:
    成功在C#和VB中将shp转换为CAD
    java 提取字符串中的数字
    java 通用文件下载 excel,pdf,word,jpg,exe,rar
    java org 写excel
    java 通用文件下载 excel,pdf,word,jpg
    重建MDB空间网格大小的工具
    redis5.0 Cluster集群搭建
    选中对象【WPF】自定义控件之依赖属性
    成员函数对象类的const和非const成员函数的重载
    设备注册Linux加载DTS设备节点的过程(以高通8974平台为例)
  • 原文地址:https://www.cnblogs.com/guwei4037/p/5582939.html
Copyright © 2020-2023  润新知