学会使用Listview及其优化,再就是用了一个自定义的聊天气泡控件。

首先,先写主页面的xml:

  xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical"    >          android:id="@+id/list_view"        android:layout_width="match_parent"        android:layout_height="0dp"        android:divider="#0000"        android:layout_weight="1">                android:layout_width="match_parent"        android:layout_height="wrap_content"        android:layout_marginBottom="5dp"        >                    android:id="@+id/input_et"  //输入要发送的信息            android:layout_width="0dp"            android:layout_height="wrap_content"            android:layout_weight="1"            android:hint="input message"            android:maxLines="2"/>                    android:id="@+id/send //发送信息按钮            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:background="#66cc99"            android:text="send"/>    


接着 定义消息的实体类,新建Msg类:

public class Msg {    public static int RECEIVED = 0; //收到的消息    public static  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;    }}
接着,开始写ListView的子页面,代码如下:

xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:app="http://schemas.android.com/apk/res-auto"    android:orientation="vertical"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:padding="10dp">    android:id="@+id/left_layout"    android:layout_width="wrap_content"    android:layout_height="wrap_content">//左边的气泡(注意,在

在build.gradle里面增加 

compile 'com.lguipeng.bubbleview:library:1.0.0',不会的看链接:http://blog.csdn.net/bi_diu1368/article/details/51491646    
android :id= "@+id/left_msg" android :layout_width= "wrap_content" android :layout_height= "wrap_content" android :layout_marginTop= "10dp" android :textSize= "20sp" android :padding= "10dp" android :textColor= "@android:color/white" app :arrowWidth= "8dp" app :angle= "8dp" app :arrowHeight= "10dp" app :arrowPosition= "14dp" app :arrowLocation= "left" app :bubbleColor= "#7EC0EE" /> android :id= "@+id/right_layout" android :layout_width= "wrap_content" android :layout_height= "wrap_content" android :layout_gravity= "end" >
//右边的气泡
android :id= "@+id/right_msg" android :layout_width= "wrap_content" android :layout_height= "wrap_content" android :layout_marginTop= "10dp" android :textSize= "20sp" android :padding= "10dp" android :textColor= "@android:color/white" app :arrowWidth= "8dp" app :angle= "8dp" app :arrowHeight= "10dp" app :arrowPosition= "14dp" app :arrowLocation= "right" app :bubbleColor= "#7EC0EE" />

接下来需要创建ListView的适配器,让其继承ArrayAdapter,将类型指为Msg,代码如下:

public class MsgAdapter extends ArrayAdapter {    int resourced;    public MsgAdapter(Context context,int textViewResourced,List objects)    {        super(context,textViewResourced,objects);        resourced = textViewResourced;    }    @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(resourced,null);            viewHolder = new ViewHolder();            viewHolder.liftLayout = (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.liftLayout.setVisibility(View.VISIBLE);            viewHolder.rightLayout.setVisibility(View.GONE);            viewHolder.leftMsg.setText(msg.getContent());        }        else if(msg.getType() == Msg.SENT)        {            viewHolder.liftLayout.setVisibility(View.GONE);            viewHolder.rightLayout.setVisibility(View.VISIBLE);            viewHolder.rightMsg.setText(msg.getContent());        }        return view;    }    class  ViewHolder{        LinearLayout liftLayout;        LinearLayout rightLayout;        TextView leftMsg;        TextView rightMsg;    }}

这里可以看出,代码对ListView做了优化,getView中,有一个convertView参数,这个参数将以前加载好的布局进行缓存,以便之后的重用。在getView中,对 convertView进行判断,如果为空,则使用LayoutInflater去加载布局,如果不为空,则直接可以对convertView进行重用。

每次在getView中,都要调用View的findViewById()来获取控件的实例。但是,我们可以借助ViewHolder来进行优化。建一个内部类viewHolder,用于对控件的实例进行缓存。当convertView为空是,创建一个viewolder的对象,将控件的实例放到viewHolder里面,调用view的setTag()方法对控件的实例进行保存。如果convertView不为空,调用view 的getTag(),把viewHolder全部取出来,这样所有的控件实例都还缓存在了viewHolder中,没有必要每次都通过findViewById()获取空间的实例。


接着,写MainActivity,为ListView初始一些数据,并给发送按钮加入事件的响应。


public class MainActivity extends Activity {    private ListView listView;    private EditText input_et;  //信息输入    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.content_main);        initMsgList();   //为ListView初始化一些数据        adapter = new MsgAdapter(MainActivity.this,R.layout.msg_item,msgList);        listView = (ListView)findViewById(R.id.list_view);        input_et = (EditText)findViewById(R.id.input_et);        send = (Button)findViewById(R.id.send);        listView.setAdapter(adapter);        send.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                String content = input_et.getText().toString();                if(!"".equals(content))                {                    Msg msg = new Msg(content,Msg.SENT);                    msgList.add(msg);                    adapter.notifyDataSetChanged(); //当有新消息时,刷新ListView的显示                    listView.setSelection(msgList.size());  //将ListView定位到最后一行                    input_et.setText(""); //清空输入框的内容                }            }        });    }    public void initMsgList()    {        Msg msg1 = new Msg("Hello,Yan Xi.",Msg.RECEIVED);        msgList.add(msg1);        Msg msg2 = new Msg("Hello,Wen Heng.",Msg.SENT);        msgList.add(msg2);        Msg msg3 = new Msg("Miss You.",Msg.RECEIVED);        msgList.add(msg3);    }}

如图

更多相关文章

  1. android 之popupWindow 在指定位置上的显示
  2. Android(安卓)应用界面开发笔记
  3. android Activity的四种启动模式
  4. android之Animation的基本使用
  5. android自定义视图属性学习
  6. Android:网络编程及Internet应用
  7. Android(安卓)中Activity、Window、ViewRoot、DecorView之间的联
  8. 【Android(安卓)自定义控件】自定义View相关知识总结
  9. Android(安卓)自定义RadioButton的样式

随机推荐

  1. Android中如何取得联系人,如何得到一个联
  2. android Content Provider详解
  3. android Audio调试程序常用命令
  4. 认识Android
  5. Android入门进阶教程(12)-SystemService
  6. Android面试-Android部分
  7. 《Android 复杂的列表视图新写法 MultiTy
  8. 【译】Kotlin Android扩展(Kotlin Android
  9. 探究Android异步消息的处理之Handler详解
  10. LinearLayout 线性布局管理器