Android高级控件(五)——如何打造一个企业级应用对话列表,以QQ,微信为例

Android高级控件(五)——如何打造一个企业级应用对话列表,以QQ,微信为例


看标题这么高大上,实际上,还是运用我么拿到listview去扩展,我们讲什么呢,就是研究一下QQ,微信的这种对话列表,我们先看一个传统的ListView是怎么样的,我们做一个通讯录吧,通讯录的组成就是一个头像,一个名字,一个电话号码,一个点击拨打的按钮,既然这样,那我们的item就出来了

call_list_item.xml

<?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:gravity="center_vertical"
    android:orientation="horizontal">

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_weight="1"
        android:src="@mipmap/ic_launcher" />

    <TextView
        android:id="@+id/tv_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_weight="1" />

    <TextView
        android:id="@+id/tv_number"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_weight="3" />

    <Button
        android:id="@+id/mCall"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_weight="1" />

</LinearLayout>

大家都知道,我们一个listview还是需要一个数据集,那我们就写一个java的实体类吧

ContentBean

package com.lgl.wechatlist.bean;

import android.widget.Button;

/**
 * 实体类
 *
 * @author LGL
 */
public class ContentBean {

    private String name;
    private String number;

    private Button mButton;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getNumber() {
        return number;
    }

    public void setNumber(String number) {
        this.number = number;
    }

    public Button getmButton() {
        return mButton;
    }

    public void setmButton(Button mButton) {
        this.mButton = mButton;
    }
}

传统的ListView,我相信大家都知道写,直接给出Adapter

ContentAdapter

package com.lgl.wechatlist.adapter;

import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.TextView;

import com.lgl.wechatlist.R;
import com.lgl.wechatlist.bean.ContentBean;

import java.util.List;

public class ContentAdapter extends BaseAdapter {

    private Context mContext;

    private List<ContentBean> mList;

    private LayoutInflater mInflater;

    private ContentBean bean;

    public ContentAdapter(Context mContext, List<ContentBean> mList) {
        this.mContext = mContext;
        this.mList = mList;
        mInflater = (LayoutInflater) mContext
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

    @Override
    public int getCount() {
        // TODO Auto-generated method stub
        return mList.size();
    }

    @Override
    public Object getItem(int position) {
        // TODO Auto-generated method stub
        return mList.get(position);
    }

    @Override
    public long getItemId(int position) {
        // TODO Auto-generated method stub
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHodler viewHodler;

        if (convertView == null) {

            viewHodler = new ViewHodler();
            convertView = mInflater.inflate(R.layout.call_list_item, null);
            viewHodler.tv_name = (TextView) convertView
                    .findViewById(R.id.tv_name);
            viewHodler.tv_number = (TextView) convertView
                    .findViewById(R.id.tv_number);
            viewHodler.mCall = (Button) convertView.findViewById(R.id.mCall);
            convertView.setTag(viewHodler);
        } else {
            viewHodler = (ViewHodler) convertView.getTag();
        }

        bean = mList.get(position);
        viewHodler.tv_name.setText(bean.getName());
        viewHodler.tv_number.setText(bean.getNumber());
        viewHodler.mCall.setText("拨打");
        viewHodler.mCall.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                Call(bean.getNumber());
            }
        });

        return convertView;
    }

    class ViewHodler {
        private TextView tv_name;
        private TextView tv_number;
        private Button mCall;
    }

    /**
     * 拨打电话
     *
     * @param phone
     */
    public void Call(String phone) {
        Intent intent = new Intent();
        intent.setAction("android.intent.action.CALL");
        intent.addCategory("android.intent.category.DEFAULT");
        intent.setData(Uri.parse("tel:"+phone));
        mContext.startActivity(intent);
    }

}

当然,还需要在我们的主类中获取数据

package com.lgl.listview;

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

import android.app.Activity;
import android.database.Cursor;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.widget.ListView;

public class MainActivity extends Activity {

    private ListView mListView;
    // 联系人集合
    private List<String> contentName = new ArrayList<String>();
    // 号码集合
    private List<String> contentPhone = new ArrayList<String>();
    private List<ContentBean> list = new ArrayList<ContentBean>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        getContent();
        mListView = (ListView) findViewById(R.id.mListView);

