今天看郭霖《第一行代码》书上写了一个聊天窗体的小例子,自己就练习学了一下。加上一些自己的理解整理了一下。

1.第一步首先是制作9.patch图片,这个在android  sdk 目录下tools文件,找到draw9patch.bat文件双击打开。这是一个专门用来处理安卓里面图像的小工具,你可以对图片指定拉伸的效果,具体教程可以百度,很简单的。

2.编写主界面

xmlns:tools="http://schemas.android.com/tools"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:background="#d8e0e8"

android:orientation="vertical">

android:id="@+id/msg_list_view"

android:layout_width="match_parent"

android:layout_height="0dp"

android:layout_weight="1"

android:divider="#0000">

android:layout_width="match_parent"

android:layout_height="wrap_content">

android:id="@+id/input_text"

android:layout_width="0dp"

android:layout_height="wrap_content"

android:layout_weight="1"

android:hint="Typ something in here"

android:maxLines="2"/>

android:id="@+id/send"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="send"/>

主界面里我们可以看到有一个ListView用于加载信息,线性布局进行嵌套,里层里有一个编辑框和一个按钮。下图就是布局初步效果图:

3.编写ListView子项布局,新建一个布局文件

android:layout_width="match_parent"

android:layout_height="match_parent"

android:orientation="vertical"

android:padding="10dp">

android:id="@+id/left_layout"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_gravity="left"

android:background="@drawable/message_left">

android:id="@+id/left_msg"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:gravity="center"

android:layout_margin="10dp"

android:textColor="#fff"/>

android:id="@+id/right_Layout"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_gravity="right"

android:background="@drawable/message_right"

>

android:id="@+id/right_msg"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_gravity="center"

android:layout_margin="10dp"/>

这里最外层是线性布局,里边嵌套两个线性布局。这两个布局分别是给消息发送界面和消息接收界面。后面可以通过设置布局的显示和隐藏属性来显示我们需要的消息。这和我之前学贪吃蛇的布局挺像的,就像把一开始的游戏前出现界面和游戏的场景界面设置在一个布局文件很相似。这也是最近学习布局收获的一点,光学课本上的单个布局的特点没有应用到实际的应用里边,很难自己想象原来布局可以这样灵活。

效果图如下:

3.完成MainActivity.java,写好布局文件以后开始写代码,这里需要大概写的几点是:

1.定义消息类的实体类Msg

public class Msg{  }

里面需要设置消息的类型:发送,接收,内容。

2.ListView适配器的建立

首先它需要继承ArrayAdapter,将泛型指定为Msg类。

这里运用到了很多书上说的ListView的优化,通过if_else判断,如果convertView为空就重新初始化加载布局,这时就需要加载很多东西,如果convertView不为空时,说明它之前有缓存,可以重用,那我们直接调用它,就大大提高了运行的效率。

还有通过创建ViewHolder这个内部类,可以对控件的实例进行缓存。当convertView为空时。将控件的实例存在ViewHolder里,调用setTag()方法,将ViewHolder对象存储在View里。当ViewHolder不为空时,调用View的setTag()方法,重新取出ViewHolder。这样就不用每次调用findViewById()方法获取控件。

3.收发消息布局的隐藏和显示

通过判断消息的类型,进行设置显示和隐藏消息。

if(msg.getType()==Msg.RECEIVED){

//如果是收到的消息,则显示左边消息布局,将右边消息布局隐藏

viewHolder.leftLayout.setVisibility(View.VISIBLE);

viewHolder.rightLayout.setVisibility(View.GONE);

viewHolder.leftMsg.setText(msg.getContent());

}else if(msg.getType()==Msg.SENT){

//如果是发出去的消息,显示右边布局的消息布局,将左边的消息布局隐藏

viewHolder.rightLayout.setVisibility(View.VISIBLE);

viewHolder.leftLayout.setVisibility(View.GONE);

viewHolder.rightMsg.setText(msg.getContent());

}

4.初始化消息initMsg()

写几条消息测试一下首发消息是否正确。

5.给按钮send设置监听器事件

