我们已经知道了TableLayout是如何时候了,那么现在我们要开始讲解GridLayout是如何使用的。
为什么还需要GridLayout,我感觉我已经可以用TableLayout做出所有表格了︿( ̄︶ ̄)︿
但是有时候,我们需要将几个单元格跨行或者跨列合并起来的时候,TableLayout就办不到了。
不是啊,TableLayout有合并单元格的属性呀,layout_span = "" 不就可以合并单元格了。
恩,的确,TableLayout可以合并单元格,但是只是能够将单元格跨列合并,无法将单元格跨行合并。
为什么不允许TableLayout跨行合并呢 - -,还需要加一个GridLayout来补充,真是太麻烦了,又需要多记一个控件的使用。
这是因为,TableLayout的特点是行是行,这就表示,每行的内容跟同表格内的其他行是不相关的,也就是没有联系的。那么跨行合并就违背了行与行之间不相关的原则。那为什么列却可以合并呢,因为列都是属于一个行的,每个列的元素在行之内都是相关的(比如说列的宽度都是由行内的控件决定的),所以就能够进行跨列合并。
效果:
然而我们对每个控件使用了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制作分割线的方法一样。
步骤一:创建界面布局,制作头部分割线的边框
边框:
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 的行是行、列是列的点。