        for (int i = 0; i < contentName.size(); i++) {
            ContentBean bean = new ContentBean();
            bean.setName(contentName.get(i));
            bean.setNumber(contentPhone.get(i));
            list.add(bean);
        }

        ContentAdapter adapter = new ContentAdapter(this, list);
        mListView.setAdapter(adapter);

    }

    /**
     * 获取联系人
     */
    private void getContent() {
        Cursor query = getContentResolver().query(
                ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null,
                null, null);
        // 创建一个对象进行储存
        String name; // 联系人
        String phone; // 电话号码
        // 我们获取到这些信息之后遍历出来
        while (query.moveToNext()) {
            // 获取名字就需要Phone.DISPLAY_NAME
            name = query
                    .getString(query
                            .getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
            // 获取num字段需要Phone.NUMBER
            phone = query
                    .getString(query
                            .getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
            contentName.add(name);
            contentPhone.add(phone);
        }
    }
}

这样,一个简易的通讯录就做好了

OK,这个没什么问题,但是我们今天要讨论的,是一个对话的ListView,这在我们之前看的群英传一书中也提到过Android群英传笔记——第四章:ListView使用技巧,但是讲的不是很详细,我们这里就多讲一下了,我们要区分左右,也就是type,需要用到getViewTypeCount()和getItemViewType()方法, 根据数据源的position返回需要显示的的layout的type,那我们从易到难,先写一个简单点的,就一个简单的文字对话框,怎么实现呢?我们当然得先定义left和right的item布局了

chatlist_left.xml

<?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:gravity="bottom"
    android:orientation="horizontal"
    android:padding="10dp">

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="20dp"
        android:src="@mipmap/ic_launcher" />

    <TextView
        android:id="@+id/chatlist_tv_left"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="20dp"
        android:background="@drawable/pop_left"
        android:gravity="center"
        android:padding="20dp" />

</LinearLayout>

chatlist_right.xml

<?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:gravity="right|bottom"
    android:orientation="horizontal"
    android:padding="10dp">

    <TextView
        android:id="@+id/chatlist_tv_right"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginRight="20dp"
        android:background="@drawable/pop_right"
        android:gravity="center"
        android:padding="20dp" />

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginRight="20dp"
        android:src="@mipmap/ic_launcher" />

</LinearLayout>

OK,别忘了这是一个新的listview,所以我们还得写一个实体类

ChatListBean

package com.lgl.wechatlist.bean;

/**
 * 对话实体类
 *
 * @author LGL
 *
 */
public class ChatListBean {

    // 指定方向
    private int type;
    // 文本
    private String value;

    public int getType() {
        return type;
    }

    public void setType(int type) {
        this.type = type;
    }

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }
}

这样就对我们的adapter进行分析了

ChatListAdapter

package com.lgl.wechatlist.adapter;

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

import com.lgl.wechatlist.R;
import com.lgl.wechatlist.bean.ChatListBean;

import java.util.List;

/**
 * 对话ListView
 */
public class ChatListAdapter extends BaseAdapter {

    public static final String KEY = "key";
    public static final String VALUE = "value";

    public static final int VALUE_LEFT_TEXT = 1;
    public static final int VALUE_RIGHT_TEXT = 2;
    private LayoutInflater mInflater;

    private List<ChatListBean> myList;

    public ChatListAdapter(Context context, List<ChatListBean> myList) {
        this.myList = myList;

        mInflater = (LayoutInflater) context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

    }

    @Override
    public int getCount() {
        return myList.size();
    }

    @Override
    public Object getItem(int arg0) {
        return myList.get(arg0);
    }

