Android 大杂烩工程之ListView的开发2以及数据仓库开发模式
Posted WindAndHorse
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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);
}
}
运行一下即可得出上图的结果。然后有的人也许会问这种设计模式有什么用?难道能提高程序的运行效率?这个也许没有提高程序的运行效率,反而还有可能略略影响了你的程序运行效率。说到这里,你也许会说我是个坑比。对此,我只能说,为什么会有这种设计模式呢?其实程序的所有设计模式都是以方便管理和编程为目的的,对于运行效率的提高主要是与你编程的算法有关。对于之前的无模式编程,如果你只有几行代码,其实有没有设计模式都无所谓了。但是你有几千甚至上万行代码的话,设计模式的就显得尤其重要。以数据仓库为例,如果你的程序有很多地方都要用到相同的数据,每个地方都要生成并且初始化数据,那不如把数据和调用数据的方法集中在一起,要用的数据的地方直接调用数据仓库里的数据就行了,自己也不用去管理数据了。这样是十分有利于整理思路和修改代码的。
今天就说到这里了,感谢各位看客老爷们的围观。
工程包链接点击打开链接
以上是关于Android 大杂烩工程之ListView的开发2以及数据仓库开发模式的主要内容,如果未能解决你的问题,请参考以下文章
Android 大杂烩工程之ListView的开发2以及数据仓库开发模式
Android 大杂烩工程之ListView的开发2以及数据仓库开发模式