一个语音助手,光会说话还不够,来简单的实现一个对话流显示聊天记录。
ListView:由于手机屏幕空间都比较有限,一次性显示所有记录显然不够现实。ListView允许用户通过手指上下滑动的方式将屏幕外的数据滚动到屏幕内,同时屏幕上原有的数据则会滚动出屏幕。因此可以借助其实现聊天记录的滑动显示功能。
这里以最近写的Demo 小炮为例,效果如下图(参考现有语音助手UI,未设计头像与对话框):
一、布局文件
比较简单,直接贴代码
1.主布局
包含ListView和对话、菜单等按钮
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| <?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:paddingTop="20dp" android:orientation="vertical" tools:context="me.weyo.magicmirror.android.MainActivity"> <ListView android:layout_marginRight="20dp" android:layout_marginLeft="20dp" android:layout_below="@id/iv_logo" android:id="@+id/msg_list_view" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:divider="#0000"> </ListView> <include layout="@layout/lo_saying" android:id="@+id/lo_saying"> </include> <include android:visibility="gone" layout="@layout/lo_edit" android:id="@+id/lo_edit"> </include> </LinearLayout>
|
2.语音输入按钮
包含设置、话筒、帮助,文字输入类似不再赘述,效果如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
| <?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="80dp" android:layout_marginBottom="20dp" android:layout_marginTop="4dp" android:layout_alignParentBottom="true" android:weightSum="3" android:gravity="center" android:orientation="horizontal" android:baselineAligned="false"> <LinearLayout android:layout_width="0dp" android:layout_height="fill_parent" android:layout_weight="1" android:gravity="center" android:layout_gravity="center_horizontal"> <ImageButton android:id="@+id/setting" android:layout_width="35dp" android:layout_height="35dp" android:layout_gravity="center" android:background="@drawable/main_setting_btn_np" /> </LinearLayout> <LinearLayout android:layout_width="0dp" android:layout_height="wrap_content" android:gravity="center" android:layout_weight="1"> <ImageButton android:id="@+id/saying" android:layout_width="70dp" android:layout_height="70dp" android:layout_gravity="center" android:background="@drawable/main_saying_btn_np"/> </LinearLayout> <LinearLayout android:layout_width="0dp" android:layout_height="fill_parent" android:layout_weight="1" android:gravity="center"> <ImageButton android:id="@+id/help" android:layout_width="35dp" android:layout_height="35dp" android:layout_gravity="center" android:background="@drawable/main_help_btn_np"/> </LinearLayout> </LinearLayout>
|
3.单次对话Item布局文件
包含左边(收到的消息)右边(发送的消息)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| <?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="vertical" android:padding="10dp" > <LinearLayout android:id="@+id/left_layout" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="left" > <TextView android:textSize="25dp" android:id="@+id/left_msg" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_margin="10dp" android:textColor="#fff" /> </LinearLayout> <LinearLayout android:id="@+id/right_layout" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="right" > <TextView android:textSize="25dp" android:textColor="#FFFFFF" android:id="@+id/right_msg" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_margin="10dp" /> </LinearLayout> </LinearLayout>
|
二、实体类
1.消息类
将消息抽象为对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
|
public class Msg { public static final int TYPE_RECEIVED = 0; public static final int TYPE_SENT = 1; private String content; private int type; public Msg(String content, int type) { this.content = content; this.type = type; } public String getContent() { return content; } public int getType() { return type; } }
|
2.Msg适配器
将meg组装到listview显示
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| public class MsgAdapter extends ArrayAdapter<Msg> { private int resourceId; public MsgAdapter(Context context, int textViewResourceId, List<Msg> objects) { super(context, textViewResourceId, objects); resourceId = textViewResourceId; } @Override public View getView(int position, View convertView, ViewGroup parent) { Msg msg = getItem(position); View view; ViewHolder viewHolder; if (convertView == null) { view = LayoutInflater.from(getContext()).inflate(resourceId, null); viewHolder = new ViewHolder(); viewHolder.leftLayout= (LinearLayout) view.findViewById (R.id.left_layout); viewHolder.rightLayout = (LinearLayout) view.findViewById (R.id.right_layout); viewHolder.leftMsg = (TextView) view.findViewById(R.id.left_msg); viewHolder.rightMsg = (TextView) view.findViewById(R.id.right_msg); view.setTag(viewHolder); } else { view = convertView; viewHolder = (ViewHolder) view.getTag(); } if (msg.getType() == Msg.TYPE_RECEIVED) {
viewHolder.leftLayout.setVisibility(View.VISIBLE); viewHolder.rightLayout.setVisibility(View.GONE); viewHolder.leftMsg.setText(msg.getContent()); } else if(msg.getType() == Msg.TYPE_SENT) {
viewHolder.rightLayout.setVisibility(View.VISIBLE); viewHolder.leftLayout.setVisibility(View.GONE); viewHolder.rightMsg.setText(msg.getContent()); } return view; } class ViewHolder { LinearLayout leftLayout; LinearLayout rightLayout; TextView leftMsg; TextView rightMsg; } }
|
3.MainActivity中关键代码
装载布局及相关监听省略
1 2 3 4
| private ListView msgListView; private MsgAdapter adapter; private List<Msg> msgList = new ArrayList<Msg>();
|
1 2 3 4
| adapter = new MsgAdapter(MainActivity.this, R.layout.msg_item, msgList); msgListView = (ListView) findViewById(R.id.msg_list_view); msgListView.setAdapter(adapter);
|
1 2 3 4 5 6 7 8
| public void setMsg(String result,int type){ Msg msg = new Msg(result, type); msgList.add(msg); adapter.notifyDataSetChanged(); msgListView.setSelection(msgList.size()); }
|
终
到这里,一个简单的对话流布局就写完了,把他应用到App中,只需要将Msg设置好内容、状态,监听里调用msg就好了!
一起来敲一个自己的语音助手吧。