    @Override
    public long getItemId(int arg0) {
        return arg0;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup arg2) {

        ChatListBean msg = myList.get(position);
        int type = getItemViewType(position);
        ViewHolderRightText holderRightText = null;
        ViewHolderLeftText holderLeftText = null;

        if (convertView == null) {
            switch (type) {
                // 左边
                case VALUE_LEFT_TEXT:
                    holderLeftText = new ViewHolderLeftText();
                    convertView = mInflater.inflate(R.layout.chatlist_left, null);
                    holderLeftText.btnLeftText = (TextView) convertView
                            .findViewById(R.id.chatlist_tv_left);
                    holderLeftText.btnLeftText.setText(msg.getValue());
                    convertView.setTag(holderLeftText);
                    break;
                // 右边
                case VALUE_RIGHT_TEXT:
                    holderRightText = new ViewHolderRightText();
                    convertView = mInflater.inflate(R.layout.chatlist_right, null);
                    holderRightText.btnRightText = (TextView) convertView
                            .findViewById(R.id.chatlist_tv_right);
                    holderRightText.btnRightText.setText(msg.getValue());
                    convertView.setTag(holderRightText);
                    break;
            }

        } else {
            switch (type) {
                case VALUE_LEFT_TEXT:
                    holderLeftText = (ViewHolderLeftText) convertView.getTag();
                    holderLeftText.btnLeftText.setText(msg.getValue());
                    break;
                case VALUE_RIGHT_TEXT:
                    holderRightText = (ViewHolderRightText) convertView.getTag();
                    holderRightText.btnRightText.setText(msg.getValue());
                    break;
            }

        }
        return convertView;
    }

    /**
     * 根据数据源的position返回需要显示的的layout的type
     * <p/>
     * type的值必须从0开始
     */
    @Override
    public int getItemViewType(int position) {

        ChatListBean msg = myList.get(position);
        int type = msg.getType();
        return type;
    }

    /**
     * 返回所有的layout的数量
     */
    @Override
    public int getViewTypeCount() {
        return 7;
    }

    // 左边的文本
    class ViewHolderLeftText {
        private TextView btnLeftText;
    }

    // 右边的文本
    class ViewHolderRightText {
        private TextView btnRightText;
    }

}

我们去主类中写点数据

package com.lgl.wechatlist;

import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.ListView;

import com.lgl.wechatlist.adapter.ChatListAdapter;
import com.lgl.wechatlist.bean.ChatListBean;

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

/**
 * Created by LGL on 2016/5/7.
 */
public class QQActivity extends AppCompatActivity implements View.OnClickListener{

    // 会话数据源
    private List<ChatListBean> ListData;
    // 会话Adapter
    private ChatListAdapter chatListAdapter;
    // 会话列表
    private ListView mListView;
    // 消息
    private String message;
    // 按钮
    private Button btn_left, btn_right;
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_qq);
        mListView = (ListView) findViewById(R.id.mListView);
        btn_left = (Button) findViewById(R.id.btn_left);
        btn_left.setOnClickListener(this);
        btn_right = (Button) findViewById(R.id.btn_right);
        btn_right.setOnClickListener(this);

        ListData = new ArrayList<ChatListBean>();
        ChatListBean chatListBean = new ChatListBean();
        chatListBean.setType(ChatListAdapter.VALUE_LEFT_TEXT);
        chatListBean.setValue("你好!");
        ListData.add(chatListBean);

        chatListAdapter = new ChatListAdapter(this, ListData);
        mListView.setAdapter(chatListAdapter);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn_left:
                listLeft("left");
                break;
            case R.id.btn_right:
                listRight("right");
                break;
        }
    }
    /**
     * 显示列表左边
     *
     * @param text
     */
    private void listLeft(String text) {
        ChatListBean left = new ChatListBean();
        left.setType(ChatListAdapter.VALUE_LEFT_TEXT);
        left.setValue(text);
        ListData.add(left);
        chatListAdapter.notifyDataSetChanged();
        // 滚动到最底部
        mListView.setSelection(mListView.getBottom());
    }

    /**
     * 显示右边列表
     *
     * @param text
     */
    private void listRight(String text) {
        ChatListBean right = new ChatListBean();
        right.setType(ChatListAdapter.VALUE_RIGHT_TEXT);
        right.setValue(text);
        ListData.add(right);
        chatListAdapter.notifyDataSetChanged();
        // 滚动到最底部
        mListView.setSelection(mListView.getBottom());
    }
}

好的运行一下

到这里,我们就对这个技巧有点熟悉了吧,既然如此,那我们即系,现在我们有6个item,分别是文字左右,图片左右,语言左右,这里就不贴出来了,要看的直接去Demo里面找哟,也没多少东西,就几个文本布局而已,我们直接来看实体类

MessageBean

package com.lgl.wechatlist.bean;

public class MessageBean {

    private int type;//指定是哪种类型
    private String value;//值

    public int getType() {
        return type;
    }

    public void setType(int type) {
        this.type = type;
    }

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }
}

你一看,和上次那个没什么不同,对的,是没什么不同,只不过代码多了一点而已,这样的话,我们可以看Adapter了

