Android 大杂烩工程之ListView的开发2以及数据仓库开发模式

今天是放完假后工作的第一天,为了证明我不是一段幽灵代码,我给各位看客老爷们说句:祝大家节日过得愉快(过得不愉快那也是人之常情)。

我们继续来讲一讲ListView的开发,上次讲到了ListView的适配器和布局模式,今天要讲的就是简单却也适用的点击事件处理了。之前我们的界面一进去就是跟机器人对话,面向的对象始终只有机器人一个,这次我们来仿照QQ的消息界面那样有一个对象列表,点击其中一个就能进入相应的聊天界面。话不多说,先上代码:

新增一个布局文件activity_chatlist.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">

    <ImageView
        android:id="@+id/iv_chatList_icon"
        android:layout_width="40dp"
        android:layout_height="40dp"
        android:layout_marginLeft="@dimen/activity_vertical_margin"/>

    <TextView
        android:id="@+id/tv_chatList_account"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_marginLeft="@dimen/activity_vertical_margin"
        android:gravity="center"
        android:textSize="@dimen/mid_text_size"/>
</LinearLayout>

新增两个java文件ChatActivity.java

package com.teachmodel.fragment;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;

import com.teachmodel.R;
import com.teachmodel.adapter.ChatAdapter;
import com.teachmodel.bean.Chat;

import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;

/**
 * Created by windbreaker on 16/4/5.
 */
public class ChatActivity extends Activity {

    private ListView mListView;
    private List<Chat> mList;
    private ChatAdapter mChatAdapter;
    private Hashtable<String, String> ansChats;
    private EditText et_chat;
    private Button btn_chat;
    private String chatName;
    private int chatIcon;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.fragment_first);
        init();
    }

    private void init() {
        Intent intent = getIntent();
        chatName = intent.getStringExtra("account");
        chatIcon = intent.getIntExtra("icon", 0);
        et_chat = (EditText) findViewById(R.id.et);
        btn_chat = (Button) findViewById(R.id.btn);
        mListView = (ListView) findViewById(R.id.lv_chat_list);
        mList = new ArrayList<>();
        ansChats = new Hashtable<>();
        ansChats.put("Hi", "Hello");
        ansChats.put("What is your name?", "My name is DuBe.");
        ansChats.put("What?DouBi?", "Yeah....");
        ansChats.put("Ha...,How interesting", "Thank you.");
        mChatAdapter = new ChatAdapter(mList, this);
        mListView.setAdapter(mChatAdapter);
        btn_chat.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Chat mChat = new Chat();
                mChat.setName("白马秋风");
                mChat.setIcon(R.mipmap.my);
                mChat.setMessage(et_chat.getText().toString());
                mChatAdapter.addItem(mChat);
                getAns(et_chat.getText().toString());
                et_chat.setText("");
            }
        });
    }

    private void getAns(String question) {
        Chat mChat = new Chat();
        mChat.setName(chatName);
        mChat.setIcon(chatIcon);
        if (ansChats.get(question) != null) {
            mChat.setMessage(ansChats.get(question));
        } else {
            mChat.setMessage("I dont know what you ask?");
        }
        mChatAdapter.addItem(mChat);
        mListView.setSelection(mListView.getBottom());
    }

}

ChatListAdapter.java

package com.teachmodel.adapter;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;

import com.teachmodel.R;
import com.teachmodel.bean.Chat;

import java.util.List;

/**
 * Created by windbreaker on 16/4/5.
 */
public class ChatListAdapter extends BaseAdapter {
    private List<Chat> chatList;
    private LayoutInflater mLayoutInflater;

    public ChatListAdapter(List<Chat> chatList, Context context) {
        this.chatList = chatList;
        this.mLayoutInflater = LayoutInflater.from(context);
    }

    @Override
    public int getCount() {
        return chatList.size();
    }

    @Override
    public Object getItem(int position) {
        return chatList.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder mViewHolder;
        if (convertView == null) {
            convertView = mLayoutInflater.inflate(R.layout.item_chatlist, null);
            mViewHolder = new ViewHolder();
            mViewHolder.iv = (ImageView) convertView.findViewById(R.id.iv_chatList_icon);
            mViewHolder.tv = (TextView) convertView.findViewById(R.id.tv_chatList_account);
            convertView.setTag(mViewHolder);
        } else {
            mViewHolder = (ViewHolder) convertView.getTag();
        }
        mViewHolder.tv.setText(chatList.get(position).getName());
        mViewHolder.iv.setImageResource(chatList.get(position).getIcon());
        return convertView;
    }

