浅谈ListView、RecycleView、GridView的使用方法步骤和效果区别.TXT
2017-02-25 11:40
423 查看
一、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 13d15 //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); }
相关文章推荐
- 使用RecyclerView实现ListView,GridView效果
- RecycleView替代ListView的使用方法
- 使用RecyclerView实现ListView,GridView的效果(上下,左右滑动),拖拽与滑动删除
- Android5.x:RecycleView(一):实现ListView + GridView + StaggeredGridLayou效果
- 使用RecyclerView实现GridView和ListView混排的效果
- android开发之&使用ViewPager加gridView实现菜单按钮分页滑动(类似QQ表情选择翻页效果)
- ListView和GridView,ViewPager滑动到顶部和底部时出现的阴影消除方法
- ListView集合中设置标记 setTag();方法带一个参数和两个参数的区别,以及设置标记时ViewHolder中的每一个属性控件都需要设置一次,否则在Item中每一个控件的点击事件中取出设置的标
- 踏平RecyclerView使用的各种坑,跟ListView和GridView说拜拜
- android 开发listview,gridview,scroolview之间的嵌套,出现子view显示不完整解决方法
- pushViewController/presentModalViewController/addSubView区别及使用方法
- android TV开发:使用RecycleView实现横向的Listview并响应点击事件
- Swift3 使用系统UIAlertView方法做吐司效果
- pushViewController/presentModalViewController/addSubView区别及使用方法
- [置顶] 当SearchView搜索的listView使用自定义适配器时,自定义setFilterText()方法(模糊查询筛选)
- RecyclerView 和 ListView 性能和效果区别
- Android Widget 小部件(四---完结) 使用ListView、GridView、StackView、ViewFlipper展示Widget
- ListView和BaseAdapter的getViewTypeCount和getItemViewType方法实现Gridview,显示多列
- RecycleView的使用步骤和样例
- 浅谈python socket函数中,send与sendall的区别与使用方法