package com.lgl.wechatlist.adapter;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;

import com.lgl.wechatlist.R;
import com.lgl.wechatlist.bean.MessageBean;

import java.util.List;

/**
 * 比原来的多了getItemViewType和getViewTypeCount这两个方法,
 *
 * */
public class WechatAdapter extends BaseAdapter {

    public static final String KEY = "key";
    public static final String VALUE = "value";

    public static final int VALUE_LEFT_TEXT = 1;
    public static final int VALUE_LEFT_IMAGE = 2;
    public static final int VALUE_LEFT_AUDIO = 3;
    public static final int VALUE_RIGHT_TEXT = 4;
    public static final int VALUE_RIGHT_IMAGE = 5;
    public static final int VALUE_RIGHT_AUDIO = 6;
    private LayoutInflater mInflater;

    private List<MessageBean> myList;

    public WechatAdapter(Context context, List<MessageBean> myList) {
        this.myList = myList;

        mInflater = (LayoutInflater) context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

    @Override
    public int getCount() {
        return myList.size();
    }

    @Override
    public Object getItem(int arg0) {
        return myList.get(arg0);
    }

    @Override
    public long getItemId(int arg0) {
        return arg0;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup arg2) {

        MessageBean msg = myList.get(position);
        int type = getItemViewType(position);
        ViewHolderRightText holderRightText = null;
        ViewHolderRightImg holderRightImg = null;
        ViewHolderRightAudio holderRightAudio = null;
        ViewHolderLeftText holderLeftText = null;
        ViewHolderLeftImg holderLeftImg = null;
        ViewHolderLeftAudio holderLeftAudio = null;

        if (convertView == null) {
            switch (type) {
            // 左边
            case VALUE_LEFT_TEXT:
                holderLeftText = new ViewHolderLeftText();
                convertView = mInflater.inflate(R.layout.list_item_left_text,
                        null);
                holderLeftText.ivLeftIcon = (ImageView) convertView
                        .findViewById(R.id.iv_icon);
                holderLeftText.btnLeftText = (Button) convertView
                        .findViewById(R.id.btn_left_text);
                holderLeftText.btnLeftText.setText(msg.getValue());
                convertView.setTag(holderLeftText);
                break;

            case VALUE_LEFT_IMAGE:
                holderLeftImg = new ViewHolderLeftImg();
                convertView = mInflater.inflate(R.layout.list_item_left_iamge,
                        null);
                holderLeftImg.ivLeftIcon = (ImageView) convertView
                        .findViewById(R.id.iv_icon);
                holderLeftImg.ivLeftImage = (ImageView) convertView
                        .findViewById(R.id.iv_left_image);
                holderLeftImg.ivLeftImage.setImageResource(R.mipmap.ic_launcher);
                convertView.setTag(holderLeftImg);
                break;

            case VALUE_LEFT_AUDIO:
                holderLeftAudio = new ViewHolderLeftAudio();
                convertView = mInflater.inflate(R.layout.list_item_left_audio,
                        null);
                holderLeftAudio.ivLeftIcon = (ImageView) convertView
                        .findViewById(R.id.iv_icon);
                holderLeftAudio.btnLeftAudio = (Button) convertView
                        .findViewById(R.id.btn_left_audio);
                holderLeftAudio.tvLeftAudioTime = (TextView) convertView
                        .findViewById(R.id.tv_left_audio_time);
                holderLeftAudio.tvLeftAudioTime.setText(msg.getValue());
                convertView.setTag(holderLeftAudio);
                break;
            // 右边
            case VALUE_RIGHT_TEXT:
                holderRightText= new ViewHolderRightText();
                convertView = mInflater.inflate(R.layout.list_item_right_text,
                        null);
                holderRightText.ivRightIcon = (ImageView) convertView
                        .findViewById(R.id.iv_icon);
                holderRightText.btnRightText = (Button) convertView
                        .findViewById(R.id.btn_right_text);
                holderRightText.btnRightText.setText(msg.getValue());
                convertView.setTag(holderRightText);
                break;

            case VALUE_RIGHT_IMAGE:
                holderRightImg= new ViewHolderRightImg();
                convertView = mInflater.inflate(R.layout.list_item_right_iamge,
                        null);
                holderRightImg.ivRightIcon = (ImageView) convertView
                        .findViewById(R.id.iv_icon);
                holderRightImg.ivRightImage = (ImageView) convertView
                        .findViewById(R.id.iv_right_image);
                holderRightImg.ivRightImage.setImageResource(R.mipmap.ic_launcher);
                convertView.setTag(holderRightImg);
                break;

            case VALUE_RIGHT_AUDIO:
                holderRightAudio=new ViewHolderRightAudio();
                convertView = mInflater.inflate(R.layout.list_item_right_audio,
                        null);
                holderRightAudio.ivRightIcon = (ImageView) convertView
                        .findViewById(R.id.iv_icon);
                holderRightAudio.btnRightAudio = (Button) convertView
                        .findViewById(R.id.btn_right_audio);
                holderRightAudio.tvRightAudioTime = (TextView) convertView
                        .findViewById(R.id.tv_right_audio_time);
                holderRightAudio.tvRightAudioTime.setText(msg.getValue());
                convertView.setTag(holderRightAudio);
                break;

            default:
                break;
            }

        } else {
            switch (type) {
            case VALUE_LEFT_TEXT:
                holderLeftText=(ViewHolderLeftText)convertView.getTag();
                holderLeftText.btnLeftText.setText(msg.getValue());
                break;
            case VALUE_LEFT_IMAGE:
                holderLeftImg=(ViewHolderLeftImg)convertView.getTag();
                holderLeftImg.ivLeftImage.setImageResource(R.mipmap.ic_launcher);
                break;
            case VALUE_LEFT_AUDIO:
                holderLeftAudio=(ViewHolderLeftAudio)convertView.getTag();
                holderLeftAudio.tvLeftAudioTime.setText(msg.getValue());
                break;
            case VALUE_RIGHT_TEXT:
                holderRightText=(ViewHolderRightText)convertView.getTag();
                holderRightText.btnRightText.setText(msg.getValue());
                break;
            case VALUE_RIGHT_IMAGE:
                holderRightImg=(ViewHolderRightImg)convertView.getTag();
                holderRightImg.ivRightImage.setImageResource(R.mipmap.ic_launcher);
                break;
            case VALUE_RIGHT_AUDIO:
                holderRightAudio=(ViewHolderRightAudio)convertView.getTag();
                holderRightAudio.tvRightAudioTime.setText(msg.getValue());
                break;

            default:
                break;
            }

            //holder = (ViewHolder) convertView.getTag();
        }
        return convertView;
    }

    /**
     * 根据数据源的position返回需要显示的的layout的type
     *
     * type的值必须从0开始
     *
     * */
    @Override
    public int getItemViewType(int position) {

        MessageBean msg = myList.get(position);
        int type = msg.getType();
        return type;
    }

    /**
     * 返回所有的layout的数量
     *
     * */
    @Override
    public int getViewTypeCount() {
        return 7;
    }

    class ViewHolderRightText {
        private ImageView ivRightIcon;// 右边的头像
        private Button btnRightText;// 右边的文本
    }

    class ViewHolderRightImg {
        private ImageView ivRightIcon;// 右边的头像
        private ImageView ivRightImage;// 右边的图像
    }

    class ViewHolderRightAudio {
        private ImageView ivRightIcon;// 右边的头像
        private Button btnRightAudio;// 右边的声音
        private TextView tvRightAudioTime;// 右边的声音时间
    }

    class ViewHolderLeftText {
        private ImageView ivLeftIcon;// 左边的头像
        private Button btnLeftText;// 左边的文本
    }

    class ViewHolderLeftImg {
        private ImageView ivLeftIcon;// 左边的头像
        private ImageView ivLeftImage;// 左边的图像
    }

    class ViewHolderLeftAudio {
        private ImageView ivLeftIcon;// 左边的头像
        private Button btnLeftAudio;// 左边的声音
        private TextView tvLeftAudioTime;// 左边的声音时间
    }

}

OK,代码清晰可见

我们的主类

package com.lgl.wechatlist;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.ListView;

import com.lgl.wechatlist.adapter.WechatAdapter;
import com.lgl.wechatlist.bean.MessageBean;

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

public class WechatActivity extends AppCompatActivity {

