如何制作表格(二)—— GridLayout

我们已经知道了TableLayout是如何时候了,那么现在我们要开始讲解GridLayout是如何使用的。


一、GridLayout的由来

为什么还需要GridLayout,我感觉我已经可以用TableLayout做出所有表格了︿( ̄︶ ̄)︿

①、单元格的合并

但是有时候,我们需要将几个单元格跨行或者跨列合并起来的时候,TableLayout就办不到了。

如何制作表格(二)—— GridLayout_第1张图片

不是啊,TableLayout有合并单元格的属性呀,layout_span = "" 不就可以合并单元格了。

恩,的确,TableLayout可以合并单元格,但是只是能够将单元格跨列合并,无法将单元格跨行合并。

为什么不允许TableLayout跨行合并呢 - -,还需要加一个GridLayout来补充,真是太麻烦了,又需要多记一个控件的使用。

这是因为,TableLayout的特点是行是行,这就表示,每行的内容跟同表格内的其他行是不相关的,也就是没有联系的。那么跨行合并就违背了行与行之间不相关的原则。那为什么列却可以合并呢,因为列都是属于一个行的,每个列的元素在行之内都是相关的(比如说列的宽度都是由行内的控件决定的),所以就能够进行跨列合并。

②、GridLayout的使用流程

GridLayout就是普通的制作表格的方法,首先我们先要知道这个表格,有多少行,多少列。
android:rowCount="2" : 表示该表格有2行
android:columnCount="3":表示该表格有3列。
然后就可以往GridLayout标签内部添加控件了,
例:添加四个TextView,,并设置一下背景颜色
<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>
 效果:
如何制作表格(二)—— GridLayout_第2张图片首先根据图我们可以得出:
①、GridLayout默认是横向填充的,就是先将一行的单元格塞满,然后在塞满下一行。那么如果我想纵向填充怎么办? 使用android:orientation="vertical",所以GridLayout默认的是android:orientation="horizontal"。
②、没有对具体控件使用layout_width="..."的情况下,默认使用layout_width="wrap_content"。
③、每个单元格的宽高并非平均分配的。一般我们会想到,我们已经设定好了行数和列数,那么是不是每个单元格都会根据GridLayout的宽高,然后将每个单元格平均分配,变成两行三列的格子,就像这样

然而我们对每个控件使用了layout_gravitiy="center"方法,可是啦啦与吼吼还是一起靠在左边,并没有居中显示,这说明View的宽高就是单元格的宽高,。造成gravity无效,表示并不是我们想象的平均分配屏幕的空间。而是跟TableLayout同样的的方式。根据当前行中View的height的最大值,来确定行的高度。根据当前列中View的width的最大值,来确定列的宽度。但是又有些不一样,我们看到"哈哈"跑到最右边去了,额,这小子真不合群。但这说明了layout_gravity="right"是生效的,这就表示该单元格的宽度并不是当前View的宽度。那么GridLayout 的单元格是按什么形式分配的呢。

1、根据当前行中View的最大高度确定行的最大高度

2、最后一列之前的宽度由当前列中View的width的最大值,来确定列的宽度。但是最后一列的宽度是根据当前所剩宽度的剩余空间来确定宽度的。就想在最后列加上了layout_weight="1"。

③、将View添加到表格的任意位置

当表格建成的时候(必须在表格宽高已经确定好的情况下),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>


步骤二:设置GridLayout的头部和课程数列表

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 的行是行、列是列的点。

你可能感兴趣的:(如何制作表格(二)—— GridLayout)