简易的聊天界面以及聊天机器人的实现
现在的聊天机器人一般都是通过连接网络API接口实现的,通过对接口的网络访问,实现聊天数据的传输,我这个就是访问图灵机器人的接口实现。
先看效果图:

界面代码:
1.activity_main.xml 主界面布局、包括头部及一个listview和下方的文本输入框与按钮。
|
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="com.jju.edu.robot.MainActivity"> <include layout="@layout/title"></include> <ListView android:id="@+id/list_view" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:cacheColorHint="#00000000"></ListView> <LinearLayout android:layout_width="match_parent" android:layout_height="40dp" android:orientation="horizontal"> <EditText android:id="@+id/ed_message" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:background="@drawable/shape2" /> <Button android:onClick="submit" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/shape1" android:text="发送"/> </LinearLayout> </LinearLayout> |
2.title.xml 头部的详细布局里面有左、中、右三个textview,方便代码重复调用(这项目里是没必要的,习惯了!)这里只用到了中间的textview。
|
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="50dp"> <RelativeLayout android:layout_width="match_parent" android:background="#0b85ed" android:layout_height="match_parent"> <TextView android:id="@+id/left" android:layout_width="wrap_content" android:layout_height="match_parent" android:gravity="center_vertical" android:textSize="20sp" android:textColor="#FFFFFF" android:layout_alignParentLeft="true" android:layout_marginLeft="10dp"/> <TextView android:id="@+id/middle" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:text="标题" android:textSize="20sp" android:textColor="#ffffff"/> <TextView android:id="@+id/right" android:layout_width="wrap_content" android:layout_height="match_parent" android:gravity="center_vertical" android:textSize="20sp" android:textColor="#FFFFFF" android:layout_alignParentRight="true" android:layout_marginRight="10dp"/> </RelativeLayout> </LinearLayout> |
3.这里是listview里面item的两种布局,分别是我们发送信息的显示布局以及收到信息的显示布局。
|
list_item_left.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="wrap_content"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center_horizontal" android:orientation="vertical"> <TextView android:id="@+id/time" android:layout_width="wrap_content" android:layout_height="20dp" android:text="时间"/> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <LinearLayout android:layout_width="50dp" android:layout_height="60dp" android:orientation="vertical"> <ImageView android:layout_width="40dp" android:layout_height="40dp" android:layout_marginLeft="10dp" android:background="@drawable/lzk"/> <TextView android:layout_width="match_parent" android:layout_height="20dp" android:layout_marginLeft="10dp" android:text="小灵"/> </LinearLayout> <TextView android:id="@+id/content" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="15dp" android:layout_marginRight="60dp" android:text="内容" android:background="@drawable/shape" android:textSize="20sp"/> </LinearLayout> </LinearLayout> </LinearLayout> |
|
list_item_right.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="wrap_content" android:orientation="vertical"> <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:id="@+id/time" android:layout_width="wrap_content" android:layout_height="20dp" android:layout_centerHorizontal="true" android:text="时间" /> <RelativeLayout android:layout_width="match_parent" android:layout_height="60dp" android:layout_marginTop="20dp"> <LinearLayout android:id="@+id/img" android:layout_width="40dp" android:layout_height="60dp" android:layout_alignParentRight="true" android:layout_marginRight="10dp" android:gravity="center_horizontal" android:orientation="vertical"> <ImageView android:layout_width="40dp" android:layout_height="40dp" android:background="@drawable/nimingliaotian" /> <TextView android:layout_width="wrap_content" android:layout_height="20dp" android:text="我" /> </LinearLayout> <TextView android:id="@+id/content" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="60dp" android:layout_marginRight="10dp" android:layout_toLeftOf="@id/img" android:background="@drawable/shape1" android:text="内容" android:textSize="20sp" /> </RelativeLayout> </RelativeLayout> </LinearLayout> |
Java代码:
首先得先找到图灵机器人的API接口,该接口有很多数据平台都会提供,而且完全免费!我这里调用的是聚合数据里的,就以聚合数据的接口示例。
注册后登录,实名认证完成后直接申请数据即可。申请成功,会获得key值及申请示例。下面直接看代码,注释里会解释:
1.MainActivity.class
|
package com.jju.edu.robot; import android.app.Activity; import android.os.Handler; import android.os.Message; import android.os.Bundle; import android.util.Log; import android.view.View; import android.view.Window; import android.widget.EditText; import android.widget.ListView; import android.widget.TextView; import android.widget.Toast; import org.json.JSONObject; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URL; import java.net.URLEncoder; import java.util.ArrayList; import java.util.Calendar; import java.util.List; public class MainActivity extends Activity { private String time;//时间(会在每次发送或接收数据时重新赋值) private String path1 = "http://op.juhe.cn/robot/index?info=";//接口路径 private String path2 = "&dtype=&loc=&lon=&lat=&userid=&key=8a2e2e11c3453a5fd3002b864174e440";//发送的各种参数及key值(这里就不过多设置参数了,直接默认) private String text = ""; private TextView middle; private EditText ed_message; private List<MessageUtil> list = new ArrayList<MessageUtil>(); private MyAdapter adapter; private ListView list_view; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.activity_main); //获取控件 middle = (TextView) findViewById(R.id.middle); ed_message = (EditText) findViewById(R.id.ed_message); list_view = (ListView) findViewById(R.id.list_view); list_view.setDividerHeight(0);//去掉黑线 middle.setText("聊天界面");//设置头部标题 //将初始值放入list集合 MessageUtil util = new MessageUtil(); util.setJudge(false); util.setTime(getTime()); util.setMessage("您好!我是小灵!"); list.add(util); //定义自定义适配器并赋值 adapter = new MyAdapter(MainActivity.this, list); //将自定义适配器添加到listview list_view.setAdapter(adapter); } //获取时间,每次调用都会获得调用时的当前时间。 public String getTime() { Calendar c = Calendar.getInstance(); time = c.get(Calendar.YEAR) + "-" + (c.get(Calendar.MONTH) + 1) + "-" + c.get(Calendar.DAY_OF_MONTH) + " " + c.get(Calendar.HOUR_OF_DAY) + ":" + c.get(Calendar.MINUTE) + ":" + c.get(Calendar.SECOND); Log.e("时间", time); return time; } //按钮点击事件 public void submit(View view) { String message = ed_message.getText().toString(); //输入不能为空 if (message == null || message.equals("")) { Toast.makeText(MainActivity.this, "输入不能为空!", Toast.LENGTH_SHORT).show(); } else { //添加自己发送的数据到list集合 MessageUtil util = new MessageUtil(); util.setJudge(true); util.setTime(getTime()); util.setMessage(message); list.add(util); //添加改变值 adapter.notifyDataSetChanged(); //显示listview最后一个值 list_view.setSelection(list.size()); //网络操作 http_(message); } ed_message.setText(""); } //网络访问操作 public void http_(final String string) { new Thread() { @Override public void run() { try { //保证编码格式正确 String city = URLEncoder.encode(string, "UTF-8"); //拼接地址与参数 URL url = new URL(path1 + city + path2); //访问 HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.connect(); InputStream is = connection.getInputStream(); //获得返回值 String info = getInfo(is); Log.e("****", info); //子线程无法操作UI,所以讲数据传递给handler。 Message message = handler.obtainMessage(); message.obj = info; message.what = 123; handler.sendMessage(message); } catch (Exception e) { e.printStackTrace(); } } }.start(); } //获得返回数据,调用解析方法 public Handler handler = new Handler() { @Override public void handleMessage(Message msg) { if (msg.what == 123) { text = (String) msg.obj; json(text); } } }; //读取返回数据将其转换成String型并返回 public String getInfo(InputStream is) { String info = null; byte[] by = new byte[1024]; StringBuilder builder = new StringBuilder(); int count = -1; try { while ((count = is.read(by)) != -1) { builder.append(new String(by, 0, count)); } info = builder.toString(); is.close(); } catch (Exception e) { e.printStackTrace(); } return info; } //解析返回的jsons数据,并将值添加到list集合后保存添加数据(应该将解析方法与添加list集合的方法写成两个方法的,这里就懒得分开了) public void json(String string) { try { JSONObject object = new JSONObject(string); String back = object.getString("result"); JSONObject object1 = new JSONObject(back); String back_message = object1.getString("text"); MessageUtil util = new MessageUtil(); util.setJudge(false); util.setTime(getTime()); util.setMessage(back_message); list.add(util); adapter.notifyDataSetChanged(); list_view.setSelection(list.size()); } catch (Exception e) { e.printStackTrace(); } } } |
2.MessageUtil.class 构造方法类
|
package com.jju.edu.robot; /** * Created by LingHao on 2016/11/3. * 构造方法类 */ public class MessageUtil { private String time; private String message; private boolean judge; public String getTime() { return time; } public void setTime(String time) { this.time = time; } public boolean isJudge() { return judge; } public void setJudge(boolean judge) { this.judge = judge; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } } |
3.MyAdapter.class 自定义适配器类。
|
package com.jju.edu.robot; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.TextView; import java.util.List; /** * Created by LingHao on 2016/11/3. */ public class MyAdapter extends BaseAdapter { private Context context; private List<MessageUtil> list; private LayoutInflater inflater; private int COME_MSG = 0; private int TO_MSG = 1; public MyAdapter(Context context, List<MessageUtil> list) { this.context = context; this.list = list; inflater = LayoutInflater.from(context); } @Override public int getCount() { return list.size(); } @Override public Object getItem(int position) { return list.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { //缓存机制 ViewHolder holder = null; if (convertView == null) { holder = new ViewHolder(); //判断是发送还是接收,从而设置风格样式靠左还是靠右 if (list.get(position).isJudge()) { convertView = inflater.inflate(R.layout.list_item_right, null); } else { convertView = inflater.inflate(R.layout.list_item_left, null); } holder.time = (TextView) convertView.findViewById(R.id.time); holder.content = (TextView) convertView.findViewById(R.id.content); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } holder.time.setText(list.get(position).getTime()); holder.content.setText(list.get(position).getMessage()); return convertView; } class ViewHolder { TextView time, content; } @Override public int getItemViewType(int position) { // 区别两种view的类型,标注两个不同的变量来分别表示各自的类型 MessageUtil util = list.get(position); if (util.isJudge()) { return COME_MSG; } else { return TO_MSG; } } @Override public int getViewTypeCount() { // 这个方法默认返回1,如果希望listview的item都是一样的就返回1,我们这里有两种风格,返回2 return 2; } } |
注意:运行之前要添加网络权限:
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
文章来源:网络 版权归原作者所有
上文内容不用于商业目的,如涉及知识产权问题,请权利人联系小编,我们将立即处理
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐

所有评论(0)