    private ListView lvData;
    private List<MessageBean> msgList;
    private MessageBean msg;
    private WechatAdapter adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_wechat);

        lvData = (ListView) findViewById(R.id.lv_data);

        msgList = new ArrayList<MessageBean>();

        adapter = new WechatAdapter(WechatActivity.this, msgList);

        lvData.setAdapter(adapter);
    }

    /**
     * 左边文字
     *
     * @param v
     */
    public void tv_left(View v) {
        MessageBean msg = new MessageBean();
        msg.setType(WechatAdapter.VALUE_LEFT_TEXT);
        msg.setValue("我是文字左");
        msgList.add(msg);
        adapter.notifyDataSetChanged();
        //滑动到底部
        lvData.setSelection(lvData.getBottom());
    }

    /**
     * 右边文字
     *
     * @param v
     */
    public void tv_right(View v) {
        MessageBean msg = new MessageBean();
        msg.setType(WechatAdapter.VALUE_RIGHT_TEXT);
        msg.setValue("我是文字右");
        msgList.add(msg);
        adapter.notifyDataSetChanged();
        //滑动到底部
        lvData.setSelection(lvData.getBottom());
    }

    /**
     * 左边图片
     *
     * @param v
     */
    public void iv_left(View v) {
        MessageBean msg = new MessageBean();
        msg.setType(WechatAdapter.VALUE_LEFT_IMAGE);
        msg.setValue("我是图片左");
        msgList.add(msg);
        adapter.notifyDataSetChanged();
        //滑动到底部
        lvData.setSelection(lvData.getBottom());
    }

    /**
     * 右边图片
     *
     * @param v
     */
    public void iv_right(View v) {
        msg = new MessageBean();
        msg.setType(WechatAdapter.VALUE_RIGHT_IMAGE);
        msg.setValue("我是图片右");
        msgList.add(msg);
        adapter.notifyDataSetChanged();
        //滑动到底部
        lvData.setSelection(lvData.getBottom());
    }

    /**
     * 左边语音
     *
     * @param v
     */
    public void iv_left_audio(View v) {
        msg = new MessageBean();
        msg.setType(WechatAdapter.VALUE_LEFT_AUDIO);
        msg.setValue("16s");
        msgList.add(msg);
        adapter.notifyDataSetChanged();
        //滑动到底部
        lvData.setSelection(lvData.getBottom());
    }

    /**
     * 右边语音
     *
     * @param v
     */
    public void iv_right_audio(View v) {
        msg = new MessageBean();
        msg.setType(WechatAdapter.VALUE_RIGHT_AUDIO);
        msg.setValue("6s");
        msgList.add(msg);
        adapter.notifyDataSetChanged();
        //滑动到底部
        lvData.setSelection(lvData.getBottom());
    }

}

