我们已经知道了TableLayout是如何时候了,那么现在我们要开始讲解GridLayout是如何使用的。
为什么还需要GridLayout,我感觉我已经可以用TableLayout做出所有表格了︿( ̄︶ ̄)︿
但是有时候,我们需要将几个单元格跨行或者跨列合并起来的时候,TableLayout就办不到了。
不是啊,TableLayout有合并单元格的属性呀,layout_span = "" 不就可以合并单元格了。
恩,的确,TableLayout可以合并单元格,但是只是能够将单元格跨列合并,无法将单元格跨行合并。
为什么不允许TableLayout跨行合并呢 - -,还需要加一个GridLayout来补充,真是太麻烦了,又需要多记一个控件的使用。
这是因为,TableLayout的特点是行是行,这就表示,每行的内容跟同表格内的其他行是不相关的,也就是没有联系的。那么跨行合并就违背了行与行之间不相关的原则。那为什么列却可以合并呢,因为列都是属于一个行的,每个列的元素在行之内都是相关的(比如说列的宽度都是由行内的控件决定的),所以就能够进行跨列合并。
<pre name="code" class="html"> <GridLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:rowCount="2" android:columnCount="3"> <TextView android:layout_height="30dp" android:layout_gravity="center" android:gravity="center" android:text="啦啦" android:background="@android:color/holo_blue_bright"/> <TextView android:layout_height="30dp" android:layout_gravity="center" android:gravity="center" android:text="吼吼" android:background="@android:color/holo_red_light"/> <!--对其于单元格的右边--> <TextView android:layout_height="30dp" android:layout_gravity="right" android:gravity="center" android:text="哈哈" android:background="@android:color/holo_green_light"/> <TextView android:layout_height="30dp" android:layout_gravity="center" android:gravity="center" android:text="哈哈" android:background="@android:color/holo_purple"/> </GridLayout>效果:
然而我们对每个控件使用了layout_gravitiy="center"方法,可是啦啦与吼吼还是一起靠在左边,并没有居中显示,这说明View的宽高就是单元格的宽高,。造成gravity无效,表示并不是我们想象的平均分配屏幕的空间。而是跟TableLayout同样的的方式。根据当前行中View的height的最大值,来确定行的高度。根据当前列中View的width的最大值,来确定列的宽度。但是又有些不一样,我们看到"哈哈"跑到最右边去了,额,这小子真不合群。但这说明了layout_gravity="right"是生效的,这就表示该单元格的宽度并不是当前View的宽度。那么GridLayout 的单元格是按什么形式分配的呢。
1、根据当前行中View的最大高度确定行的最大高度
2、最后一列之前的宽度由当前列中View的width的最大值,来确定列的宽度。但是最后一列的宽度是根据当前所剩宽度的剩余空间来确定宽度的。就想在最后列加上了layout_weight="1"。
当表格建成的时候(必须在表格宽高已经确定好的情况下),GridLayout也具有,将VIew添加的到表格中任意位置的能力。并且还能安排占几行几列。
android:layout_column="" :表示该View处于第几列
android:layout_row="":表示该View处于第几行
android:layout_columnSpan="":表示该View占据几列
android::layout_rowSpan="":表示该View占据几行
GridLayout自身也没有设定divider的方法,所以设置边框和分割线的方法跟之前讲到的TableLayout制作分割线的方法一样。
步骤一:创建界面布局,制作头部分割线的边框
<!--activity_main--> <RelativeLayout 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" tools:context="com.newbiechen.usegridlayout.MainActivity"> <!--设置表格的数量,row=每天按照12节课计算+星期的头部=13,col=日期+星期=8--> <GridLayout android:id="@+id/main_gridlayout" android:layout_width="match_parent" android:layout_height="wrap_content" android:rowCount="13" android:columnCount="8"> </GridLayout> </RelativeLayout>边框:
<!--grid_frame--> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <solid android:color="@android:color/white"/> <stroke android:color="@android:color/holo_blue_light" android:width="1dp"/> </shape>
public class MainActivity extends AppCompatActivity { //第一步:创建头部的文字 private static final String [] GRID_TITLE = {"9月","星期一","星期二", "星期三","星期四","星期五","星期六","星期日"}; private static final int COURSE_NUM = 12; private GridLayout mGridLayout; private int mGridMinWidth; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mGridLayout = (GridLayout) findViewById(R.id.main_gridlayout); //初始化表格的最小宽度 mGridMinWidth = getScreenWidth()/15; //设置课程的标题 setUpCourseScheduleTitle(); //设置课程的数量,12节课 setUpCourseScheduleNum(); } private void setUpCourseScheduleTitle(){ for(int i = 0; i< GRID_TITLE.length; ++i){ String title = GRID_TITLE[i]; //创建 GridLayout.LayoutParams params = new GridLayout.LayoutParams(); params.setGravity(Gravity.CENTER); //表示设置月份的列 if (i == 0){ params.width = mGridMinWidth; } else { params.width = mGridMinWidth * 2; } //个人设置为30dp params.height = (int) getResources().getDimension(R.dimen.course_schedule_height); //创建添加到表格的View TextView tvTitle = new TextView(this); tvTitle.setText(title); tvTitle.setGravity(Gravity.CENTER); tvTitle.setTextColor(getResources().getColor(android.R.color.holo_blue_bright)); tvTitle.setBackground(getResources().getDrawable(R.drawable.grid_frame)); mGridLayout.addView(tvTitle,params); } } private void setUpCourseScheduleNum(){ //原理:利用代码确定View的位置 for(int i=1; i<=COURSE_NUM; ++i){ //首先GridLayout行列,是从0开始计算的,所以我们第一个num应该在1,0的位置 GridLayout.LayoutParams params = new GridLayout.LayoutParams(); //设置所在列的宽度和高度 params.width = mGridMinWidth; params.height = (int) getResources().getDimension(R.dimen.course_schedule_height); //设置View在表格的什么位置。Spec用来设置View在表格的位置,View占几个单元格,且View在单元格的状态(是否占满单元格的行,或者占满单元格的列) params.rowSpec = GridLayout.spec(i);//行的位置。 params.columnSpec = GridLayout.spec(0);//列的位置。 //创建添加到表格的View TextView tvTitle = new TextView(this); tvTitle.setText(i+""); tvTitle.setGravity(Gravity.CENTER); tvTitle.setTextColor(getResources().getColor(android.R.color.holo_blue_bright)); tvTitle.setBackground(getResources().getDrawable(R.drawable.grid_frame)); mGridLayout.addView(tvTitle,params); } } //第二步:获取屏幕大小,然后设置表格的宽度 private int getScreenWidth(){ DisplayMetrics metrics = getResources().getDisplayMetrics(); return metrics.widthPixels; } }
仿照setUpCourseScheduleNum()的示例,来添加课程。。。就不演示了
(注意的问题:View宽高要与之前设置的一样)
④、使用过程中遇到的问题
1、当View设定的位置超出GridLayout设定的行或者列的时候,就会报错
//这是超出行数了,超出列数也会报同样的错误
java.lang.IllegalArgumentException: row indices (start + span) mustn't exceed the row count.
2、如何设置GridLayout的边框和分割线
GridLayout自身也没有设定divider的方法,所以设置边框和分割线的方法跟TableLayout一样。
我们复习一下
(1) 使用layer-list制作分割线
(2) 使用View制作分割线
(3) 使用9.png制作分割线
3、对比TableLayout,GridLayout的缺点和优点
优点:1、能够横向、和纵向的合并单元格,TableLayout只能够纵向合并单元格
2、能够指定View该方法在那个格子里面,TableLayout却不能
3、GridLayout可以设置是横向添加View还是纵向添加View。TableLayout只能横向添加
缺点:1、没有TableLayout 的行是行、列是列的点。