浅谈ListView、RecycleView、GridView的使用方法步骤和效果区别.TXT

来源:互联网 发布:淘宝买东西寄到国外 编辑:程序博客网 时间:2024/05/16 07:07
一、ListView的使用说明:1、LIstView与滚动视图(ScrollView)类似,可以将多个组件加入到ListView之中以达到组件的滚动显示效果,可以通过divider设置分割线颜色和高度 布局文件中:android:dividerHeight="20dp"        android:paddingTop="10dp"(设置listview和顶部的距离)        ListView组件本身也有对应的ListView类支持,可以通过操作ListView类以完成对此组组件的操作,        ListView类的继承结构如下所示:        java.lang.Object            ? android.view.View                 ? android.view.ViewGroup                    ? android.widget.AdapterView<T extends android.widget.Adapter>                          ? android.widget.AbsListView                             ? android.widget.ListView      2、ListView的使用需要3个元素            *ListView控件的支持            *需要Adapter,用于将数据显示到ListView的每一个item布局中            *数据源。多条数据的集合                    ArrayAdapter:                        系统线性布局适配器,只显示一行字,绑定的数据类型,可以是基本数据类型,也可以是自定义的对象类型。                        ArrayAdapter(Context context, int textViewResourceId, List<T> objects)                        context:Context对象,为this;                        textViewResourceId:每一行布局文件的id;                        objects:数据源;                         代码: private void intiArrayList(){                                //数据构建                                str_list=new ArrayList<String>();                                str_list.add("Android");                                str_list.add("IOS");                                str_list.add("WindowsPhone");                                ArrayAdapter adapter=new ArrayAdapter(this,android.R.layout.simple_list_item_1,str_list);                                //将适配器设置给listview                                lv.setAdapter(adapter);                            }                    SimpleAdapter:                        具有良好的扩展性,可以自定义item布局,实现没有逻辑的图文混排的效果                                步骤:a/在acvitity布局文件中定义ListView布局,并给布局添加ID                                      b/在layout文件中新建自定义的布局文件                                      c/构建数据源,新建simpleadapter,给listview设置adapter                                       代码:private void intiSimpleAdapter(){                                            List<HashMap<String,Object>> list=new ArrayList();                                            for (int i = 0; i <names.length ; i++) {                                                HashMap<String,Object> map=new HashMap<>();                                                map.put("name",names[i]);                                                map.put("img",ids[i]);                                                list.add(map);                                            }                                            //上下文对象 数据源 资源文件的id                                            //String[] from                                            //int[]  to                                            String[] from=new String[]{"name","img"};                                            int[] to =new int[]{R.id.name,R.id.iv_img};                                            SimpleAdapter adapter=new SimpleAdapter(this,list,R.layout.activity_item_list,from,to);                                            lv.setAdapter(adapter);                    自定义Adapter:                             可以有自己的逻辑,实现带按钮的item布局                            步骤:a/在acvitity布局文件中定义ListView布局,并给布局添加ID                                  b/在layout文件中新建自定义的布局文件                                  c/构建数据源,新建自定义adapter继承与BaseAdapter(创建有参的构造函数,重写里边的四个方法),给listview设置adapter                                代码:                                    public class MyAdapter extends BaseAdapter {                                            private List<CarCompany> list;//数据源                                            private Context context;//上下文对象                                            private LayoutInflater inflater;//布局加载器                                            //有参的构造函数,为数据源,上下文对象复制,同时实例化布局加载器                                            public MyAdapter(List<CarCompany> list,Context context) {                                                this.list=list;                                                this.context=context;                                                inflater=LayoutInflater.from(context);                                            }                                            //有多少条数据,需要创建多少个item布局                                            @Override                                            public int getCount() {                                                return list.size();                                            }                                            //返回position对应位置的数据                                            @Override                                            public Object getItem(int position) {                                                return list.get(position);                                            }                                            //返回position对应位置item的id                                            @Override                                            public long getItemId(int position) {                                                return position;                                            }                                            /**                                             * 具体定义加载item布局,并将数据显示到item布局上的方法。                                             * @param position                                             * @param convertView                                             * @param parent                                             * @return                                             */                                            @Override                                            public View getView(int position, View convertView, ViewGroup parent) {                                                //加载item布局 将xml布局加载到内存中,形成一个view                                                View view=inflater.inflate(R.layout.activity_item_list,null);                                                //实例化item布局上的控件                                                ImageView iv= (ImageView) view.findViewById(R.id.iv_img);                                                TextView tv= (TextView) view.findViewById(R.id.name);                                                //往控件上显示数据                                                //获取position对应位置的数据                                                CarCompany company= (CarCompany) getItem(position);                                                iv.setImageResource(company.getImg());                                                tv.setText(company.getCompany());                                                return view;                                            }                            在activity中实例化adapter,设置给listview                                private void intiCustomAdapter(){                                    List<CarCompany> list=new ArrayList<CarCompany>();                                    for (int i = 0; i < names.length; i++) {                                        CarCompany company=new CarCompany();                                        company.setImg(ids[i]);                                        company.setCompany(names[i]);                                        list.add(company);                                    }//数据源构建好之后实例化自定义的适配器,将数据源list作为参数传入适配器中,然后将adapter加载到ListView的布局中                                    MyAdapter myadapter=new MyAdapter(list,this);                                    lv.setAdapter(myadapter);                                }ListView的优化:        1、复用convertview,减少item的数量:节省内存,运行更流畅        2、使用ViewHolder类,减少findviewbyid的次数,好处就是运行更流畅        代码:在自定义Adapter从写BaseAdapter的getview()方法时:                public View getView(int position, View convertView, ViewGroup parent) {                                ViewHolder holder=null;                                //加载item布局 将xml布局加载到内存中,形成一个view                                if(convertView==null){ //被复用后的convertview类依然包含tag                                    holder=new ViewHolder();                                    convertView=inflater.inflate(R.layout.activity_phone_list,null);                                    holder.iv= (ImageView) convertView.findViewById(R.id.img_phone);                                    holder.tv_phonename= (TextView) convertView.findViewById(R.id.phone_name);                                    holder.tv_phoneprice= (TextView) convertView.findViewById(R.id.phone_price);                                    holder.tv_phonecounter= (TextView) convertView.findViewById(R.id.phone_counter);                                    convertView.setTag(holder);                                }else {//convertview不为空,不为空则说明convertview包含tag                                   holder= (ViewHolder) convertView.getTag();                                }                        //        View view=inflater.inflate(R.layout.activity_phone_list,null);                                //实例化item布局上的控件                        //          ImageView iv= (ImageView) view.findViewById(R.id.img_phone);                        //          TextView tv_phonename= (TextView) view.findViewById(R.id.phone_name);                        //          TextView tv_phoneprice= (TextView) view.findViewById(R.id.phone_price);                        //          TextView tv_phonecounter= (TextView) view.findViewById(R.id.phone_counter);                                //往控件上显示数据                                //获取position对应位置的数据                                PhoneEntity phonety= (PhoneEntity) getItem(position);                                holder.iv.setImageResource(phonety.getImg());                                holder.tv_phonename.setText(phonety.getName());                                holder.tv_phoneprice.setText(phonety.getPrice());                                holder.tv_phonecounter.setText(phonety.getCountNum());                                return convertView;                            }                            class ViewHolder{                            //ViewHolder内部类:相当于一个View视图的缓存容量池,里边记录了自定义adapter布局中所有控件的属性,不用每次重新加载自定义布局                                public ImageView iv;                                public  TextView tv_phonename;                                public  TextView tv_phoneprice;                                public TextView tv_phonecounter;                            }******************************************************************************************************************************************************************************                              二、GridView的使用(展示相同图片大小的网格布局):说明:1、GridView组件是以网格的形式显示所有的组件(大小相同),        例如:在制作相册的时候,所有的图片都会以相同大小显示在不同的格子之中,就可以依靠此组件完成,        让图文混排组件整体居中的方法就是在整个自定义item布局中设置          android:gravity="center"        此组件的继承结构如下所示:                        java.lang.Object                               ? android.view.View                                   ? android.view.ViewGroup                                       ? android.widget.AdapterView<T extends android.widget.Adapter>                                           ? android.widget.AbsListView                                               ? android.widget.GridView     2、GridView常用方法说明:            public GridView(Context context)                                创建GridView对象            public void setStretchMode(int stretchMode)                     android:stretchMode 缩放模式            public void setVerticalSpacing(int verticalSpacing)             android:verticalSpacing 设置垂直间距            public void setHorizontalSpacing(int horizontalSpacing)         android:horizontalSpacing   设置水平间距            public void setNumColumns(int numColumns)                       android:numColumns  设置每列显示的数据量,如果设置为auto_fit则表示自动设置            public void setSelection(int position)                          设置默认选中项            public void setGravity(int gravity)                             android:gravity 设置对齐模式,由Gravity类指定            public void setAdapter(ListAdapter adapter)                     设置显示图片集     3、代码:            a/自定义布局样式layout:item_gridview.xml,给样例中每个控件添加id                          <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"                android:orientation="vertical" android:layout_width="match_parent"                android:layout_height="match_parent">                <ImageView                    android:id="@+id/iv_img"                    android:src="@drawable/benz"                    android:layout_width="60dp"                    android:layout_height="60dp"                    android:layout_margin="10dp"/>                <TextView                    android:id="@+id/tv_name"                    android:layout_width="wrap_content"                    android:layout_height="wrap_content"                    android:text="奔驰"                    android:textSize="30sp"                    android:layout_marginLeft="10dp"/>            b/acvitity_gridview.xml设置GridView属性,给布局文件添加id                  <!--显示3列(auto_fit自己适应屏幕),垂直距离为30dp-->                  <GridView                    android:id="@+id/gv"                    android:numColumns="3"                    android:verticalSpacing="30dp"                    android:layout_width="match_parent"                    android:layout_height="wrap_content"/>            c/在Acvitity的Java代码中实例化GridView布局,并给布局构建数据源                public class GridBarActivity extends AppCompatActivity {                    private GridView gv;                    private String[] names = new String[]{"长安", "沃尔沃", "大众", "宾利", "奔驰"};                    private int[] ids = new int[]{R.drawable.changan, R.drawable.vol, R.drawable.das, R.drawable.bl, R.drawable.benz};                    @Override                    protected void onCreate(Bundle savedInstanceState) {                        super.onCreate(savedInstanceState);                        setContentView(R.layout.activity_grid_bar);                        gv= (GridView) findViewById(R.id.gv);                        //adapter SimpleAdapter 自定义也可                        intiGrid();                    }                    private void intiGrid(){                        //构建数据源                        final List<Map<String,Object>> list =new ArrayList<>();                        for (int i = 0; i <names.length ; i++) {                            Map<String,Object> map=new HashMap<>();                            map.put("name",names[i]);                            map.put("img",ids[i]);                            list.add(map);                        }                        String[] from=new String[]{"name","img"};                        int[] to=new int[]{R.id.tv_name, R.id.iv_img};                        SimpleAdapter adapter=new SimpleAdapter(this,list,R.layout.item_gridview,from,to);                        gv.setAdapter(adapter);                        //添加点击事件                        gv.setOnItemClickListener(new AdapterView.OnItemClickListener() {                            @Override                            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {                                Toast.makeText(GridBarActivity.this,"点击"+list.get(position).get("name").toString(),Toast.LENGTH_SHORT).show();                            }                        });                        gv.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {                            @Override                            public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {                                Toast.makeText(GridBarActivity.this,"长按"+list.get(position).get("name").toString(),Toast.LENGTH_SHORT).show();                                return true;//不再返回上一次监听                            }                        }); **重点内容**GridView中每个item的点击事件(将点击的item的属性设置在另一个控件上显示):(点击事件要在GridView的adapter加载后设置才会有效果,并且监听事件的返回值要设置成void,不能return view)     gv_pig.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {                @Override                public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {                    iv_move.setImageResource(ids[position]);                    tv_move.setText(kind[position]);                    return true;                }            });******************************************************************************************************************************************************************************      三、RecycleView的使用:    说明: 1、RecyclerView:5.0之后的控件,扩展优化,吸收了ViewHolder,我们操作Recyvlerview的adapter的时候我们只操作ViewHolder             以前listview:使用viewholder减少实例化的次数,本质上是一种实例化的方式。我们就负责创建holder.负责给holder上的控件设置数据。            2、ViewHolder./RecyclerView的adapter与BaseAdapter不同            3、RecyclerView的adapter:只负责创建holder,给holder设置展示的数据            4、通过设置LayoutManager可设置展示方式                     rv.setLayoutManager(new StaggeredGridLayoutManager(3, StaggeredGridLayoutManager.VERTICAL));//瀑布流                   rv.setLayoutManager(new LinearLayoutManager(this));//像ListView一样展示                   rv.setLayoutManager(new GridLayoutManager(this, 3));//gridview    步骤: 1、添加兼容包,依赖包 File-->project stru-->选中module,Dependes--->加号-->选择recyvlerview的包,添加。                        2、自定义item布局            3、创建实体类            4、搭建数据集:List<实体类>            5、Adapter:ViewHolder:实例化控件                自定义Adapter步骤:                 a、先创建一个ViewHolder的内部类MyHolder继承于ViewHolder,在内部类中实例化控件属性                 b、让主类RecyclePhoneAdapter继承于RecycleView下的adapter并且给Adapter加上内部类的泛型                    主要为了重写3个方法时候不用再强转返回值类型(不设置泛型返回值为父类)                 c、新建自定义adapter完成后要在对应主Java代码中( RecyclePhoneAdapter adapter=new RecyclePhoneAdapter(this,list);)使用                        并且设置展示样式( //设置布局管理器                    rv_phone.setLayoutManager(new LinearLayoutManager(this));//像ListView一样展示                    rv_phone.setAdapter(adapter);)                    ps; //使用系统自带默认分割线                    rv_phone.addItemDecoration(new DividerItemDecoration(this,LinearLayoutManager.VERTICAL));     自定义Adapter代码样例:            /**自定义adapter的作用,创建ViewHolder,给holder设置数据展示             * 继承RecycleView.Adapter<当前类的泛型.MyHolder>,重写里边三个方法             * Created by Administrator on 2017/2/20.             * 步骤:1、先创建一个ViewHolder的内部类MyHolder继承于ViewHolder,在内部类中实例化控件属性             *      2、让主类RecyclePhoneAdapter继承于RecycleView下的adapter并且给Adapter加上内部类的泛型             *          主要为了重写3个方法时候不用再强转返回值类型(不设置泛型返回值为父类)             *       3、新建自定义adapter完成后要在对应主Java代码中( RecyclePhoneAdapter adapter=new RecyclePhoneAdapter(this,list);)使用             *          并且设置展示样式( //设置布局管理器                            rv_phone.setLayoutManager(new LinearLayoutManager(this));//像ListView一样展示                            rv_phone.setAdapter(adapter);)                            ps; //使用系统自带默认分割线                            rv_phone.addItemDecoration(new DividerItemDecoration(this,LinearLayoutManager.VERTICAL));             */            public class RecyclePhoneAdapter extends RecyclerView.Adapter<RecyclePhoneAdapter.MyHolder> implements View.OnClickListener{                private Context pContext;                private List<PhoneEntity> list;                private LayoutInflater inflater;                private OnItemClick ItemClickListener=null;                //给自定义接口一个实例,并提供下边set方法                public void setItemClickListener(OnItemClick itemClickListener) {                    ItemClickListener = itemClickListener;                }                //有参的构造函数,并实例化布局加载器                public RecyclePhoneAdapter(Context pContext, List<PhoneEntity> list) {                    this.pContext = pContext;                    this.list = list;                    inflater=LayoutInflater.from(pContext);                }                @Override                public MyHolder onCreateViewHolder(ViewGroup parent, int viewType) {                    //第二个参数是容器 第三个参数:true使用父布局的布局参数,false使用自己的布局参数                    View view=inflater.inflate(R.layout.activity_phone_list,parent,false);//使用自定义布局格式                    MyHolder holder=new MyHolder(view);//将自定义的布局传给MyHolder内置处理                    holder.itemView.setOnClickListener(this);//为当前item设置点击事件                    return new MyHolder(view);                }                @Override                public void onBindViewHolder(MyHolder holder, int position) {                    //获取对应位置的数据, 不能再此重新实例化                    PhoneEntity phone=list.get(position);                    holder.phone_name.setText(phone.getName());                    holder.img_phone.setImageResource(phone.getImg());                    holder.phone_price.setText(phone.getPrice());                    holder.phone_counter.setText(phone.getCountNum());                    holder.itemView.setTag(position);//将item位置设置成标签,                }                @Override                public int getItemCount() {                    return list.size();                }                //继承自定义接口,重写自定义接口中的方法,给item添加点击事件                @Override                public void onClick(View v) {                    //调用自定义接口中的方法,给当前item添加点击事件                    if(ItemClickListener!=null){                        ItemClickListener.onitemclick(Integer.parseInt(v.getTag().toString()));                    }                }                //创建内部类继承于RecycleView.ViewHolder实例化自定义布局中的属性                class MyHolder extends RecyclerView.ViewHolder{                    private ImageView img_phone;                    private TextView phone_name;                    private TextView phone_price;                    private  TextView phone_counter;                    public MyHolder(View itemView) {                        super(itemView);                        img_phone= (ImageView) itemView.findViewById(R.id.img_phone);                        phone_name= (TextView) itemView.findViewById(R.id.phone_name);                        phone_price= (TextView) itemView.findViewById(R.id.phone_price);                        phone_counter= (TextView) itemView.findViewById(R.id.phone_counter);                    }                }             //有方法 我们需要知道点击的是第几个item.            // 自定义接口,同时传入position参数设置item布局点击的是哪一个item                public interface OnItemClick{                    void onitemclick(int position);                }    自定义Adapter中自定义接口的使用步骤:              1.在adapter中新建一个接口,接口在adapter中有一个实例,并且提供set方法              2.在createViewHolder的时候给itemview设置点击事件this(Adapter实现了View.OnClickListener 接口).              3.在onBindViewHolder的时候给itemview设置tag,目的是让itemview带着自己的位置,被复用后会设置新的。              4.重写Adapter的OnClickListener方法。                  if (ItemclickListener != null) {                    ItemclickListener.onitemclick(Integer.parseInt(view.getTag().toString()));                }              5.在Activity中去使用。给adapter.setItemclickListener(匿名内部类的方式)。                                     也可以Activity实现OnItemClick接口,重写onitemclick方法。            代码:                    public class RecyclePhoneAdapter extends RecyclerView.Adapter<RecyclePhoneAdapter.MyHolder> implements View.OnClickListener{                    private Context pContext;                    private List<PhoneEntity> list;                    private LayoutInflater inflater;                    private OnItemClick ItemClickListener=null;                    //给自定义接口一个实例,并提供下边set方法                    public void setItemClickListener(OnItemClick itemClickListener) {                        ItemClickListener = itemClickListener;                    }                    //有参的构造函数,并实例化布局加载器                    public RecyclePhoneAdapter(Context pContext, List<PhoneEntity> list) {                        this.pContext = pContext;                        this.list = list;                        inflater=LayoutInflater.from(pContext);                    }                    @Override                    public MyHolder onCreateViewHolder(ViewGroup parent, int viewType) {                        //第二个参数是容器 第三个参数:true使用父布局的布局参数,false使用自己的布局参数                        View view=inflater.inflate(R.layout.activity_phone_list,parent,false);//使用自定义布局格式                        MyHolder holder=new MyHolder(view);//将自定义的布局传给MyHolder内置处理                        holder.itemView.setOnClickListener(this);//为当前item设置点击事件                        return new MyHolder(view);                    }                    @Override                    public void onBindViewHolder(MyHolder holder, int position) {                        //获取对应位置的数据, 不能再此重新实例化                        PhoneEntity phone=list.get(position);                        holder.phone_name.setText(phone.getName());                        holder.img_phone.setImageResource(phone.getImg());                        holder.phone_price.setText(phone.getPrice());                        holder.phone_counter.setText(phone.getCountNum());                        holder.itemView.setTag(position);//将item位置设置成标签,                    }                    @Override                    public int getItemCount() {                        return list.size();                    }                    //继承自定义接口,重写自定义接口中的方法,给item添加点击事件                    @Override                    public void onClick(View v) {                        //调用自定义接口中的方法,给当前item添加点击事件                        if(ItemClickListener!=null){                            ItemClickListener.onitemclick(Integer.parseInt(v.getTag().toString()));                        }                    }                    //创建内部类继承于RecycleView.ViewHolder实例化自定义布局中的属性                    class MyHolder extends RecyclerView.ViewHolder{                        private ImageView img_phone;                        private TextView phone_name;                        private TextView phone_price;                        private  TextView phone_counter;                        public MyHolder(View itemView) {                            super(itemView);                            img_phone= (ImageView) itemView.findViewById(R.id.img_phone);                            phone_name= (TextView) itemView.findViewById(R.id.phone_name);                            phone_price= (TextView) itemView.findViewById(R.id.phone_price);                            phone_counter= (TextView) itemView.findViewById(R.id.phone_counter);                        }                    }                //    自定义接口,通过触发不同位置item的方式,调用接口中的方法,实现点击事件的监听效果                    public interface OnItemClick{                        void onitemclick(int position);                    }
0 0