这里用到的是send.setOnClickListener(new OnClickListener(){   },这一看就是匿名内部类的方式。

这里只是大体说了一下编写的大概内容,具体的可以看下面源代码:

package com.example.chat_layout;

import java.util.ArrayList;

import java.util.List;

import android.R.string;

import android.os.Bundle;

import android.app.Activity;

import android.content.Context;

import android.view.LayoutInflater;

import android.view.Menu;

import android.view.View;

import android.view.View.OnClickListener;

import android.view.ViewGroup;

import android.view.Window;

import android.widget.Adapter;

import android.widget.ArrayAdapter;

import android.widget.Button;

import android.widget.EditText;

import android.widget.LinearLayout;

import android.widget.ListView;

import android.widget.TextView;

public class MainActivity extends Activity {

private ListView msgListView;

private EditText inputText;

private Button send;

private MsgAdapter adapter;

private List msgList = new ArrayList();

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

requestWindowFeature(Window.FEATURE_NO_TITLE);//设置窗口没有标题栏

setContentView(R.layout.activity_main);

initMsg();

adapter = 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(adapter);

send.setOnClickListener(new OnClickListener(){

@Override

public void onClick(View v) {

String content = inputText.getText().toString();

if(!"".equals(content)){

Msg msg = new Msg(content, Msg.SENT);

msgList.add(msg);

adapter.notifyDataSetChanged();//有新消息时,刷新ListView中的显示

msgListView.setSelection(msgList.size());//将ListView定位到最后一行

inputText.setText("");//清空输入框的内容

}

}

});

}

private void initMsg() {

Msg msg1 = new Msg("I miss you!",Msg.RECEIVED);

msgList.add(msg1);

Msg msg2 = new Msg("I miss you,too!",Msg.SENT);

msgList.add(msg2);

Msg msg3 = new Msg("I will come back soon!",Msg.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;

}

public class Msg{

public static final int RECEIVED = 0;//收到一条消息

public static final int 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;

}

}

public class MsgAdapter extends ArrayAdapter{

private int resourceId;

public MsgAdapter(Context context, int textViewresourceId, List 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.RECEIVED){

//如果是收到的消息,则显示左边消息布局,将右边消息布局隐藏

viewHolder.leftLayout.setVisibility(View.VISIBLE);

viewHolder.rightLayout.setVisibility(View.GONE);

viewHolder.leftMsg.setText(msg.getContent());

}else if(msg.getType()==Msg.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条消息,ok这是通过底下编辑器输入的,看一看到实现了聊天对话框的基本内容和要求。

android高仿微信下拉有页面,Android——(仿微信聊天界面布局实例)相关推荐

  1. android代码下拉刷新页面,Android下拉刷新的实现

    ListView下拉刷新实现方式分析 1.添加顶部下拉加载界面. 2.监听onScrollListener,来判断当前是否在ListView最顶部. 3.监听onTouch事件,根据手势变化改变当前状 ...

  2. 仿Ios下拉菜单,android Spinner效果(美团下拉效果)

    先上效果图: 直接上代码: Ios spinner文件 package com.choe.iosspinner;import android.app.Activity; import android. ...

  3. android微信下拉出现小程序,仿新版微信的小程序下拉栏

    原标题:仿新版微信的小程序下拉栏 本项目会对金融交易软件中存在的各种View进行模仿绘制,提供详细的实现思路,收集整理相关算法.文档以及专业资料. https://github.com/scsfwgy ...

  4. android webview 下拉刷新页面,Android 下拉刷新控件SwipeRefreshLayout结合WebView使用

    SwipeRefreshLayout 是谷歌官方下拉刷新控件,4.0如下的版本须要用到 android-support-v4.jar包才能用到html android-support-v4.jar 包 ...

  5. 谷歌的android下拉刷新页面,Android SwipeRefreshLayout:谷歌官方SDK包中的下拉刷新

     <Android SwipeRefreshLayout:谷歌官方SDK包中的下拉刷新> 下拉刷新在如今移动开发中应用如此广泛和普遍,以至于谷歌干脆在SDK中给予支持.在android ...

  6. Android仿微信下拉

    Android仿微信下拉 eclipse版本,不知道studio上是否适用 工具类 public class MyReboundScrollView extends ScrollView {priva ...

  7. Android 天气APP(十)继续优化、下拉刷新页面天气数据

    上一篇:Android 天气APP(九)细节优化.必应每日一图 修复每日一图,增加下拉刷新,滑动改变标题 新版------------------- 一.修复每日请求必应壁纸Bug 二.增加下拉刷新 ...

  8. android组件的下拉回弹,Android自定义控件仿ios下拉回弹效果

    网上有很多类似的文章,大多数还是继承listview来实现(主要是listview.addHeaderView()和listview.addFooterView在listview的首尾添加view,也 ...

  9. 微信小程序 通过wx.redirectTo,实现单页面刷新效果 & 下拉刷新页面数据效果

    微信小程序 通过wx.redirectTo,实现单页面刷新效果 & 下拉刷新页面数据效果 一: 使用 wx.redirectTo(),实现页面刷新数据效果 API说明: 关闭当前页面,跳转到应 ...

最新文章

  1. onkeyup,onkeydown和onkeypress的区别介绍
  2. C#中使用代码动态改变配置文件信息
  3. HTML5中各种标签总结(body标签)
  4. windows10环境下安装Anaconda环境
  5. VTK:可视化之ProgrammableGlyphFilter
  6. OpenCV之cvSmooth函数平滑滤波
  7. vm+ubuntu联网
  8. docker部署php站点,docker部署php
  9. 调账成功 对账失败处理流程反思
  10. 10种开发以及改善应用的低成本方法
  11. mysql 动态加载数据库数据库连接,如何根据每个客户端动态连接mysql数据库?
  12. 误删除数据恢复 plsql
  13. Django之Model操作之select_related和prefetch_related【ORM篇八】
  14. java图书商城项目_JavaWeb之网上图书商城-框架搭建
  15. 超级计算机的性能指标
  16. 递归最小二乘(RLS)算法详解
  17. 阿里云服务器安装mongodb
  18. Project directory ‘x/x/x‘ is not part of the build defined by settings file ‘x/x/x‘. If this is ...
  19. java开发的游戏测试_用java编写。模拟一个简单的测试打字速度的游戏
  20. 区分网络管理员和网络工程师

热门文章

  1. 100m光纤测速多少正常_终于知道为什么我的百兆宽带测速只有一半了
  2. 鸿蒙大陆罪恶深渊哪里出,罪恶深渊 - 音阙诗听 - 5SING中国原创音乐基地
  3. 安装程序配置服务器失败。参考服务器错误日志和 C:/WINDOWS/sqlstp.log 了解更多信息。
  4. 字体文件反反爬-- 起点中文网
  5. 利用frp和RDClient实现远程控制电脑
  6. NV终于出必杀!怪兽显卡GTX TITAN首测
  7. ti dra712多处理器芯片
  8. 如何快速找国外客户?新手必备!
  9. ios 项目被拒绝各种理由
  10. MemoryAnalyzer(MAT)内存分析工具和Android Profiler的使用