1.气泡的准备:为了避免图片的失真需要用到如下工具:
在Android sdk 目录下有一个tools 文件夹,在这个文件夹中找到draw9patch.bat 文件,
我们就是使用它来制作Nine-Patch 图片的。双击打开之后,在导航栏点击File→Open 9-patch
将图片加载进来
我们可以在图片的四个边框绘制一个个的小黑点,在上边框和左边框绘制的部分就表示
当图片需要拉伸时就拉伸黑点标记的区域,在下边框和右边框绘制的部分则表示内容会被放
置的区域。
最后点击导航栏 File→Save 9-patch 把绘制好的图片进行保存,此时的文件名就是.9.png。
2.布局文件如下 activity_main.xml
<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"
tools:context="com.example.simple.MainActivity" >
<ListView
android:id="@+id/listView"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:background="#ffffff"
android:dividerHeight="5dp"
android:scrollbars="none"
android:divider="#ffffff"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="50dp"
android:orientation="horizontal">
<EditText
android:id="@+id/editText"
android:layout_width="0dp"
android:layout_weight="1"
android:hint="请输入..."
android:layout_height="match_parent"/>
<Button
android:id="@+id/btn_send"
android:layout_marginLeft="5dp"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="发送"/>
</LinearLayout>
</LinearLayout>
msg_item.xml:消息的布局,ListView的子条目如下:
<!--
将左右两边的消息放在一个布局,通过信息的类型而隐藏掉相对的布局
android:gravity="center|left" 让文字居中且过长的时候换行靠左显示
-->
<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"
tools:context="com.example.simple.MainActivity" >
<LinearLayout
android:id="@+id/left_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<ImageView
android:id="@+id/ivicon"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_gravity="top"
android:src="@drawable/ic_launcher" />
<TextView
android:id="@+id/left_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_marginRight="100dp"
android:layout_marginTop="8dp"
android:background="@drawable/left"
android:gravity="center|left"
android:padding="8dp"
android:text="左边默认的文字" />
</LinearLayout>
<LinearLayout
android:id="@+id/right_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:orientation="horizontal" >
<TextView
android:id="@+id/right_text"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="100dp"
android:layout_marginRight="5dp"
android:layout_marginTop="8dp"
android:layout_weight="1"
android:background="@drawable/right"
android:gravity="center|left"
android:padding="8dp"
android:text="右边默认的文字" />
<ImageView
android:id="@+id/right_image"
android:layout_width="30dp"
android:layout_height="30dp"
android:src="@drawable/app_lvjian_message_background" />
</LinearLayout>
</LinearLayout>
注意:这里右边的消息如果不设置权重让右边的图片先显示,如果内容过长会把图片挤出外面
3.消息的实体类:Message.java
/**消息的实体类:包括content消息内容 type消息类型
*/
public class Message {
private String content;//内容
private boolean type;//消息类型,该消息是否是自己发送
public Message() {
super();
}
/**
* @param content 消息内容
* @param type 消息类型:true代表是自己发送 false代表是接收到的消息
*/
public Message(String content, boolean type) {
super();
this.content = content;
this.type = type;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public boolean isType() {
return type;
}
public void setType(boolean type) {
this.type = type;
}
}
4.适配器 MyAdapter.java:
//自定义的Adapter加载布局文件的时候需要判断是哪方发送的消息来决定用哪个item布局文件
public class MyAdapter extends BaseAdapter {
private List<Message> list;// Message包括消息类型和消息
private Context context;
public MyAdapter(Context context, List<Message> list) {
super();
this.list = list;
this.context = 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;
View view = null;//装所有消息的布局
if (convertView == null) {
holder = new ViewHolder();
view = LayoutInflater.from(context).inflate(R.layout.msg_item, null);
holder.leftMsg = (TextView) view.findViewById(R.id.left_text);
holder.leftLayout = (LinearLayout) view.findViewById(R.id.left_layout);
holder.rightLayout = (LinearLayout) view.findViewById(R.id.right_layout);
holder.rightMsg = (TextView) view.findViewById(R.id.right_text);
view.setTag(holder);
} else {
view=convertView;//将翻出去的视图对象赋值给view,对象的重复使用
holder = (ViewHolder) view.getTag();
}
Message msg=list.get(position);//获取消息的对象
if(msg.isType()){//如果是自己发送的
holder.rightMsg.setText(msg.getContent());//将信息内容设置到TextView中显示
holder.leftLayout.setVisibility(View.GONE);//设置左边的布局不可见且不占用位置
holder.rightLayout.setVisibility(View.VISIBLE);//设置右边的布局可见
}else{//如果是收到的消息
holder.leftMsg.setText(msg.getContent());
holder.leftLayout.setVisibility(View.VISIBLE);
holder.rightLayout.setVisibility(View.GONE);
}
return view;
}
// 提高效率
class ViewHolder {
LinearLayout leftLayout;
LinearLayout rightLayout;
TextView leftMsg;
TextView rightMsg;
}
}
5.MainActivity.java
public class MainActivity extends Activity {
private EditText editText;//编辑信息的编辑框
private Button btn_send;//发送消息的按钮
private ListView listView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
editText = (EditText) findViewById(R.id.editText);
btn_send = (Button) findViewById(R.id.btn_send);
listView = (ListView) findViewById(R.id.listView);
//模拟几条消息
final List<Message> list=new ArrayList<Message>();
list.add(new Message("在吗?", false));//false代表是接收到的消息
list.add(new Message(,不回我",false));
list.add(new Message("就是不回,你能拿我怎么滴!!!",true));
list.add(new Message("咖啡骄傲的算法来房间了发打发斯蒂芬打发大师傅阿道夫阿道夫",false));
final MyAdapter adapter=new MyAdapter(this, list);
listView.setAdapter(adapter);
btn_send.setOnClickListener(new View.OnClickListener() {
@Override//发送信息按钮监听
public void onClick(View v) {
String str=editText.getText().toString();//编辑框的内容
if(!TextUtils.isEmpty(str)){
list.add(new Message(str, true));
adapter.notifyDataSetChanged(); //刷新ListView
listView.setSelection(list.size()); // 将ListView定位到最后一行
editText.setText("");//清空输入框
}
}
});
}
}