编写聊天界面的最佳实践

1、编写主界面,activity_main.xml:

  • 使用总线性布局,在总线性布局里包含了一个ListView控件和另一个LinearLayout。
  • 在垂直方向上,LinearLayout按照wrap_content来计算,剩下的空间是ListView控件的,( android:layout_weight="1")
  • LinearLayout里边包含一个EditText控件和一个按钮控件。按钮控件按照wrap_content来计算,剩下的空间是EditText控件的(android:layout_weight="1")
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
 >
     <!-- ListView 占下剩余的空间 -->
    <ListView
        android:id="@+id/msg_list_view"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:divider="#0000">

    </ListView>
   <LinearLayout
       android:layout_width="match_parent"
       android:layout_height="wrap_content">
       <EditText
           android:id="@+id/input_text"
           android:layout_width="0dp"
           android:layout_height="wrap_content"
           android:layout_weight="1"
           android:hint="Type something here"
           android:maxLines="2"/>
       <Button
           android:id="@+id/send"
           android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           android:text="Send"/>
   </LinearLayout>

</LinearLayout>

2、编写消息的实体类

package com.example.uibestpractice;

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;
    }

}

3、编写ListView子项的布局:msg_item.xml

LinearLayout里边又包含了两个线性布局分别为LinearLayout1和LinearLayout2.一个为左布局,一个为右。在后面中,可以控制控件的可见性,来区别消息是发送还是接收。

<?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"
        android:background="@drawable/message_left">
        <TextView
            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"
        android:background="@drawable/message_right">
        <TextView
            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>

4、创建ListView的适配器

package com.example.uibestpractice;

import java.util.List;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.LinearLayout;
import android.widget.TextView;

public class MsgAdapter extends ArrayAdapter<Msg>{

    private int resourceID;
    public MsgAdapter(Context context, int textViewResourceId, List<Msg> objects) {
        super(context, textViewResourceId, objects);
        // TODO Auto-generated constructor stub
        resourceID=textViewResourceId;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        // TODO Auto-generated method stub
        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.leftLayout.setVisibility(View.GONE);
            viewHolder.rightLayout.setVisibility(View.VISIBLE);
            viewHolder.rightMsg.setText(msg.getContent());
        }
        return view;
    }

    class ViewHolder{
        LinearLayout leftLayout;
        LinearLayout rightLayout;
        TextView leftMsg;
        TextView rightMsg;
    }

}

5、最后修改MainActivity.java

package com.example.uibestpractice;

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

import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;

public class MainActivity extends Activity {

    private ListView msgListView;
    private EditText inputText;
    private Button send;
    private MsgAdapter msgAdapter;
    private List<Msg> msgList=new ArrayList<Msg>();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initMsgs();
        msgAdapter=new MsgAdapter(MainActivity.this, R.layout.msg_item, msgList);
        inputText=(EditText) findViewById(R.id.input_text);
        send=(Button) findViewById(R.id.send);
        msgListView=(ListView) findViewById(R.id.msg_list_view);
        msgListView.setAdapter(msgAdapter);
        send.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View arg0) {
                // TODO Auto-generated method stub
                String content=inputText.getText().toString();
                if(!"".equals(content)){
                    Msg msg=new Msg(content,Msg.TYPE_SENT);
                    msgList.add(msg);
                    msgAdapter.notifyDataSetChanged();//当有新消息时,刷新ListView中显示
                    msgListView.setSelection(msgList.size());//将ListView定位到最后一行。
                    inputText.setText("");//清空输入框中的内容
                }

            }
        });

    }

    private void initMsgs(){
        Msg msg1=new Msg("Hello guy.",Msg.TYPE_RECEIVED);
        msgList.add(msg1);
        Msg msg2=new Msg("Hello. Who is that?",Msg.TYPE_SENT);
        msgList.add(msg2);
        Msg msg3=new Msg("This is Tom. Nice Talking to you",Msg.TYPE_RECEIVED);
        msgList.add(msg3);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

}
时间: 2024-11-05 04:02:44

编写聊天界面的最佳实践的相关文章

编写Shell脚本的最佳实践

前言 由于工作需要,最近重新开始拾掇shell脚本.虽然绝大部分命令自己平时也经常使用,但是在写成脚本的时候总觉得写的很难看.而且当我在看其他人写的脚本的时候,总觉得难以阅读.毕竟shell脚本这个东西不算是正经的编程语言,他更像是一个工具,用来杂糅不同的程序供我们调用.因此很多人在写的时候也是想到哪里写到哪里,基本上都像是一段超长的main函数,不忍直视.同时,由于历史原因,shell有很多不同的版本,而且也有很多有相同功能的命令需要我们进行取舍,以至于代码的规范很难统一. 考虑到上面的这些原

