前言:GridView顾名思义就是网格布局,它可以使用网格的形式将文本内容展示出来。前两篇文章基本上把RecyclerView和ListView的使用简单讲解过了。其实这三种列表布局方式本身的差别没有说特别大,当然RecyclerView作为三者中较新的一个,无论是UI上还是功能的拓展上自然更为优秀,但是三者其实本质上也是优点越明显,缺点也越明显。所以,没有绝对的说非要使用RecyclerView或者说ListView或者GridView,对于UI部分的设计,我个人是比较喜欢遵守适合的才是最好的这一原则,扬长避短,取长补短。
本文目的:通过简单的例子来展示GridView的常规用法。
本文Demo下载地址:https://github.com/ShaoWangYun/SlideViewDemo
最终效果图:
一、布局文件
1.activity_grid_view.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:padding="15dp" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".gridview.GridViewActivity"> <GridView android:id="@+id/grid_view" android:numColumns="2" android:layout_width="match_parent" android:layout_height="match_parent"> </GridView> </RelativeLayout>2.grid_item.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:padding="15dp" android:layout_width="match_parent" android:layout_height="match_parent"> <ImageView android:id="@+id/image" android:src="@mipmap/ic_launcher_round" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <TextView android:id="@+id/text_grid" android:layout_centerVertical="true" android:layout_toRightOf="@+id/image" android:layout_marginLeft="20dp" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </RelativeLayout>二、数据实体类
public class GridDataBean { private String Index; public String getIndex () { return Index; } public void setIndex (String index) { Index = index; } public GridDataBean (String index) { Index = index; } public GridDataBean () { } @Override public String toString () { return "RecyclerDataBean{" + "Index='" + Index + '\'' + '}'; } }三、适配器
public class GridAdapter extends BaseAdapter { private Context context = null; private List<GridDataBean> list = new ArrayList<>(); public GridAdapter (Context context, List<GridDataBean> list) { this.context = context; this.list = list; } @Override public int getCount () { return list.size(); } @Override public GridDataBean getItem (int position) { return list.get(position); } @Override public long getItemId (int position) { return position; } @Override public View getView (int position, View convertView, ViewGroup parent) { ViewHolder mHolder; if (convertView == null) { mHolder = new ViewHolder(); LayoutInflater inflater = LayoutInflater.from(context); convertView = inflater.inflate(R.layout.grid_item, null, true); mHolder.Index = (TextView) convertView.findViewById(R.id.text_grid); convertView.setTag(mHolder); } else { mHolder = (ViewHolder) convertView.getTag(); } String index = list.get(position).getIndex(); mHolder.Index.setText(index); return convertView; } //自定义的ViewHolder,持有每个Item的的所有界面元素 public class ViewHolder { private TextView Index; } }四、主界面
public class GridViewActivity extends AppCompatActivity { private GridView grid_view; private GridAdapter gridAdapter; private List<GridDataBean> gridDataBeans = new ArrayList<>(); @Override protected void onCreate (Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_grid_view); initView(); } private void initView () { grid_view = findViewById(R.id.grid_view); makeData(); refreshListView(); } //循环生成一组假数据,作为RecyclerView的子项数据源,后续将会对recyclerDataBeans中的这20条数据进行操作 private void makeData () { for (int i = 0; i < 20; i++) { GridDataBean gridDataBean = new GridDataBean(); gridDataBean.setIndex(String.valueOf(i)); gridDataBeans.add(gridDataBean); } } private void refreshListView () { gridAdapter = new GridAdapter(GridViewActivity.this, gridDataBeans); grid_view.setAdapter(gridAdapter); grid_view.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick (AdapterView<?> parent, View view, int position, long id) { Utils.showLog("单击事件", "click!!!"); Utils.showToast(GridViewActivity.this, "您点击了的子项的序号为:" + gridAdapter.getItem(position).getIndex(), 0); } }); grid_view.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() { @Override public boolean onItemLongClick (AdapterView<?> parent, View view, final int position, long id) { Utils.showLog("长按事件", "click!!!"); AlertDialog.Builder builder = new AlertDialog.Builder(GridViewActivity.this); builder.setTitle("警告"); builder.setCancelable(false); builder.setMessage("你想要删除序号为 " + gridAdapter.getItem(position).getIndex() + " 的数据么?"); builder.setPositiveButton("确定", new DialogInterface.OnClickListener() { @Override public void onClick (DialogInterface dialog, int which) { try { //获取position(便于局部刷新recyclerview) int deleteposition = getPositionFromList(gridAdapter.getItem(position).getIndex()); //刷新UI gridDataBeans.remove(deleteposition); refreshListView(); gridAdapter.notifyDataSetChanged(); //提示用户 Utils.showToast(GridViewActivity.this, "删除成功", 1); } catch (Exception e) { e.printStackTrace(); Utils.showToast(GridViewActivity.this, "删除失败", 1); } dialog.dismiss(); } }); builder.setNegativeButton("取消", new DialogInterface.OnClickListener() { @Override public void onClick (DialogInterface dialog, int which) { dialog.dismiss(); } }); builder.create().show(); return true; } }); } //根据studentID获取该条数据在list中的下标,便于对recyclerview进行局部刷新 private int getPositionFromList (String index) { List<GridDataBean> list = gridDataBeans; for (int i = 0; i < list.size(); i++) { if (list.get(i).getIndex().equals(index)) { return i; } } return -1; } }五、写在最后
至此,三个最常用的列表布局的简单用法就介绍完了,实际开发中对三种View的使用也远远比讲解的要复杂的多,也会有很多的技巧,包括适配器的设计、数据的填充、刷新等等,还会配合其他的比如说下拉刷新、上拉刷新等完成分页显示或者其他更为复杂的视图。如果有机会的话,我也会进一步的整理一些常用的技巧,还是使用最简单明了的方式分享给大家,敬请期待。
最后,欢迎大家在评论区留言。