    class ViewHolder {
        ImageView iv;
        TextView tv;
    }
}

再改一下FirstFragment.java

package com.teachmodel.fragment;

import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ListView;

import com.teachmodel.R;
import com.teachmodel.adapter.ChatListAdapter;
import com.teachmodel.bean.Chat;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by windbreaker on 16/3/23.
 */
public class FirstFragment extends Fragment {
    private View v;

    private ListView lv;
    private List<Chat> mList;
    private int[] iconLab = {R.mipmap.ic_launcher, R.mipmap.usericon, R.mipmap.my};
    private String[] nameLab = {"机器人", "管理员", "夜的风衣"};

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle
            savedInstanceState) {
        v = inflater.inflate(R.layout.activity_chatlist, null);
        init();
        initData();
        return v;
    }

    private void init() {
        lv = (ListView) v.findViewById(R.id.lv_chatList);
        lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                Intent intent = new Intent(getActivity(), ChatActivity.class);
                intent.putExtra("account", mList.get(position).getName());
                intent.putExtra("icon", mList.get(position).getIcon());
                startActivity(intent);
            }
        });
    }

    private void initData() {
        mList = new ArrayList<>();
        for (int i = 0; i < 3; i++) {
            Chat mChat = new Chat();
            mChat.setName(nameLab[i]);
            mChat.setIcon(iconLab[i]);
            mList.add(mChat);
        }
        ChatListAdapter mChatListAdapter = new ChatListAdapter(mList, getActivity());
        lv.setAdapter(mChatListAdapter);
    }

}

记得在AndroidManifest.xml注册新的activity组件:<activity android:name=".fragment.ChatActivity"/>

至此咋们运行一下,看看效果如何,请看大屏幕:

嗯哼,这略略一看,效果还不错。咋们来分析分析一下代码吧,首先是补充说一下上次没有说的适配器里的getView()这个方法。

public View getView(int position, View convertView, ViewGroup parent) {

ViewHolder mViewHolder;

if (convertView == null) {

convertView = mLayoutInflater.inflate(R.layout.item_chatlist, null);

mViewHolder = new ViewHolder();

mViewHolder.iv = (ImageView) convertView.findViewById(R.id.iv_chatList_icon);

mViewHolder.tv = (TextView) convertView.findViewById(R.id.tv_chatList_account);

convertView.setTag(mViewHolder);

} else {

mViewHolder = (ViewHolder) convertView.getTag();

}

mViewHolder.tv.setText(chatList.get(position).getName());

mViewHolder.iv.setImageResource(chatList.get(position).getIcon());

return convertView;

}

第一行代码我们就看到了这个ViewHolder内部类,这个类是用来干什么的呢?这个其实是对布局文件item_chatlist里的控件的一个抽象,这个类里有有一个ImageView和TextView 刚好对应于布局文件里的两个控件。接下来的代码则是检查是否已经存在View对象了,如果没有则重新实例化,有的话就直接使用了。这样说起来可能比较抽象。咋们打个比方:把程序比较教官,把要实例化的对象看成是一排要报名的队员。现在教官知道一共有多少人,但是不知道有多少人已经发了身份卡(ViewHolder)。所以他开始点名,也就是这个过程:

if (convertView == null) {

convertView = mLayoutInflater.inflate(R.layout.item_chatlist, null);

mViewHolder = new ViewHolder();

mViewHolder.iv = (ImageView) convertView.findViewById(R.id.iv_chatList_icon);

mViewHolder.tv = (TextView) convertView.findViewById(R.id.tv_chatList_account);

convertView.setTag(mViewHolder);

} else {

mViewHolder = (ViewHolder) convertView.getTag();

}

先判断你有没有身份卡,没有的话我发给你一张

mViewHolder = new ViewHolder();

mViewHolder.iv = (ImageView) convertView.findViewById(R.id.iv_chatList_icon);