编写Shell脚本的最佳实践,规范二

需要养成的习惯如下: 代码有注释 #!/bin/bash # Written by steven # Name: mysqldump.sh # Version: v1.0 # Parameters : 无 # Function: mysqldump备份mysql # Create Date: 2016-08-27 缩进有规矩 编码要统一 在写脚本的时候尽量使用UTF-8编码 太长要分行 巧用heredocs 学会查路径 script_dir=$(cd $(dirname $0) && pw

编写Shell脚本的最佳实践,规范一

随着写的SHELL程序越来越多,发现自己每次写都有不同的习惯或者定义了不同的东西,变量名定义得不一样,整个程序缩进不统一,没有注释等问题,等我回过头看这些程序的时候发现很麻烦.所以写了个shell代码规范. 1.1 目的 定义Shell脚本命名和编码规范,统一管理Shell脚本,便于自己和别人查看,提高代码书写速度和美观,暂时只对自己进行约束,其它人只供参考. 1.2 开发工具 shell脚本是个文件,没有开发环境,FC4图形环境下,可用gedit.vi.vim.joe等,推荐使用vim因为这个

Dockerfile 最佳实践

之前 一篇文章介绍 docker 的镜像基本原理和概念 ,主要介绍在编写 docker 镜像的时候一些需要注意的事项和推荐的做法. 虽然 Dockerfile 简化了镜像构建的过程,并且把这个过程可以进行版本控制,但是不正当的 Dockerfile 使用也会导致很多问题: docker 镜像太大.如果你经常使用镜像或者构建镜像,一定会遇到那种很大的镜像,甚至有些能达到 2G 以上 docker 镜像的构建时间过长.每个 build 都会耗费很长时间,对于需要经常构建镜像(比如单元测试)的地方这可

android#编写一个聊天界面

摘自<第一行代码>——郭霖 既然是要编写一个聊天界面,那就肯定要有收到的消息和发出的消息.上一节中我们制作的message_left.9.png可以作为收到消息的背景图,那么毫无疑问你还需要再制作一张message_right.9.png作为发出消息的背景图.图片都提供好了之后就可以开始编码了,首先还是编写主界面,修改activity_main.xml中的代码,如下所示: <LinearLayout xmlns:android="http://schemas.android.c

jQuery插件的编写相关技术 设计总结和最佳实践

原文:http://www.itzhai.com/jquery-plug-in-the-preparation-of-related-technical-design-summary-and-best-practices.html 1.声明插件名称: 添加一个函数到jQuery.fn(jQuery.prototype)对象,该函数的名称就是你的插件名称: jQuery.fn.myPlugin = function() { // Do your awesome plugin stuff here

编写超级可读代码的15个最佳实践

译自:http://net.tutsplus.com/tutorials/html-css-techniques/top-15-best-practices-for-writing-super-readable-code/ 译者:蒋宇捷        一月两次,我们重温Nettuts历史上读者最喜欢的文章. 代码可读性是一个计算机编程世界的普遍主题.它是我们作为开发者第一件学习的事情.这篇文章将阐述编写可读性代码十五个最重要的最佳实践. 1 – 注释和文档 集成开发环境IDE在过去的短短几年里走

iOS应用开发最佳实践:编写高质量的Objective-C代码

本文转载至 http://www.cocoachina.com/industry/20131129/7445.html 点标记语法 属性和幂等方法(多次调用和一次调用返回的结果相同)使用点标记语法访问,其他的情况使用方括号标记语法. 良好的风格 : view.backgroundColor = [UIColor orangeColor]; [UIApplication sha “” 阅读器 本文由“海水的味道"编译 点标记语法 属性和幂等方法(多次调用和一次调用返回的结果相同)使用点标记语法访问

编写 Node.js Rest API 的 10 个最佳实践

Node.js 除了用来编写 WEB 应用之外,还可以用来编写 API 服务,我们在本文中会介绍编写 Node.js Rest API 的最佳实践,包括如何命名路由.进行认证和测试等话题,内容摘要如下: 正确使用 HTTP Method 和路由 正确的使用 HTTP 状态码 使用 HTTP Header 来发送元数据 为 REST API 挑选合适的框架 要对 API 进行黑盒测试 使用基于 JWT 的无状态的认证机制 学会使用条件请求机制 拥抱接口调用频率限制(Rate-Limiting) 编