Android listview加载不同布局与adapter用法

来源:互联网 发布:软件停止运行怎么回事 编辑:程序博客网 时间:2024/06/07 03:17

Android listview加载不同布局与adapter用法
android开发过程中会经常用到listview,虽然recycleview也出来了,但是还是存在一些bug没有解决,还不是特别的成熟,那我们就来介绍一下listview的使用及其加载不同布局的item的一般写法。

  1. 首先我们listview需要加载不同的布局,首先我们需要些几个不同的布局(我写不同item的布局喜欢以inflate_功能_type_one来命名,大家可以根据自己的习惯,但是一定要有一个好的编程习惯哦!!!)
    布局一:
<?xml version="1.0" encoding="utf-8"?><TextView xmlns:android="http://schemas.android.com/apk/res/android"    android:id="@+id/txt_inflat_type_one"    android:background="#44C494"    android:layout_width="match_parent"    android:layout_height="40dp"></TextView>

布局二:

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:orientation="horizontal"    android:background="#ffa07a"    android:layout_width="match_parent"    android:layout_height="40dp">    <TextView        android:id="@+id/txt_inflat_type_two"        android:layout_width="200dp"        android:layout_height="match_parent" />    <ImageView        android:id="@+id/img_inflat_type_two"        android:layout_width="match_parent"        android:layout_height="match_parent"        android:contentDescription="@null"        android:background="@mipmap/ic_launcher"/></LinearLayout>

布局三:

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:orientation="horizontal"    android:layout_width="match_parent"    android:layout_height="40dp">    <TextView        android:id="@+id/txt_inflat_type_there_1"        android:layout_width="match_parent"        android:layout_height="match_parent" />    <TextView        android:id="@+id/txt_inflat_type_there_2"        android:layout_width="match_parent"        android:layout_height="match_parent"        /></LinearLayout>
  1. 接下来就是需要写的是MyAdapter了,我这里是继承BaseAdapter来写的,首先我们需要重写BaseAdapter的四个方法,getCount(listview需要展示的个数,根据数据源而定的,我在这里是写的规固定的)、getItem(获取数据源的单个实体类)、getItemId(获取下角标位置)、getView(UI控件的获取及其数据的挂载)。
    这里,我们需要写的是不同布局item显示的样式,我们还需要重写其他两个方法:getItemViewType(获取每一个下角标(position)相对应得item类型),getViewTypeCount(几种布局的显示的总数)。
    注意
        //listview显示时的不同布局的item        private int TypeOne=0;//注意这个不同布局的类型起始值必须从0开始        private int TypeTwo=1;        private int TypeThere=2;
  1. 因为在实际开发项目中,我们要加载的数据往往是特别大的,这时候我们就要考虑布局的复用,说到复用我们就要来了解一下ListView的原理:ListView中的每一个Item显示都需要Adapter调用一次getView的方法,这个方法会传入一个convertView的参数,返回的View就是这个Item显示的View。如果当Item的数量足够大,再为每一个Item都创建一个View对象,必将占用很多内存,创建View对象(getLayoutInflater().inflate(R.layout.inflate_type_one, parent,false);从xml中生成View,这是属于IO操作)也是耗时操作,所以必将影响性能。Android提供了一个叫做Recycler(反复循环器)的构件,就是当ListView的Item从上方滚出屏幕视角之外,对应Item的View会被缓存到Recycler中,相应的会从下方生成一个Item,而此时调用的getView中的convertView参数就是滚出屏幕的Item的View,所以说如果能重用这个convertView,就会大大改善性能。

getView方法中的操作是这样的:先从xml中创建view对象(inflate操作,我们采用了重用convertView方法优化),然后在这个view去findViewById,找到每一个子View,如:一个TextView等。这里的findViewById操作是一个树查找过程,也是一个耗时的操作,所以这里也需要优化,就是使用viewHolder,把每一个子View都放在Holder中,当第一次创建convertView对象时,把这些子view找出来。然后用convertView的setTag将viewHolder设置到Tag中,以便系统第二次绘制ListView时从Tag中取出。当第二次重用convertView时,只需从convertView中getTag取出来就可以。