mViewHolder.tv = (TextView) convertView.findViewById(R.id.tv_chatList_account);

这个身份卡就是我以后找你你的标志了convertView.setTag(mViewHolder);

你拿了之后,把姓名和头像给写上

mViewHolder.tv.setText(chatList.get(position).getName());

mViewHolder.iv.setImageResource(chatList.get(position).getIcon());

如果你有的话,教官根据标签要求你拿出你相应的身份卡我看看

mViewHolder = (ViewHolder) convertView.getTag();

然后再给你核对一下你的身份卡信息

mViewHolder.tv.setText(chatList.get(position).getName());

mViewHolder.iv.setImageResource(chatList.get(position).getIcon());

直到把所有的队友的检查完一遍没问题就OK了。

讲完适配器的工作原理,咋们再来讲讲ListView如何响应点击事件。

listView的点击事件是很简单的,只需要在实例化后(lv = (ListView) v.findViewById(R.id.lv_chatList);)使用这个方法

lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {

@Override

public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

//你的执行代码

Intent intent = new Intent(getActivity(), ChatActivity.class);

intent.putExtra("account", mList.get(position).getName());

intent.putExtra("icon", mList.get(position).getIcon());

startActivity(intent);

}

});

就可以处理点击事件了。这里的position就是你点击的列表的第几项。

就这样,ListView的讲解就先到这里。我们接下来讲讲数据仓库的设计模式。

再讲这个概念之前,我们先来讲讲我们的程序,如你所见的,我们程序里的所有数据都是在activity里生成的,也就是说activity不仅仅要定义变量,管理变量,获取控件,处理控件的监听事件还要生成并且处理数据,管理跳转逻辑,管理自身的生命周期等等。如果让一个人来处理这些事情,我想那个人即使不会跳楼,也会不胜其烦。同样,这样对于activity来说也是不好的,因为他管理的东西太多太杂了。那咋办呢?难道也要上天吗?与太阳肩并肩?对于这个问题,我们只要做一下职能分离就好,就是把数据生成和数据处理的功能单独出来,activity只负责获取数据集合就OK了,这就是所谓的数据仓库设计了。不瞎逼逼,咋们来看看具体实现。

新增一个java文件:ChatLab.java

package com.teachmodel.bean;

import com.teachmodel.R;

import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;

/**
 * Created by windbreaker on 16/4/5.
 */
public class ChatLab {

    private static ChatLab mChatLab;
    private static List<Chat> mList;
    private Hashtable<String, String> ansChats;
    private int[] iconLab = {R.mipmap.ic_launcher, R.mipmap.usericon, R.mipmap.my};
    private String[] nameLab = {"机器人", "管理员", "夜的风衣"};

    private ChatLab() {

        mList = new ArrayList<>();
        for (int i = 0; i < 3; i++) {
            Chat mChat = new Chat();
            mChat.setName(nameLab[i]);
            mChat.setIcon(iconLab[i]);
            mList.add(mChat);
        }

        ansChats = new Hashtable<>();
        ansChats.put("Hi", "Hello");
        ansChats.put("What is your name?", "My name is DuBe.");
        ansChats.put("What?DouBi?", "Yeah....");
        ansChats.put("Ha...,How interesting", "Thank you.");
    }

    public static ChatLab getInstance() {
        if (mChatLab == null) {
            mChatLab = new ChatLab();
        }
        return mChatLab;
    }

    public List<Chat> getList() {
        return mList;
    }

    public Hashtable<String, String> getAns() {
        return ansChats;
    }
}

然后修改一下FirstFragment.java和ChatActivity.java

package com.teachmodel.fragment;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;

import com.teachmodel.R;
import com.teachmodel.adapter.ChatAdapter;
import com.teachmodel.bean.Chat;
import com.teachmodel.bean.ChatLab;

import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;

/**
 * Created by windbreaker on 16/4/5.
 */
public class ChatActivity extends Activity {