那这样的话,我们运行一下

行,我们是不是已经有了大致的了解,我Demo也理得比较顺,要是看的不是很懂可以结合Demo来

Demo下载地址:http://download.csdn.net/detail/qq_26787115/9512985

我的群,通往Android的神奇之旅 :555974449,欢迎大家进来交流技术!

时间: 2016-05-07

Android高级控件(五)——如何打造一个企业级应用对话列表,以QQ,微信为例的相关文章

Android高级控件(二)——SurfaceView实现GIF动画架包,播放GIF动画,自己实现功能的初体现

Android高级控件(二)--SurfaceView实现GIF动画架包,播放GIF动画,自己实现功能的初体现 写这个的原因呢,也是因为项目中用到了gif动画,虽然网上有很多的架包可以实现,不过我们还是要追究一下原理怎么做的,我们新建一个GifLibrary,然后右键Properties--Android,我们把架包勾上 然后我们新建一个类GifSurfaceView继承自SurfaceView并且实现它的Callback接口 GifSurfaceView package com.lgl.gif

Android 高级控件

高级控件: GridView ScrollView ViewPager SlideMenu PullToRefreshListView 1.ScrollView视图(滚动视图)可以有效的安排这些组件,浏览时可以进行滚屏的操作 垂直滚动--ScrollView 水平滚动--HorizontalScrollView ScrollView是单一容器,只能包含一个组件 练习:设置界面的垂直滚动                        理想效果                            

android中高级控件问题

问题描述 android中高级控件问题 android高级控件中添加图片为何老是出现错误,该怎么办.大神们求解决 解决方案 因为是高级控件啊, 你还要添加图片, 于是就出现了错误 解决方案二: 楼上说的很有道理,因为太高级.. 解决方案三: android 控件花屏问题android gallery控件的使用问题android自定义控件焦点问题 解决方案四: 什么高级控件???说清楚一些~