我们就需要先写几个不同item需要的viewHolder类:

private class TypeOneViewHolder{            private TextView txt_inflat_type_one;        }private class TypeTwoViewHolder{            private TextView txt_inflat_type_two;            private ImageView img_inflat_type_two;        }  private class TypeThereViewHolder{            private TextView txt_inflat_type_there_1;            private TextView txt_inflat_type_there_2;        }

getView方法:

@Override        public View getView(int position, View convertView, ViewGroup parent) {            TypeOneViewHolder typeOneViewHolder = null;            TypeTwoViewHolder typeTwoViewHolder = null;            TypeThereViewHolder typeThereViewHolder = null;            int Type=getItemViewType(position);            //第一次没有加载convertView            if(convertView==null){                if(Type==TypeOne){                    convertView=getLayoutInflater().inflate(R.layout.inflate_type_one,parent,false);                    typeOneViewHolder=new TypeOneViewHolder();                    typeOneViewHolder.txt_inflat_type_one= (TextView) convertView.findViewById(R.id.txt_inflat_type_one);                    convertView.setTag(typeOneViewHolder);                }else if(Type==TypeTwo){                    convertView=getLayoutInflater().inflate(R.layout.inflate_type_two,parent,false);                    typeTwoViewHolder=new TypeTwoViewHolder();                    typeTwoViewHolder.txt_inflat_type_two= (TextView) convertView.findViewById(R.id.txt_inflat_type_two);                    typeTwoViewHolder.img_inflat_type_two= (ImageView) convertView.findViewById(R.id.img_inflat_type_two);                    convertView.setTag(typeTwoViewHolder);                }else if(Type==TypeThere){                    convertView=getLayoutInflater().inflate(R.layout.inflate_type_there,parent,false);                    typeThereViewHolder=new TypeThereViewHolder();                    typeThereViewHolder.txt_inflat_type_there_1= (TextView) convertView.findViewById(R.id.txt_inflat_type_there_1);                    typeThereViewHolder.txt_inflat_type_there_2= (TextView) convertView.findViewById(R.id.txt_inflat_type_there_2);                    convertView.setTag(typeThereViewHolder);                }            }else {            //布局的复用convertView            //根据setTag()和getTag()方法来实现布局的复用                if(Type==TypeOne){                    typeOneViewHolder= (TypeOneViewHolder) convertView.getTag();                }else if(Type==TypeTwo){                    typeTwoViewHolder= (TypeTwoViewHolder) convertView.getTag();                }else if(Type==TypeThere){                    typeThereViewHolder= (TypeThereViewHolder) convertView.getTag();                }            }            //设置数据            if(Type==TypeOne){                typeOneViewHolder.txt_inflat_type_one.setText("第一种布局"+position);            }else if(Type==TypeTwo){                typeTwoViewHolder.txt_inflat_type_two.setText("第二种布局"+position);                typeTwoViewHolder.img_inflat_type_two.setImageResource(R.mipmap.ic_launcher);            }else if(Type==TypeThere){                typeThereViewHolder.txt_inflat_type_there_1.setText("第三种布局"+position+"左");                typeThereViewHolder.txt_inflat_type_there_2.setText("第三种布局"+position+"右");            }            return convertView;        }

实现效果截图:
这里写图片描述

这里写图片描述

最后附整体代码:

package com.example.administrator.baseadapterapplication;import android.content.Context;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.ImageView;import android.widget.ListView;import android.widget.TextView;/** * Android listview加载不同布局与adapter用法 *@author wujun * */public class MainActivity extends AppCompatActivity {    private ListView listView;    private MyAdapter myAdapter;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        initView();        initData();    }    private void initView() {        listView= (ListView) findViewById(R.id.listview);    }    private void initData() {        myAdapter=new MyAdapter(MainActivity.this);        listView.setAdapter(myAdapter);        myAdapter.notifyDataSetChanged();    }    //适配器    private class  MyAdapter extends BaseAdapter {        private Context mcontext;        //listview显示时的不同布局的item        private int TypeOne=0;//注意这个不同布局的类型起始值必须从0开始        private int TypeTwo=1;        private int TypeThere=2;        private   MyAdapter(Context context){            mcontext=context;        }        @Override        public int getCount() {            return 30;        }        @Override        public Object getItem(int position) {            return null;        }        @Override        public long getItemId(int position) {            return position;        }        //item的不同布局的判断        @Override        public int getItemViewType(int position) {//            return super.getItemViewType(position);            if(position==1||position==5||position==10||position==15||position==20||position==26){                return TypeOne;            }else if(position==2||position==6||position==8||position==13||position==23||position==0){                return TypeTwo;            }else {                return TypeThere;            }        }        @Override        public int getViewTypeCount() {//            return super.getViewTypeCount();            return 3;        }        @Override        public View getView(int position, View convertView, ViewGroup parent) {            TypeOneViewHolder typeOneViewHolder = null;            TypeTwoViewHolder typeTwoViewHolder = null;            TypeThereViewHolder typeThereViewHolder = null;            int Type=getItemViewType(position);            if(convertView==null){                if(Type==TypeOne){                    convertView=getLayoutInflater().inflate(R.layout.inflate_type_one,parent,false);                    typeOneViewHolder=new TypeOneViewHolder();                    typeOneViewHolder.txt_inflat_type_one= (TextView) convertView.findViewById(R.id.txt_inflat_type_one);                    convertView.setTag(typeOneViewHolder);                }else if(Type==TypeTwo){                    convertView=getLayoutInflater().inflate(R.layout.inflate_type_two,parent,false);                    typeTwoViewHolder=new TypeTwoViewHolder();                    typeTwoViewHolder.txt_inflat_type_two= (TextView) convertView.findViewById(R.id.txt_inflat_type_two);                    typeTwoViewHolder.img_inflat_type_two= (ImageView) convertView.findViewById(R.id.img_inflat_type_two);                    convertView.setTag(typeTwoViewHolder);                }else if(Type==TypeThere){                    convertView=getLayoutInflater().inflate(R.layout.inflate_type_there,parent,false);                    typeThereViewHolder=new TypeThereViewHolder();                    typeThereViewHolder.txt_inflat_type_there_1= (TextView) convertView.findViewById(R.id.txt_inflat_type_there_1);                    typeThereViewHolder.txt_inflat_type_there_2= (TextView) convertView.findViewById(R.id.txt_inflat_type_there_2);                    convertView.setTag(typeThereViewHolder);                }            }else {                if(Type==TypeOne){                    typeOneViewHolder= (TypeOneViewHolder) convertView.getTag();                }else if(Type==TypeTwo){                    typeTwoViewHolder= (TypeTwoViewHolder) convertView.getTag();                }else if(Type==TypeThere){                    typeThereViewHolder= (TypeThereViewHolder) convertView.getTag();                }            }            //设置数据            if(Type==TypeOne){                typeOneViewHolder.txt_inflat_type_one.setText("第一种布局"+position);            }else if(Type==TypeTwo){                typeTwoViewHolder.txt_inflat_type_two.setText("第二种布局"+position);                typeTwoViewHolder.img_inflat_type_two.setImageResource(R.mipmap.ic_launcher);            }else if(Type==TypeThere){                typeThereViewHolder.txt_inflat_type_there_1.setText("第三种布局"+position+"左");                typeThereViewHolder.txt_inflat_type_there_2.setText("第三种布局"+position+"右");            }            return convertView;        }        private class TypeOneViewHolder{            private TextView txt_inflat_type_one;        }        private class TypeTwoViewHolder{            private TextView txt_inflat_type_two;            private ImageView img_inflat_type_two;        }        private class TypeThereViewHolder{            private TextView txt_inflat_type_there_1;            private TextView txt_inflat_type_there_2;        }    }}

大家有什么android开发问题可以一起交流(QQ:965244491 附微信二维码交流

2 0
原创粉丝点击