天天看点

Android ListView加载多种布局

我们经常看到聊天界面有各种布局显示,例如微信,网上也很多写相关的文章,这里值写一个简单的demo,先上一张图看下效果

Android ListView加载多种布局
Android ListView加载多种布局
Android ListView加载多种布局

效果图就如图片右侧,接下来我们看下demo怎么实现多种Item的加载。

这里还是使用listview,也可以使用其他开源的控件如PullToRefreshListView,RecycleView等。

看一下主界面的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="horizontal"
    >
    <FrameLayout
        android:layout_width="0dip"
        android:layout_height="fill_parent"
        android:layout_weight="2">
        <SurfaceView
            android:id="@+id/surface"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent" />

        <ImageButton
            android:id="@+id/take_pic"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical|right"
            android:background="@drawable/take_pic_selector" />
        <ImageView
            android:id="@+id/smallptoto"
            android:layout_width="100dip"
            android:layout_height="100dip"
            />
    </FrameLayout>

    <RelativeLayout
        android:layout_width="0dip"
        android:layout_height="match_parent"
        android:layout_weight="1.0"
        >
        <ListView
            android:id="@+id/deal_talk_list"
            android:layout_above="@+id/send_ll"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:cacheColorHint="#00000000"
            android:clipToPadding="false"
            android:divider="@android:color/white"
            android:background="#ffffff"
            android:dividerHeight="0.5dp"
            android:fadingEdge="none"
            android:fastScrollEnabled="false"
            android:footerDividersEnabled="true"
            android:headerDividersEnabled="false"
            android:scrollbarStyle="outsideOverlay"
            android:smoothScrollbar="true" />
        <RelativeLayout
            android:id="@+id/send_ll"
            android:background="#ffffff"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            >
            <EditText
                android:id="@+id/edit_send"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:textColor="@android:color/background_dark"
                android:layout_toLeftOf="@+id/send"
                android:maxLines="4"
                android:scrollbars="vertical"
                android:textSize="12sp"
                 />
            <Button android:id="@+id/send"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentRight="true"
                android:background="@drawable/bg_item_select"
                android:textSize="12sp"
                android:textColor="@android:color/background_dark"
                android:text="发送"/>
        </RelativeLayout>
    </RelativeLayout>
</LinearLayout>
      

效果就如图片布局一样,这里我们主要看ListView:

主界面里面主要是显示数据,这里做了一个简单操作,点击发送的按钮每次往listView中添加一个TalkBean,然后刷新数据,没点击一次往左边添加一条数据,再点击往右边添加一条,如此往复。看下onClick方法:

public void onClick(View v) {
    num++;
    switch (v.getId())
    {
        case  R.id.send:
            TalkBean talkBean=new TalkBean();
            talkBean.talk_content=edit.getText().toString();
            if(true) {
                talkBean.user_no = "xxnan";
                talkBean.isLeft=false;
            }else
            {
                talkBean.user_no = "jack";
                talkBean.isLeft=true;
            }
            list.add(talkBean);
            myAdapter.seList(list);//做刷新
        break;
    }
    deal_talk_list.setSelection(list.size()-1);
    edit.setText("");
}      

每次刷新完成之后listview滑到最底一个数据,把输入框显示为空。

然后主要是看下listview的adapter,这里我们自定义一个Adapter继承BaseAdapter:

/**
 * Created by xxnan on 2016/6/30.
 */
public class MyAdapter extends BaseAdapter {
    private Context mContext;
    private  List<TalkBean> mlist;
    private LayoutInflater inflater;
    public MyAdapter(Context applicationContext, List<TalkBean> list) {
        mContext=applicationContext;
        mlist=list;
        inflater=LayoutInflater.from(mContext);
    }
      
@Override
    public int getItemViewType(int position) {
        if(mlist.get(position).isLeft)
            return 0;
        else
        return 1;
    }

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

    @Override
    public Object getItem(int position) {
        return mlist.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }
    @Override
    public int getViewTypeCount() {
        return 2;
    }
    public void seList( List<TalkBean> list)
    {
        mlist=list;
        notifyDataSetChanged();
    }
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        TalkleftHolder talkleftHolder=null;
        TalkrightHolder talkrightHolder=null;
        TalkBean bean=mlist.get(position);
        int type=getItemViewType(position);
        if(convertView==null)
        {
            switch (type){
                case 0:
                    convertView =inflater.inflate(R.layout.talk_left_item,null);
                    talkleftHolder=new TalkleftHolder();
                    talkleftHolder.leftcontent=(Button)convertView.findViewById(R.id.talk_data_left_tv);
                    talkleftHolder.lefttalkname=(TextView) convertView.findViewById(R.id.talk_name_tv);
                    talkleftHolder.leftcontent.setText(bean.talk_content);
                    talkleftHolder.lefttalkname.setText(bean.user_name);
                    convertView.setTag(talkleftHolder);
                    break;
                case  1:
                    convertView =inflater.inflate(R.layout.talk_right_item,null);
                    talkrightHolder=new TalkrightHolder();
                    talkrightHolder.rightcontent=(Button)convertView.findViewById(R.id.talk_data_right_tv);
                    talkrightHolder.righttalkname=(TextView) convertView.findViewById(R.id.talk_myself_tv);
                    talkrightHolder.rightcontent.setText(bean.talk_content);
                    talkrightHolder.righttalkname.setText(bean.user_name);
                    convertView.setTag(talkrightHolder);
                    break;
                default:
                    break;
            }

        }else
        {
            switch (type){
                case 0:
                    talkleftHolder=(TalkleftHolder) convertView.getTag();
                    talkleftHolder.leftcontent.setText(bean.talk_content);
                    talkleftHolder.lefttalkname.setText(bean.user_no);
                    break;
                case  1:
                    talkrightHolder=(TalkrightHolder)convertView.getTag();
                    talkrightHolder.rightcontent.setText(bean.talk_content);
                    talkrightHolder.righttalkname.setText(bean.user_no);
                    break;
                default:
                    break;
            }
        }
        return convertView;
    }
    static class TalkleftHolder{
        private Button leftcontent;
        private TextView lefttalkname;
    }
   static class TalkrightHolder{
        private Button  rightcontent;
        private TextView righttalkname;
    }
}      
getItemViewType方法判断是左边还是右边,       
getViewTypeCount() 有多少中布局      

主要看getView方法,我们使用两种Holder分别代表左边和右边,然后优化也是重用convertView,如果convertView为null就创建,然后根据type设置不同的Tag,

convertView不为null则根据type获取Tag显示聊天内容和名称。

当然我们还可以添加更多的布局类型,也可以做的和微信一样漂亮,如果有意愿可以加以完善。

代码下载:https://github.com/xxnan/LiaoTianActivity