精华内容
下载资源
问答
  • gridlayout
    千次阅读
    2018-12-27 15:27:42

    前言

    前两天突发一个bug,我在ScrollView中嵌套了一个GridView(已经重写了onMeasure方法),GridView的高度是wrap_content,在我更新adapter的时候GridView的高度竟然会时高时低,搞得我一脸懵逼,最终找到原因:

    @Override
        public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2 + expandHeight,
                    MeasureSpec.AT_MOST);
            super.onMeasure(widthMeasureSpec, expandSpec);
        }
    

    不知道是什么历史原因,高度的测量模式竟然被我修改成这个样子,影响了MeasureSpec.AT_MOST模式下的高度测量,并且问题非必现。

    ScrollView嵌套GridView,为了解决手势冲突问题,需要设置GridView高度为wrap_content,我遇到的有两种解决方案:

    1. 重写测量模式,对于这种做法,我一直都不喜欢,而且好像总会出现一些莫名其妙的问题。
    2. 通过LinearLayout模拟GridView,虽然问题得到解决,但是性能上并不是很完美(因为要嵌套LinearLayout实现换行)。

    所有的不满终于在这次爆发,决定实现一个令自己满意的网格布局。

    源码及具体用法,移步github地址,希望大家多多支持

    正文

    基于之前提到的LinearLayout去模拟一个网格布局的实现思路,需要每一行都嵌套一个LinearLayout,通过weight去平分宽度。如果能把这个嵌套的LinearLayout去掉,就是我想要的效果了,于是我想到了GridLayout。

    GridLayout是安卓的五大布局之一,但是用的比较少,最经典的案例就是做计算器的布局:

    计算器布局

    GridLayout最大的优势:可以设置在网格中的位置坐标,占用的格数。例如下面的xml:

    <android.support.v7.widget.GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="300dp"
        android:layout_height="300dp"
        android:background="@color/colorPrimaryDark"
        app:alignmentMode="alignBounds"
        app:columnCount="3"
        app:horizontalSpacing="5dp"
        app:orientation="vertical"
        app:rowCount="3"
        app:verticalSpacing="5dp">
    
        <TextView
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:background="@color/colorAccent"
            app:layout_column="0"
            app:layout_row="0" />
    
        <TextView
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:background="@color/colorAccent"
            app:layout_column="1"
            app:layout_row="1" />
    
    </android.support.v7.widget.GridLayout>
    


    我们简单的复习了一下基本效果,接下来就可以动手实现了。

    首先我们需要一个适配器,建议直接使用BaseAdapter,这样方便替换掉已经使用的GridView,而不用修改适配器的代码。

    /**
         * 设置该控件的适配器
         *
         */
        var adapter: BaseAdapter? = null
            set(adapter) {
                // 解绑之前的adapter的数据监听
                unregisterDataSetObserver()
                field = adapter
                this.count = field!!.count
                this.adapter!!.registerDataSetObserver(dataSetObserver)
                this.fillChildInLayout()
            }
            
    private val dataSetObserver = object : DataSetObserver() {
            override fun onChanged() {
                super.onChanged()
                count = adapter!!.count
                fillChildInLayout()
            }
    
            override fun onInvalidated() {
                super.onInvalidated()
                count = adapter!!.count
                fillChildInLayout()
            }
        }
    

    设置了Adapter后,我们注册一个监听adapter数据的观察者,这样adapter.notifyDataSetChanged可以直接刷新内容的显示。

    fillChildInLayout()是填充内容的方法:

    /**
         * 通过adapter把item填入到GridLayout中
         */
        private fun fillChildInLayout() {
            if (adapter == null || count == 0) {
                clear()
                return
            }
    
            // 判断如果是竖向
            if (orientation == GridLayout.VERTICAL) {
                fillChildInLayoutVertical()
            } else {
                fillChildInLayoutHorizontal()
            }
    
            // 如果当前child的数量比count要大,移除多余Child
            if (childCount > count) {
                removeViews(count, childCount - count)
            }
    
        }
    

    首先判断adapter是否为空或者数量为0,我们只要删除所有的child就可以了。如果数量大于0,根据方向填充child,最后判断目前填充的child的个数和变化后的个数做对比,如果child个数多了,就都删掉。

    每次刷新数据,频繁的移除和填充Child,实在是一种很笨的做法,不如更新已经填充的child,多退少补,优化性能。

    下面以竖直方向的填充方法fillChildInLayoutVertical为例:

    private fun fillChildInLayoutVertical() {
            val columnCount = columnCount
            // 遍历adapter
            for (position in 0 until count) {
                // 得到adapter中的View
                val child = getView(position)
                // 得到布局信息
                val params = generateLayoutParams(child, position)
                // 设置水平方向的间距
                if (position % columnCount == columnCount - 1) {
                    params.rightMargin = 0
                } else {
                    params.rightMargin = horizontalSpace
                }// 中间的child
                // 设置竖直方向的间距,
                if (position > count - 1 - columnCount) {
                    params.bottomMargin = 0
                } else {
                    params.bottomMargin = verticalSpace
                }
                // 设置点击之间
                child.setOnClickListener {
                    onCellClickListener?.onCellClick(position, this.adapter?.getItem(position) as T)
                }
                child.layoutParams = params
                if (child.parent == null) {
                    addView(child)
                }
            }
        }
    

    遍历adapter,得到指定位置的child,刷新child的显示,然后根据child所处的位置,设置右间距和下间距,最后一列不设置右间距,最后一行没有下间距,这样就实现了网格水平和上下的间距。

    接下来看一下getView()方法,在这个方法中实现了之前提到的多退少补的优化策略:

    /**
         * 从cache中得到View,没有则创建
         */
        private fun getView(index: Int): View {
            // 首先遍历已经存在的child,直接更新内容
            // 这样可以节省清空再填充的性能浪费
            var view: View? = null
            if (index < count) {
                view = getChildAt(index)
            }
            // 更新数据显示
            view = this.adapter!!.getView(index, view, this)
            return view
        }
    
    class TestAdapter(private val context: Context, private val list: List<String>) : BaseAdapter() {
    
        override fun getItem(position: Int): String = list[position]
    
        override fun getItemId(position: Int): Long = position.toLong()
    
        override fun getCount(): Int = list.size
    
        override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View {
            var view = convertView
            if(view == null){
                view = LayoutInflater.from(context).inflate(R.layout.item_test, parent, false)
            }
            view!!.findViewById<TextView>(R.id.text).text = list[position]
            return view
        }
    }
    
    

    首先查询是否已经添加了指定位置的child,然后调用adapter.getView(),如果没有找到child,会引入一个新的布局,如果找到了child,直接更新内容,这样已经添加的child直接得到了复用。

    最后就是设置child的位置了:

    /**
         * 生成LayoutParams
         */
        private fun generateLayoutParams(child: View, position: Int): GridLayout.LayoutParams {
            val params: GridLayout.LayoutParams = if (child.layoutParams != null) {
                child.layoutParams as GridLayout.LayoutParams
            } else {
                GridLayout.LayoutParams()
            }
            // 设置宽度
            if (orientation == VERTICAL) {
                // 设置所占的行数
                params.columnSpec = GridLayout.spec(position % columnCount, 1, 1f)
                params.rowSpec = GridLayout.spec(position / columnCount, 1)
            } else {
                // 设置所占的行数
                params.rowSpec = GridLayout.spec(position % rowCount, 1, 1f)
                params.columnSpec = GridLayout.spec(position / rowCount, 1)
            }
            return params
        }
    

    GridLayout.LayoutParams简单的介绍一下:

    columnSpec:child所在的列。
    rowSpec:child所在的行。
    GridLayout.spec(position % rowCount, 1, 1f)
    第一个参数:所在列/行的位置;
    第二个参数:所占用的个数,这里需要注意的是,格数仅仅是占用的数量,而不是宽度比;
    第三个参数:所在的列/行,所占的宽度/高度的比例。

    这就是GridLayoutView的全部实现,非常的简单,最后看一下实际的应用:

    <!-- XML布局 -->
    <com.lzp.grid.GridLayoutView
            android:id="@+id/grid"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@color/colorPrimaryDark"
            app:columnCount="3"
            app:horizontalSpacing="5dp"
            app:orientation="vertical"
            app:verticalSpacing="5dp" />
    
    <!-- Java代码 -->
    GridLayoutView<String> gridView = findViewById(R.id.grid);
    gridView.setOnCellClickListener((index, s) -> Toast.makeText(this, s, Toast.LENGTH_SHORT).show());
    gridView.setAdapter(adapter);
    

    因为要在child的点击事件直接回调Adapter中的数据对象,所以需要指定Item的泛型。

    总结

    这一次的内容相对来说比较简单,但是在思考的过程中发生了很多奇妙蛋疼的事情,最后给大家留下几个问题:

    1. 我继承的是android.support.v7.widget.GridLayout,如果直接使用自带的GridLayout,在android 26以下是不能使用weight的,这个要怎么就解决呢?

    提示:计算宽高比,需要得到自身的宽度,如何解决getWidth/getHeight等于0的问题

    1. 以第一个添加child为例,此时一个child都没有,需要循环addView,已知addView会调用requestLayout(),这种情况下会layout几次,是否会有性能问题呢?

    需要了解View整体的添加和绘制流程,理解android的优化策略。

    3、如果我们需要自定义LayoutParam,如何设置xml中添加的child的LayoutParam是自定义类型呢?

    可以参考一下GridLayout源码

    今天分享就这些了,如果有高手知道问题答案的话,欢迎留言大家共同学习,最后祝大家元旦愉快。

    更多相关内容
  • 网格布局标签是GridLayout。这个布局是android4.0新增的布局。这个布局只有4.0之后的版本才能使用。 不过新增了一些东东 ①跟LinearLayout(线性布局)一样,他可以设置容器中组件的对齐方式 ②容器中的组件可以跨多行...
  • 本文实例讲述了Android开发之计算器GridLayout布局实现方法。分享给大家供大家参考,具体如下: 运行效果: Demo 下载地址:https://github.com/LonglyWolf/Calculator 或者点击此处本站下载。 按钮布局实现: 一个...
  • GridLayout布局 GridLayout 布局的功能非常强大,也是笔者常用的一种布局方式。GridLayout是网格式布局,它把父组件分成一个表格,默认情况下每个子组件占据一个单元格的空间,每个子组件按添加到父组件的顺序排列在...
  • 资源文章介绍地址:https://www.cnblogs.com/lifexy/p/14686618.html 通过GridLayout来做一个简易的网站导航界面,并支持自适应界面.当我们点击其中的某个按钮,就会打开浏览器跳到对应的网站上.
  • GridLayout 的灵感来自 GridBagLayout 管理器。 它同样灵活,但更符合我的口味,而且还需要更少的样板代码。 每个单元格都是一个 uicontainer 并且只能容纳一个孩子。 与 GridBagLayout 不同,通过将单元格容器句柄...
  • 主要介绍了Android中使用GridLayout网格布局来制作简单的计算器App的实例,GridLayout比表格布局TabelLayout更容易用来制作计算器这样的多按钮排列的界面,需要的朋友可以参考下
  • 思路:就是先设置Gridlayout的行列数,然后往里面放置一定数目的自定义日历按钮控件,最后实现日历逻辑就可以了。 步骤: 第一步:自定义日历控件(初步) 第二步:实现自定义单个日期按钮控件 第三步:将第二步得到...
  • AverageGridLayout 适用于Android的简单GridLayout 截屏 使用布局xml < View android : layout_width = " match_parent " android : layout_height = " matc
  • Qt自定义控件GridLayout

    2017-12-13 09:22:22
    自定义布局控件 实现功能 1、控件增(前插、后插)、删 2、设置列数 3、设置滚动条显示与隐藏 有什么更好的建议请留言...
  • android-support-v7-gridlayout.jar
  • 主要介绍了JavaSwing GridLayout 网格布局的实现代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
  • 回收视图使用不同类型的 RecycleView 管理器,如 LinearLayout 和 GridLayout。 使用 LinearLayout 作为垂直滚动的 RecyleView。 使用 LinearLayout 作为水平滚动条的 RecyleView。 RecyleView 与 GridLayout
  • 北京信息职业技术学院 | 范美英 Android网格布局GridLayout的 使用场合及简要介绍 网格布局GridLayout GridLayout布局使用虚细线将布局划分为行列和单元格也支持一个控件在行列上都有交错排列 GridLayout使用的其实...
  • 记录了Android开发的历程,本DEMO是通过GridLayout布局编写了一个精美简易的计算器界面,暂时还没计算的功能,后续会补上
  • Android基础入门教程——2.2.5 GridLayout(网格布局)-附件资源
  • matlab开发-GridLayout

    2019-08-22 18:35:47
    matlab开发-GridLayout。直观灵活的布局管理器
  • GridLayout实例程序

    2015-12-12 02:29:12
    纯手写GridLayout程序,适合初学者学习
  • React-Grid-Layout:网格布局(grid layout)系统,但专为 React 服务
  • 在2.2下使用GridLayout

    2019-04-21 01:34:39
    NULL 博文链接:https://zheyiw.iteye.com/blog/1926973
  • GridLayout

    2009-02-14 13:40:17
    GridLayout 类是一个布局处理器,它以矩形网格形式对容器的组件进行布置。容器被分成大小相等的矩形,一个矩形中放置一个组件。
  • 简单的GridLayout

    2013-11-14 19:52:42
    GridLayout做的例子,超级简单。
  • Android GridLayout

    2021-06-05 12:29:24
    译者注:说实话 我确实没用过GridLayout 好好认识一下吧!android开发者每天都在问自己一个问题:我到底应该用哪个layout然而GridLayout在当前开发中的情况如下:大多数开发者并不知道这个布局一些开发者知道...

    译者注:说实话 我确实没用过GridLayout 好好认识一下吧!

    android开发者每天都在问自己一个问题:我到底应该用哪个layout

    然而GridLayout在当前开发中的情况如下:

    大多数开发者并不知道这个布局

    一些开发者知道GridLayout但是因为某些原因没有使用

    只有少部分开发者花时间了解和积极使用

    这是我为什么要写这篇文章的原因,因为我觉得这个布局被不公平遗忘了

    为什么我们需要Grid Layout

    GridLayout可以让你用一个简单的根view创建一个表格系统布局

    我可以用LinearLayout嵌套来实现

    是可以做到,但是你会有性能问题当布局层次太深

    我可以用RelativeLayout来创建

    也行,但是RelativeLayout有一些限制,例如:

    没法同时控制2个轴线对齐

    当组件需要的空间超出你预期的时候会跑出屏幕或发生重叠因为你不能使用weight等等

    换一句话说就是RelativeLayout不够灵活和响应性不足。

    例子

    让我们实现一个简单的布局包含一个大图片,2个小图标和跟在图标后面的文本

    1*hm-KJs7FJG5qtHglpvWYSQ.png

    Preview

    RelativeLayout

    用RelatieveLayout实现起来非常简单,通过关键属性layout_below,layout_toRightOf和layout_alignTop

    1*orH45OZ2t_qeoEfSHzaZtA.png

    Code

    一眼看上去好像很完美,等你用不同字体size进行布局测试就呵呵了

    问题 1 没法同时控制基于2个轴对齐

    单行文本应该相对于图标垂直居中,不幸的是RelativeLayout没有提供这个可能性

    1*1pxJm-XLyhFHoIzZf65CdQ.png

    Preview

    问题 2 组件重叠

    多行文本会引起重叠,因为text用了layout_alignTop对图标进行对齐

    1*uemGANLvCQv-tdfyadqnqA.png

    Preview

    GridLayout

    如你看到的下面图片一样,GridLayout提供更好的表现结果:

    文本垂直居中于图标

    多行文本不会向下移动组件

    1*Dz8SX4ju0NEW4OL6sHeI5g.png

    Preview

    那么怎么实现这个效果呢?首先定义GridLayout为根布局。然后计算你要多少列并通过android:columnCount属性定义,在我们的例子中我们有2列。

    因为GridLayout里面的views是一个接一个被放置的,所以没必要明确定义row和column

    如果你想撑开view让它占用2行或2列,你可以用layout_columnSpan/layout_rowSpan属性

    还有一件重要的事要记住-如果你想你的view使用所有可用的空间,不要设置width为match_parent,应该设置成0dp同时设置属性layout_gravity="fill"

    1*lSg-UAbQTJkG4pVMM34YaA.png

    Code

    总结

    GridLayout一方面是一个非常强大的工具,它提供了很好的灵活性和性能,另外一方面它需要一些时间来学习了解它如何工作,你通常需要花更多的时间来开发和维护这样的布局。

    展开全文
  • 在android开发中,import android-support-v7-gridlayout.jar,有不同于V4的功能区别
  • Android开发之GridLayout

    2022-03-14 11:12:02
    网格布局类似与前一篇博客讲的表格布局,但是更加灵活。支持表格布局做不到的行合并。 文章目录 基本框架 常见属性 子控件属性 基本框架 <GridLayout xmlns:android=...可以看到网格布局跟表格布局不一样的地方,在不...

    网格布局类似与前一篇博客讲的表格布局,但是更加灵活。支持表格布局做不到的行合并。

    基本框架

    <?xml version="1.0" encoding="utf-8"?>
    <GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_height="match_parent"
        android:layout_width="match_parent">
    
        <Button
            android:text="Button1"
            android:layout_height="wrap_content"
            android:layout_width="wrap_content"/>
        <Button
            android:text="Button1"
            android:layout_height="wrap_content"
            android:layout_width="wrap_content"/>
        <Button
            android:text="Button1"
            android:layout_height="wrap_content"
            android:layout_width="wrap_content"/>
    
    </GridLayout>
    

    在这里插入图片描述
    可以看到网格布局跟表格布局不一样的地方,在不额外设置的时候,所有组件是默认水平线性排列的。

    常见属性

    android:orientation 设置水平显示还是垂直显示
    android:columnCount 设置列的显示个数
    android:rowCount 设置行的显示个数

    在设置了列的显示个数后,超过该个数的组件就会换行。

    <?xml version="1.0" encoding="utf-8"?>
    <GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_height="match_parent"
        android:layout_width="match_parent"
        android:columnCount="3"
        android:orientation="horizontal">
    
        <Button
            android:text="Button1"
            android:layout_height="wrap_content"
            android:layout_width="wrap_content"/>
        <Button
            android:text="Button2"
            android:layout_height="wrap_content"
            android:layout_width="wrap_content"/>
        <Button
            android:text="Button3"
            android:layout_height="wrap_content"
            android:layout_width="wrap_content"/>
        <Button
            android:text="Button4"
            android:layout_height="wrap_content"
            android:layout_width="wrap_content"/>
        <Button
            android:text="Button5"
            android:layout_height="wrap_content"
            android:layout_width="wrap_content"/>
    
    </GridLayout>
    

    在这里插入图片描述
    设置行的个数类似:

    <?xml version="1.0" encoding="utf-8"?>
    <GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_height="match_parent"
        android:layout_width="match_parent"
        android:rowCount="3"
        android:orientation="vertical">
    
        <Button
            android:text="Button1"
            android:layout_height="wrap_content"
            android:layout_width="wrap_content"/>
        <Button
            android:text="Button2"
            android:layout_height="wrap_content"
            android:layout_width="wrap_content"/>
        <Button
            android:text="Button3"
            android:layout_height="wrap_content"
            android:layout_width="wrap_content"/>
        <Button
            android:text="Button4"
            android:layout_height="wrap_content"
            android:layout_width="wrap_content"/>
        <Button
            android:text="Button5"
            android:layout_height="wrap_content"
            android:layout_width="wrap_content"/>
    
    </GridLayout>
    

    在这里插入图片描述

    子控件属性

    android:layout_column 显示在第几列
    android:layout_columnSpan 横跨几列
    android:layout_columnWeight 该行剩余空间按权重分配

    android:layout_column 显示在第几行
    android:layout_columnSpan 纵跨几行
    android:layout_columnWeight 该列剩余空间按权重分配

    android:layout_gravity 在网格中的显示位置

    这些属性就与表格布局十分类似了,比如设置某个组件的行和列:

    <Button
            android:text="Button2"
            android:layout_height="wrap_content"
            android:layout_width="wrap_content"
            android:layout_row="1"
            android:layout_column="0"/>
        <Button
            android:text="Button3"
            android:layout_height="wrap_content"
            android:layout_width="wrap_content"
            android:layout_row="0"
            android:layout_column="1"/>
    

    在这里插入图片描述
    权重分配则与线性布局中的类似,将剩余空间按权重瓜分。

    <Button
            android:text="Button4"
            android:layout_height="wrap_content"
            android:layout_width="wrap_content"
            android:layout_rowWeight="1"/>
    

    在这里插入图片描述
    跨多行/列操作也是跟表格布局类似的,但是注意这里的跨列只是给该组件分配了空间,需要结合android:layout_gravity属性,比如用fill就可以看到组件填满了整个空间:

    <Button
            android:text="Button2"
            android:layout_height="wrap_content"
            android:layout_width="wrap_content"
            android:layout_row="1"
            android:layout_column="0"
            android:layout_columnSpan="3"
            android:layout_gravity="fill"/>
    

    在这里插入图片描述

    展开全文
  • GridLayout 布局的功能非常强大,也是笔者常用的一种布局方式。GridLayout是网格式布局,它把父组件分成一个表格,默认情况下每个子组件占据一个单元格的空间,每个子组件按添加到父组件的顺序排列在表格中。...

    GridLayout 布局的功能非常强大,也是笔者常用的一种布局方式。GridLayout是网格式布局,它把父组件分成一个表格,默认情况下每个子组件占据一个单元格的空间,每个子组件按添加到父组件的顺序排列在表格中。

    GridLayout布局

    GridLayout 布局的功能非常强大,也是笔者常用的一种布局方式。GridLayout是网格式布局,它把父组件分成一个表格,默认情况下每个子组件占据一个单元格的空间,每个子组件按添加到父组件的顺序排列在表格中。GridLayout提供了很多的属性,可以灵活设置网格的信息。另外,GridLayout 布局提供了GridData类,子组件可以设置相应的GridData,例如 “dogPhoto.setLayoutData(gridData)”,GridData可以设置每个组件当做单元格的信息。GridLayout的风格

    GridLayout类提供了GridLayout 布局中划分网格的信息,主要通过以下几个参数进行设置。 NumColumns:通过“gridLayout.numColumns”属性可以设置父组件中分几列显示子组件。

    MakeColumnsEqualWidth:通过“gridLayout. makeColumnsEqualWidth”属性可以设置父组件中子组件是否有相同的列宽,当MakeColumnsEqualWidth为true时表示每列的列宽相等。 MarginLeft:表示当前组件距离父组件左边距的像素点个数。 MarginRight:表示当前组件距离父组件右边距的像素点个数。 MarginTop:表示当前组件距离父组件上边距的像素点个数。 MarginBottom:表示当前组件距离父组件下边距的像素点个数。 HorizontalSpacing:表示子组件的水平间距。VerticalSpacing:表示子组件的垂直间距。GridData的相关属性

    GridLayout布局的灵活之处在于它利用网格布局数据GridData。通过GridData可以设置子组件在网格中的填充方式、大小边距等信息,用户可以通过子组件的setLayoutData方法设置网格布局数据。

    GridData可以控制子组件在网格中的位置大小等相关显示信息。GridData可以设置如下的一些属性。 HorizontalAlignment:表示水平对齐方式。 VerticalAlignment:表示子组件的垂直对齐方式,值和水平方式一样。 HorizontalIndent:表示子组件水平偏移多少像素。此属性和“horizontalAlignment = GridData.BEGINNING”属性一起使用。 HorizontalSpan:表示组件水平占据几个网格。GrabExcessHorizontalSpace:表示当父组件大小改变时,子组件是否以水平方向抢占空间。 GrabExcessVerticalSpace:表示当父组件大小改变时,子组件是否以垂直方向抢占空间。 WidthHint:表示子组件的宽度为多少像素(前提是未设置其他相关属性)。 HeightHint:表示子组件的高度为多少像素(前提是未设置其他相关属性)。

    另外,GridData可以通过构造函数指定相应的属性值,有兴趣的读者可以参考GridData类的构造函数。 .

    14.11.1 GridLayout的风格

    GridLayout类提供了GridLayout 布局中划分网格的信息,主要通过以下几个参数进行设置。

    NumColumns:通过“gridLayout.numColumns”属性可以设置父组件中分几列显示子组件,如表14-4所示。

    表14-4  NumColumns效果

    列    数

    显 示 效 果

    numColumns = 1

    c3db3f493d8ebf0848492e1efd3f6375.png

    numColumns = 2

    ecbd448910c3c1a206f1743447a5bc01.png

    numColumns = 3

    3019c5cef8020a68f91d46cb30efd2a0.png

    >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

    GridLayout1.java

    69c5a8ac3fa60e0848d784a6dd461da6.png

    1 importorg.eclipse.swt.SWT;2 importorg.eclipse.swt.layout.GridLayout;3 importorg.eclipse.swt.widgets.Button;4 importorg.eclipse.swt.widgets.Display;5 importorg.eclipse.swt.widgets.Shell;6

    7 public classGridLayout1 {8 public static voidmain(String[] args) {9 final Display display =Display.getDefault();10 final Shell shell = newShell();11 shell.setSize(327, 253);12 //---------创建窗口中的其他界面组件-------------13 //把空间分3列。建立5个按钮,由左向右排,排满3个后换行继续

    14 shell.setLayout(new GridLayout(3, false));15 new Button(shell, SWT.NONE).setText("b1");16 new Button(shell, SWT.NONE).setText("button2");17 new Button(shell, SWT.NONE).setText("b3");18 new Button(shell, SWT.NONE).setText("button4");19 new Button(shell, SWT.NONE).setText("button5");20 //-----------------END------------------------

    21 shell.layout();22 shell.open();23 while (!shell.isDisposed()) {24 if (!display.readAndDispatch())25 display.sleep();26 }27 display.dispose();28 }29 }

    69c5a8ac3fa60e0848d784a6dd461da6.png

    6367b78235ab529cd7a0bc3f13580db8.png

    GridLayout1.java

    69c5a8ac3fa60e0848d784a6dd461da6.png

    1 public classGridData1 {2 public static voidmain(String[] args) {3 final Display display =Display.getDefault();4 final Shell shell = newShell();5 shell.setSize(327, 253);6 //---------创建窗口中的其他界面组件-------------

    7 shell.setLayout(new GridLayout(2, false));8 new Button(shell, SWT.NONE).setText("b1");9 new Button(shell, SWT.NONE).setText("button2");10

    11 //定义一个GridData对象,让b3按钮抢占两列的空间

    12 Button b3 = newButton(shell, SWT.NONE);13 GridData gridData = newGridData();14 //GridData gridData = new GridData(GridData.FILL_HORIZONTAL);

    15 gridData.horizontalSpan = 2;16 b3.setLayoutData(gridData);17 b3.setText("b3");18

    19 new Button(shell, SWT.NONE).setText("button4");20 new Button(shell, SWT.NONE).setText("button5");21

    22 //Button button6 = new Button(shell, SWT.NONE);23 //GridData gridData2 = new GridData(GridData.FILL_HORIZONTAL);24 //button6.setLayoutData(gridData2);25 //button6.setText("button6");26

    27 //-----------------END------------------------

    28 shell.layout();29 shell.open();30 while (!shell.isDisposed()) {31 if (!display.readAndDispatch())32 display.sleep();33 }34 display.dispose();35 }36 }

    69c5a8ac3fa60e0848d784a6dd461da6.png

    8a83698547f204d2d973fdf6d004d0ee.png

    GridData2.java

    69c5a8ac3fa60e0848d784a6dd461da6.png

    1 public classGridData2 {2 public static voidmain(String[] args) {3 final Display display =Display.getDefault();4 final Shell shell = newShell();5 shell.setSize(327, 253);6 //---------创建窗口中的其他界面组件-------------

    7 shell.setLayout(newGridLayout());8 Button b1 = newButton(shell, SWT.NONE);9 GridData gridData = newGridData();10 gridData.horizontalAlignment =GridData.BEGINNING;11 b1.setLayoutData(gridData);12 b1.setText("b1");13 new Button(shell, SWT.NONE).setText("button2");14 //-----------------END------------------------

    15 shell.layout();16 shell.open();17 while (!shell.isDisposed()) {18 if (!display.readAndDispatch())19 display.sleep();20 }21 display.dispose();22 }23 }

    69c5a8ac3fa60e0848d784a6dd461da6.png

    cc59ad2edd83df1b95c526572d1ec57c.png

    GridData3.java

    69c5a8ac3fa60e0848d784a6dd461da6.png

    1 public classGridData3 {2 public static voidmain(String[] args) {3 final Display display =Display.getDefault();4 final Shell shell = newShell();5 shell.setSize(327, 253);6 //---------创建窗口中的其他界面组件-------------

    7 shell.setLayout(newGridLayout());8 Button b1 = newButton(shell, SWT.NONE);9 GridData gridData = newGridData();10 gridData.grabExcessHorizontalSpace = true;11 gridData.horizontalAlignment =GridData.FILL;12 //以上三句和GridData gridData = new GridData(GridData.FILL_HORIZONTAL);等效

    13 b1.setLayoutData(gridData);14 b1.setText("b1");15 new Button(shell, SWT.NONE).setText("button2");16 //-----------------END------------------------

    17 shell.layout();18 shell.open();19 while (!shell.isDisposed()) {20 if (!display.readAndDispatch())21 display.sleep();22 }23 display.dispose();24 }25 }

    69c5a8ac3fa60e0848d784a6dd461da6.png

    2c37dda2a4b0ce03af2f58dcdde1f332.png

    本文转自SummerChill博客园博客,原文链接:http://www.cnblogs.com/DreamDrive/p/4256524.html,如需转载请自行联系原作者

    展开全文
  • [AWT] GridLayout

    热门讨论 2022-03-13 10:30:47
    大家好我是Nick,今天我们一起来学习的是 GridLayout 和 GridBagLayout,这两个管理器虽然长得差不多,但是功能对比简直一个在天一个在地,那么现在跟着Nick一起来探索学习下趴~

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 40,228
精华内容 16,091
关键字:

gridlayout

友情链接: mqtt_fan.zip