    private ListView mListView;
    private List<Chat> mList;
    private ChatAdapter mChatAdapter;
    private EditText et_chat;
    private Button btn_chat;
    private String chatName;
    private int chatIcon;
    private Hashtable<String, String> ansChats;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.fragment_first);
        init();
        initData();
    }

    private void init() {
        et_chat = (EditText) findViewById(R.id.et);
        btn_chat = (Button) findViewById(R.id.btn);
        mListView = (ListView) findViewById(R.id.lv_chat_list);
    }

    private void initData() {
        Intent intent = getIntent();
        chatName = intent.getStringExtra("account");
        chatIcon = intent.getIntExtra("icon", 0);
        ansChats = ChatLab.getInstance().getAns();
        mList = new ArrayList<>();

        mChatAdapter = new ChatAdapter(mList, this);
        mListView.setAdapter(mChatAdapter);
        btn_chat.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Chat mChat = new Chat();
                mChat.setName("白马秋风");
                mChat.setIcon(R.mipmap.my);
                mChat.setMessage(et_chat.getText().toString());
                mChatAdapter.addItem(mChat);
                getAns(et_chat.getText().toString());
                et_chat.setText("");
            }
        });
    }

    private void getAns(String question) {
        Chat mChat = new Chat();
        mChat.setName(chatName);
        mChat.setIcon(chatIcon);
        if (ansChats.get(question) != null) {
            mChat.setMessage(ansChats.get(question));
        } else {
            mChat.setMessage("I dont know what you ask?");
        }
        mChatAdapter.addItem(mChat);
        mListView.setSelection(mListView.getBottom());
    }

}
package com.teachmodel.fragment;

import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ListView;

import com.teachmodel.R;
import com.teachmodel.adapter.ChatListAdapter;
import com.teachmodel.bean.Chat;
import com.teachmodel.bean.ChatLab;

import java.util.List;

/**
 * Created by windbreaker on 16/3/23.
 */
public class FirstFragment extends Fragment {
    private View v;

    private ListView lv;
    private List<Chat> mList;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle
            savedInstanceState) {
        v = inflater.inflate(R.layout.activity_chatlist, null);
        init();
        initData();
        return v;
    }

    private void init() {
        lv = (ListView) v.findViewById(R.id.lv_chatList);
        lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                Intent intent = new Intent(getActivity(), ChatActivity.class);
                intent.putExtra("account", mList.get(position).getName());
                intent.putExtra("icon", mList.get(position).getIcon());
                startActivity(intent);
            }
        });
    }

    private void initData() {
        mList = ChatLab.getInstance().getList();
        ChatListAdapter mChatListAdapter = new ChatListAdapter(mList, getActivity());
        lv.setAdapter(mChatListAdapter);
    }

}

运行一下即可得出上图的结果。然后有的人也许会问这种设计模式有什么用?难道能提高程序的运行效率?这个也许没有提高程序的运行效率,反而还有可能略略影响了你的程序运行效率。说到这里,你也许会说我是个坑比。对此,我只能说,为什么会有这种设计模式呢?其实程序的所有设计模式都是以方便管理和编程为目的的,对于运行效率的提高主要是与你编程的算法有关。对于之前的无模式编程,如果你只有几行代码,其实有没有设计模式都无所谓了。但是你有几千甚至上万行代码的话,设计模式的就显得尤其重要。以数据仓库为例,如果你的程序有很多地方都要用到相同的数据,每个地方都要生成并且初始化数据,那不如把数据和调用数据的方法集中在一起,要用的数据的地方直接调用数据仓库里的数据就行了,自己也不用去管理数据了。这样是十分有利于整理思路和修改代码的。

今天就说到这里了,感谢各位看客老爷们的围观。

工程包链接点击打开链接

时间: 2024-11-09 21:14:01

Android 大杂烩工程之ListView的开发2以及数据仓库开发模式的相关文章

【转】Android自定义Adapter的ListView的思路及代码

原文网址:http://www.jb51.net/article/37236.htm Android自定义Adapter的ListView的思路及代码,需要的朋友可以参考一下 在开发中,我们经常使用到ListView这个控件.Android的API也提供了许多创建ListView适配器的快捷方式.例如ArrayAdapter.SimpleAdapter和SimpleCursorAdapter等.但你是否发现,如果采用这些系统自带的适配器,对于事件的响应只能局限在一个行单位.假设一行里面有一个按钮

软件工程之“个人附加题”