教你五分钟打造一个文字时空洞

  新手教程,教你五分钟打造一个文字时空洞!本教程为翻译+改造,原作者是个外国人,已经不记得是谁了,有知道的欢迎补充.本教程然将教你如何创作一个富有空间感的字体图案. 分类: PS文字教程

eSWT移动扩展简介,第2部分: 在移动应用程序中使用高级控件

简介 随着移动平台变得越来越复杂,移动计算需求将会不断增长.嵌入式 Standard Widget Toolkit (eSWT) Mobile Extension 是一种 Eclipse 技术,可以用于为各种移动电话开发具有桌面应用程序外观的 Java 应用程序. 本系列的 eSWT 移动扩展简介,第 1 部分:使用简单小部件快速构建移动应用程序 "使用简单小部件快速构建移动应用程序" 对移动扩展包作了概述.它还描述了一些基本控件(CaptionedControl.Constraine

ASP.NET 2.0高级控件之FileUpload控件

asp.net|高级|控件 应用程序中经常需要允许用户把文件上传到web服务器.尽管在ASP.NET 1.X也可以完成该功能,但在ASP.NET 2.0中使用FileUpload控件会更简单. 该控件让用户更容易地浏览和选择用于上传的文件,它包含一个浏览按钮和用于输入文件名的文本框.只要用户在文本框中输入了完全限定的文件名,无论是直接输入或通过浏览按钮选择,都可以调用FileUpload的SaveAs方法保存到磁盘上. 除了从WebControl类继承的标准成员,FileUpload控件还公开了

打造一个通用ASP.NET数据分页控件

asp.net|分页|控件|数据 对于几乎所有的数据表现Web应用来说,组织好数据的显示方式.避免给用户带来混乱的感觉就是最主要的目标之一.每个页面显示20条记录当然是可以接受的,但每页显示10000条记录就很容易给用户带来不便了.将数据分成多个页面显示,即对数据进行分页,是解决此类问题的最常见的办法. 一.慨述 ASP.NET本身只提供了一个支持数据分页的控件,即DataGrid分页控件,不过它比较适合Intranet环境使用,对于Internet环境来说,DataGrid分页控件提供的功能似

ASP.NET自定义控件 第五天 真正可以评分的星级控件

1. 引言 在前几次任务里开发的星级控件仅适用于静态展示,例如标明某个软件的受欢 迎度,但是实际上很多网站还希望能够由用户对某一信息进行评分,最终计算出 该信息的受欢迎程度,使数据更为客观和可信,由此需要在原有的星级控件上加 以改进,使用户能够动态评分,实际的效果图看起来如下图所示: 图中第一行是经过评分后控件的状态,开发人员处理了评分事件并在页面输出 了选择的分数:图中第二行显示了另外一种评分状态--鼠标移动到了星形图案 上,此时使用红色的星形提示用户. 2. 分析 对于该控件我们要在原有控件

如何打造一个高逼格的云运维平台?

作者简介 鲁逸丁  中国银行卡组织运维架构师 长期从事金融信息系统运维工作,专注于运维体系建设,对金融企业云计算运维具有深刻理解,银行卡组织云运维平台负责人. 前言 大家做运维普遍经历这样的过程: 首先我们会把操作做一个标准化,这个阶段是运维质量的提升的阶段. 在标准化实施完以后,由于数目的增加,或者是一些运维场景的增多,我们会逐步的进行一些工具化和自动化,这个阶段我们的运维的效率得到提升. 但是众多的工具以及自动化脚本,会让我们的管理过程中比较困难,随着人员的变动或者是一些工具维护过程中的差错

Android高仿IOS 滚轮选择控件_Android

最近根据项目需要,整理了一个相对比较全面的 WheelView 使用控件,借用之前看到的一句话来说,就是站在巨人肩膀上,进行了一些小调整. 这里先贴上效果图 一般常用的时间选择格式,,单项选择,以及城市联动,这里基本都可以满足了. 这里把 单项选择,和 日期时间选择 给提出到 Util 类中,代码如下: public class Util { /** * 时间选择回调 */ public interface TimerPickerCallBack { void onTimeSelect(Stri