智能机器人“小昆”的实现(五)MainActivty的实现及项目结束
好了,一切准备工作都完成了,下面我们就可以真正的编写MainActivity了。在MainActivity中,我们要为ListView设定适配器,并为发送按钮设定点击事件。我们的逻辑就是点击发送按钮,就会将发送的消息显示在ListView中,同时获取服务器返回的消息也显示的ListView中。如果你经常写ListView的实现,这对你来说应该不是难点。注意为了实现ListView子项的两种布局,我们使用BaseAdapter。好了,废话不多说,直接进入代码。好多东西,其实在代码以及代码注释中写的很清楚了。
一、适配器编写
如果不知道怎么写两种子项布局的ListView,应该好好学习这段代码。如下:
package com.fuly.kun; import java.text.SimpleDateFormat;
import java.util.List; import com.fuly.kun.bean.ChatMsg; import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView; //ListView的适配器
//这里主要注意当子项有不同的布局方式时,代码怎么编写
public class MyAdapter extends BaseAdapter{ private List<ChatMsg> mDatas;
private LayoutInflater inflater; public MyAdapter(Context context, List<ChatMsg> datas) { this.mDatas = datas; inflater = LayoutInflater.from(context); } //该方法用来获取不同的view的id号
public int getItemViewType(int position) { ChatMsg cm = mDatas.get(position);
if(cm.getType() == ChatMsg.Type.INPUT){
return 0;//将输入消息的子项布局编号为0
}else{
return 1;//将显示服务器消息的子项布局编号为1
} } //该方法用来获取共有多少条数据
public int getCount() { return mDatas.size();
} //该方法用来获取具体位置的数据对象
public Object getItem(int position) { return mDatas.get(position);
} //该方法用来获取位置的序号,直接返回位置即可
public long getItemId(int position) { return position;
} //该方法用来告诉ListView的子项共有几种布局
//我们这里有两种
public int getViewTypeCount() { return 2;
} //下面开始真的为子项编写具体的view
public View getView(int position, View convertView, ViewGroup parent) { ViewHolder vh = null; if(convertView == null){
vh = new ViewHolder(); //根据不同的标号获得不同的子项布局
if(getItemViewType(position) == 0){
convertView = inflater.inflate(R.layout.item_in,parent,false);
vh.mText = (TextView) convertView.findViewById(R.id.tv_inmsg);
}
if(getItemViewType(position) == 1){
convertView = inflater.inflate(R.layout.item_out,parent,false);
vh.mDate = (TextView) convertView.findViewById(R.id.tv_out_date);
vh.mText = (TextView) convertView.findViewById(R.id.tv_outmsg);
} convertView.setTag(vh);
}else{
vh = (ViewHolder) convertView.getTag();
} ChatMsg cm = mDatas.get(position); //设置数据
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
if(vh.mDate != null){
vh.mDate.setText(df.format(cm.getDate()));
}
vh.mText.setText(cm.getMsg()); return convertView;
} class ViewHolder{ private TextView mDate;
private TextView mText;
} }
二、MainActivity的编写
废话不多说了,直接上代码:
package com.fuly.kun; import java.util.ArrayList;
import java.util.Date;
import java.util.List; import com.fuly.kun.bean.ChatMsg;
import com.fuly.kun.bean.ChatMsg.Type;
import com.fuly.kun.util.HttpUtil; import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ListView;
import android.widget.Toast; public class MainActivity extends Activity { private ListView lv;
private MyAdapter mAdapter;
private List<ChatMsg> mDatas = new ArrayList<ChatMsg>(); private ImageButton btn;
private EditText et; private Handler mHandler = new Handler(){ public void handleMessage(android.os.Message msg) { ChatMsg cms= (ChatMsg) msg.obj;
mDatas.add(cms);//加入到数据集
mAdapter.notifyDataSetChanged();//通知lv更新
lv.setSelection(mDatas.size()-1);//将lv设定为显示最后一项
};
}; protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); initView();//初始化数据等 btn.setOnClickListener(new OnClickListener() { public void onClick(View v) { if(et.getText().toString().equals("")){
Toast.makeText(MainActivity.this, R.string.info, Toast.LENGTH_LONG).show();
}else{ //下面的代码为把输入框中消息也封装非ChatMsg。并显示在listView中 ChatMsg cts = new ChatMsg();
cts.setMsg(et.getText().toString());
cts.setDate(new Date());
cts.setType(ChatMsg.Type.INPUT); mDatas.add(cts); mAdapter.notifyDataSetChanged(); lv.setSelection(mDatas.size()-1);//将lv设定为显示最后一项 //下面的代码为从服务器端获取数据
new Thread(new Runnable(){
public void run(){ String jsonMsg = HttpUtil.doGet(et.getText().toString()); ChatMsg cmg = HttpUtil.getResultMsg(jsonMsg); Message msg = new Message();
msg.obj = cmg;
mHandler.sendMessage(msg); }
}).start(); } et.setText("");//最后将编辑框清空 }
}); //显示最初的数据
ChatMsg cg = new ChatMsg("嘿嘿,小昆为你服务!",new Date(),ChatMsg.Type.OUTPUT);
mDatas.add(cg);
mAdapter = new MyAdapter(this, mDatas);
lv.setAdapter(mAdapter);
} private void initView() { btn = (ImageButton) findViewById(R.id.btn_send);
et = (EditText) findViewById(R.id.et_inmsg);
lv = (ListView) findViewById(R.id.listview_msg); if(mDatas != null){
mAdapter = new MyAdapter(this, mDatas);
} } }
对了,忘记之前说了,应该首先添加权限的:
<uses-permission android:name="android.permission.INTERNET" />
好了,一切都已经编写完成了。我们的项目结束了,是不是迫不及待的要和你的机器人聊天了呢?赶紧运行该程序吧!!
智能机器人“小昆”的实现(五)MainActivty的实现及项目结束的更多相关文章
- hiho#1513 : 小Hi的烦恼 五维偏序
hiho#1513 : 小Hi的烦恼 五维偏序 链接 hiho 思路 高维偏序用bitset,复杂度\((\frac{n^2}{32})\) 代码 #include <bits/stdc++.h ...
- 小程序实践(五):for循环绑定item的点击事件
微信展示列表效果借助于 wx:for 简单写一个列表(wxml文件中): 对应的数据源(js文件中): 写一个点击监听: 效果: 以上.可以实现列表的item点击效果,但是无法到点击的item对应的 ...
- 微信小程序把玩(五)页面生命周期
原文:微信小程序把玩(五)页面生命周期 这里只要熟悉页面的基本生命周期即可,业务在指定生命周期函数内书写. 以下是官网给出的生命周期函数方法和状态图 上面的生周期函数图对于做Android 或者IOS ...
- Mysql查找所有项目开始时间比之前项目结束时间小的项目ID
这是之前遇到过的一道sql面试题,供参考学习: 查找所有项目开始时间比之前项目结束时间小的项目ID mysql> select * from t2; +----+---------------- ...
- easyui小清新俺也晒晒 视频管理软件bs项目
easyui小清新俺也晒晒 视频管理软件bs项目 针对设备的管理软件 这是我听到最多的话.视频管理软件bs项目.easyui 好与坏我不去评价 项目做了好几个月,其实代码看来也没用多少,但是做需求,时 ...
- Android Studio(五):修改Android Studio项目包名
Android Studio相关博客: Android Studio(一):介绍.安装.配置 Android Studio(二):快捷键设置.插件安装 Android Studio(三):设置Andr ...
- 手把手和你一起实现一个Web框架实战——EzWeb框架(五)[Go语言笔记]Go项目实战
手把手和你一起实现一个Web框架实战--EzWeb框架(五)[Go语言笔记]Go项目实战 代码仓库: github gitee 中文注释,非常详尽,可以配合食用 本篇代码,请选择demo5 中间件实现 ...
- 微信小程序入门(五)
24.MINA框架讲解 MINA框架架构 25.小程序运行机制 小程序在首次打开的时间会比较长,后续再打开启动会很快,那么小程序是如何启动的呢? 运行机制-启动 冷启动 热启动 热启动:假入用户已经打 ...
- wx小程序知识点(五)
五.双向绑定和 vue 的区别 ① vue 中实现双向绑定只需要修改 this.data var vm = new Vue({ el: '#example', data: { message: 'He ...
随机推荐
- 数据结构与算法(C++)大纲
1.栈 栈的核心是LIFO(Last In First Out),即后进先出 出栈和入栈只会对栈顶进行操作,栈底永远为0 1.1概念 栈底(bottom):栈结构的首部 栈顶(top):栈结构的尾部 ...
- SpringBoot | 第三十六章:集成多CacheManager
前言 今天有网友咨询了一个问题:如何在一个工程中使用多种缓存进行差异化缓存,即实现多个cacheManager灵活切换.原来没有遇见这种场景,今天下班抽空试了下,以下就把如何实现的简单记录下. 一点知 ...
- golang学习之go简单博客应用
先说说golang的语法吧,个人觉得有以下特点: 简洁,不管是变量.方法声明,还是代码编写,均十分简洁,效率也比较高 非纯粹面向对象,但是go的struct类似c的struct,go的结构体还可以进行 ...
- 初进JAVA职场面试小技巧:一个老学长的吐血之作!
看着一批批小白的遭遇,有些无奈,又跟我年轻时有些类似.今天正好有点时间,给你几个建议. 1.在结业之前一定要把自己参与过的项目仔细审视一下,一点要特别熟悉项目的流程功能,另外也要重视自己做过的模块,看 ...
- docker 容器启动并自启动redis
centos7.5 背景:每次开机后都要自动启动redis,也就是宿主机开机,启动容器,然后启动redis 按照网上的做法是:修改redis.conf ,修改redis的启动脚本(utils/...s ...
- FWORK-数据存储篇 -- 范式与反模式 (学习和理解)
理解 1.第二范式的侧重点是非主键列是否完全依赖于主键,还是依赖于主键的一部分.第三范式的侧重点是非主键列是直接依赖于主键,还是直接依赖于非主键列. 2. 反模式 范式可以避免数据冗余,减少数据库的 ...
- crontab 切割日志
cutlog.sh #!/bin/sh source /etc/profile D=$(date "+%Y%m%d%H%M%S") mv "/usr/local/Cell ...
- Grunt usemin前端自动化打包流程
前端优化是尽量减少http请求,所以我们需要尽量合并压缩文件,然后调用压缩后的文件,比如多个css文件压缩成一个,多个js文件合并压缩等,usemin能够自动在html中使用压缩后的文件,达到上面的目 ...
- 如何解决git fatal: refusing to merge unrelated histories
我在Github新建一个仓库,写了License,然后把本地一个写了很久仓库上传. 先pull,因为两个仓库不同,发现refusing to merge unrelated histories,无法p ...
- [转]ggplot2用法简单介绍
简介 ggplot2包是基于Wilkinson在<Grammar of Graphics>一书中所提出的图形语法的具体实现, 这套图形语法把绘图过程归纳为data, transformat ...