(1) 你认为本门课程需要在哪里进行改进,具体措施有哪些,包括:时间进度安排,项目难度等均可: 对于皱欣老师的软件工程之“构建之法”,说实话,我并没有权利 去评价,不过对于上了一个学期的课本,,我简述一下个人对这本书的看法:首先书上的理论知识太少,我们学生并不知道怎么去学,虽然课本结合了很多的故事,不过当我们将课本结合实际时,并不知道怎么入手.而且作业有点偏多,有的项目难度偏大,比如最后一个团队项目,作为大三学生,我们拿得出手的也只有C++,对于使用安卓,有点迷茫.时间进度在减少一些项目之后应该

【Android】Android软件开发之ListView 详解

原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://xys289187120.blog.51cto.com/3361352/657171 ListView的使用方法 ListView是Android软件开发中非常重要组件之一,基本上是个软件基本都会使用ListView ,今天我通过一个demo来教大家怎么样使用ListView组件 绘制出漂亮的列表,说道ListView就不得不说Adapter适配器,因为只有通过Adapter才可

【Android进阶】关于ListView中item与控件抢夺焦点的那些事

在开发中,listview可以说是我们使用最频繁的控件之一了,但是关于listview的各种问题也是很多.当我们使用自定义布局的Listview的时候,如果在item的布局文件里面存在Button或者是CheckBox等控件以及其子类控件的时候,经常会碰到各种控件的点击事件冲突的情况,那么我们如何来处理Listview中这种控件之间焦点冲突的情况呢? 我们以item存在一个Button控件为例 首先,加入我们不设置任何关于焦点的属性,比如focus等,代码如下 @Override public

FrameWork逆向工程之MotioPI

在BI项目建设的过程中我们一般都是有备份的,而且这个是必须有的!特别是例如ETL Model,还有Data Model这一类的元数据,这些东西如果我们没有备份,而恰好的我们的开发模型又在某一天离我们而去,这个时候我们就捉急了,今天我们就说一下Framework的逆向工程,如何利用Cognos发布的数据包逆向的得到Framework Manager创建的模型文件?让你再捉急,下面我们就开始吧. 一:首先我们要获取一个工具,这个工具就是叫做MotioPI 1.1如何获取工具,我们先看一下下面的连接

Android Demo之旅 ListView底部添加加载更多按钮实现数据分页

在我们的实际项目中,数据应该说是很多的,我们的ListView不可能一下子把数据全部加载进来,我们可以当滚动条滚动到ListView的底部的时候,给一个更多的提示,当我们点击它即加载下一页的数据,相当与我们的分页效果,参考网上的东西,写了一个小小的demo,并总结了一些知识点,功能图如下:    源代码下载地址:http://download.csdn.net/detail/harderxin/7762625 掌握知识点: 1)自定义Adapter,将数据和ListView绑定起来 2)理解La

[Android]使用RecyclerView替代ListView(三)

以下内容为原创,转载请注明: 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/4268097.html  这次来使用RecyclerView实现PinnedListView的效果,效果很常见: 开发的代码建立在上一篇([Android]使用RecyclerView替代ListView(二):http://www.cnblogs.com/tiantianbyconan/p/4242541.html)基础之上. 修改布局如下: 1 <?xml vers

Android Studio添加Parcelable序列化小工具(快速提高开发效率)

Android Studio添加Parcelable序列化小工具(快速提高开发效率) Android Studio是google专门为开发Android提供的开发工具,在它内部可以直接的添加一些非常好用的开发小工具,这里就讲解怎样添加这些小工具,并且向大家推荐一个非常有用的对象传递时,必须要把对象序列化的接口Parcelable小工具; 这里先介绍下 Android中实现序列化的两个选择:一是实现Serializable接口(是JavaSE本身就支持的),一是实现Parcelable接口(是An

android学习笔记--android启动过程之init.rc文件浅析

1.  init.rc文件结构文件位置:init.c  : /system/core/initinit.rc  : /system/core/rootdir 首先init.rc文件是以模块为单位的,每个模块里的内容都是一起执行的,模块分为3种类型:on.service.import.我们可以看下init.rc文件是怎么写的:1.import import /init.usb.rc import /init.${ro.hardware}.rc import /init.trace.rc 上面的内容