Android非常牛叉的表格编辑库SmartTable,让复杂表格变得So Easy

最近项目需求需要制作一个表格展示效果,先看下UI图吧:

image.png

刚开始接收到这个需求的时候,第一反应就是使用 RecyclerView 来进行实现,谁让 RecyclerView 那么牛逼呢?不用纠结 RecyclerView 完完全全可以实现这种效果,无外乎可能就是稍微复杂些

RecyclerView 实现思路:

  • 最外层采用 HorizontalScrollView,保证表格可以左右进行滑动
  • 内层使用 RecyclerView,而使用 RecyclerView 时需要使用到 getItemViewType 这个方法来规定条目的类型(第一行title以及合计可以认为是同一种类型,而“沈阳”那一个稍微大一点的条目可以认为是第二种类型
  • 类型一:这个类型布局就非常简单了,采用 LInearLayout 就可以非常简单的实现
  • 类型二:可以采用水平的 LinearLayout 包裹 TextView 以及 RecyclerView 来进行实现

上面仅仅是介绍了我最开始采用的方案,当然缺点非常多:

  1. 使用上面方案时,需要考虑列的宽度问题,要么宽度直接在布局中写死(每列中文字长度不一样,可能会出现第一行与第二行的列错位情况),要么根据服务器返回的数据动态获取每列中最长字符串所需要占用的宽度进行动态设置
  2. 表格一般都会存在排序功能(当然我这个项目中暂时还未出现),如果出现需要对列进行升序或降序排序,那就呵呵了,自己想办法去吧,想想都痛苦

说了这么多并不是贬低 RecyclerView 的意思,因为 RecyclerView 本身的定义就不是专门用来做这种复杂表格的(有说错的地方,欢迎在评论中留言),你让 RecyclerView 去实现这种效果就有点.......

下面来介绍一下今天的主角:SmartTable —— 好用漂亮的 Android 表格框架

先说一下 SmartTable 都支持的功能吧,具体例子后面再给出:

  1. 快速配置自动生成表格;
  2. 自动计算表格宽高
  3. 表格列标题组合
  4. 表格固定左序列、顶部序列、第一行、列标题、统计行
  5. 自动统计,排序(自定义统计规则)
  6. 表格图文、序列号、列标题格式化
  7. 表格各组成背景、文字、网格、padding 等配置
  8. 表格批注
  9. 表格内容、列标题点击事件
  10. 缩放模式和滚动模式
  11. 注解模式
  12. 内容多行显示
  13. 分页模式
  14. 首尾动态添加数据
  15. 丰富的格式化
  16. 支持二维数组展示(用于类似日程表,电影选票等)
  17. 导入 excel(支持颜色,字体,背景,批注,对齐,图片等基本 Excel 属性)
  18. 表格合并单元(支持注解合并,支持自动合并)
  19. 支持其他刷新框架 SmartRefreshLayout
  20. 可配置表格最小宽度(小于该宽度自动适配)
  21. 支持直接 List 或数组字段转列
  22. 支持 Json 数据直接转换成表格
  23. 支持表格网格指定行列显示

看介绍是不是感觉叼的不要不要的,不过呢,我也是刚使用这个框架,在这里也仅仅是介绍一些开发中常用的,其他的自己去尝试吧

如何使用

  • 引用:添加 JitPack repository 到你的 build 文件
allprojects {
        repositories {
            ...
            maven { url 'https://www.jitpack.io' }
        }
    }
  • 增加依赖
dependencies {
            compile 'com.github.huangyanbin:SmartTable:2.0'
    }

使用方式

SmartTable 的使用方式有两种:

  1. 采用注解的形式
  2. 基本模式,手动配置行与列

一、注解方式

  • 步骤一:在布局文件中使用 SmartTable
<com.bin.david.form.core.SmartTable
        android:id="@+id/table"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
  • 步骤二:定义表格(自定义bean对象)
@SmartTable(name = "销售计划表")
public class UserInfo {
    public UserInfo(String city, int name, int count, int restaurant, int ka, int wholesale, int industry, int other) {
        this.city = city;
        this.name = name;
        this.count = count;
        this.restaurant = restaurant;
        this.ka = ka;
        this.wholesale = wholesale;
        this.industry = industry;
        this.other = other;
    }

    //    name:版块名称,count:目标值,restaurant:餐饮数量,ka:KA数量,wholesale:流通批发数量,industry:工业加工数量,other:其它数量
    @SmartColumn(id = 0, name = "部门/渠道", autoMerge = true)
    private String city;
    @SmartColumn(id = 1, name = "板块")
    private int name;
    @SmartColumn(id = 2, name = "目标值")
    private int count;
    @SmartColumn(id = 3, name = "餐饮")
    private int restaurant;
    @SmartColumn(id = 4, name = "KA")
    private int ka;
    @SmartColumn(id = 5, name = "流通批发")
    private int wholesale;
    @SmartColumn(id = 6, name = "工业加工")
    private int industry;
    @SmartColumn(id = 7, name = "其他")
    private int other;
}
  • 步骤三:绑定数据(完成)
public class MainActivity extends AppCompatActivity {

    private SmartTable table;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        List<UserInfo> list = new ArrayList<>();
        table = findViewById(R.id.table);
        list.add(new UserInfo("沈阳",100, 150, 50, 240, 1100, 450, 23458));
        list.add(new UserInfo("沈阳",100, 150, 50, 240, 1100, 450, 23458));
        list.add(new UserInfo("沈阳",100, 150, 50, 240, 1100, 450, 23458));
        list.add(new UserInfo("沈阳",100, 150, 50, 240, 1100, 450, 23458));
        list.add(new UserInfo("乌鲁木齐",100, 150, 50, 240, 1100, 450, 23458));
        list.add(new UserInfo("乌鲁木齐",100, 150, 50, 240, 1100, 450, 23458));
        list.add(new UserInfo("乌鲁木齐",100, 150, 50, 240, 1100, 450, 23458));
        list.add(new UserInfo("乌鲁木齐",100, 150, 50, 240, 1100, 450, 23458));
        list.add(new UserInfo("沈阳",100, 150, 50, 240, 1100, 450, 23458));
        list.add(new UserInfo("沈阳",100, 150, 50, 240, 1100, 450, 23458));
        list.add(new UserInfo("沈阳",100, 150, 50, 240, 1100, 450, 23458));
        list.add(new UserInfo("沈阳",100, 150, 50, 240, 1100, 450, 23458));

        table.setData(list);
        table.getConfig().setContentStyle(new FontStyle(50, Color.BLUE));
    }
}

是不是分分钟实现,效果图如下:


image.png

二、基本方式,手动创建行与列

  • 步骤一:在布局文件中使用 SmartTable
<com.bin.david.form.core.SmartTable
        android:id="@+id/table"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
  • 步骤二:定义表格(自定义bean对象),与采用注解方式唯一的不同就是不在使用 @SmartColumn 与 @SmartColumn 进行标注
public class User {
    public User(String city, int name, int count, int restaurant, int ka, int wholesale, int industry, int other) {
        this.city = city;
        this.name = name;
        this.count = count;
        this.restaurant = restaurant;
        this.ka = ka;
        this.wholesale = wholesale;
        this.industry = industry;
        this.other = other;
    }

    //    name:版块名称,count:目标值,restaurant:餐饮数量,ka:KA数量,wholesale:流通批发数量,industry:工业加工数量,other:其它数量
    private String city;
    private int name;
    private int count;
    private int restaurant;
    private int ka;
    private int wholesale;
    private int industry;
    private int other;
}
  • 步骤三:手动创建列字段
//普通列
Column<String> city = new Column<>("部门/渠道", "city");
Column<Integer> name = new Column<>("板块", "name");
Column<Integer> count = new Column<>("目标值", "count");
Column<Integer> restaurant = new Column<>("餐饮", "restaurant");
Column<Integer> ka = new Column<>("KA", "ka");
Column<Integer> wholesale = new Column<>("流通批发", "wholesale");
Column<Integer> industry = new Column<>("工业加工", "industry");
Column<Integer> other = new Column<>("其他", "other");
//设置该列当字段相同时自动合并
city.setAutoMerge(true);
  • 步骤四:设置单元格内容
//设置单元格内容
List<User> list = new ArrayList<>();
list.add(new User("沈阳", 100, 150, 50, 240, 1100, 450, 23458));
list.add(new User("沈阳", 100, 150, 50, 240, 1100, 450, 23458));
list.add(new User("沈阳", 100, 150, 50, 240, 1100, 450, 23458));
list.add(new User("沈阳", 100, 150, 50, 240, 1100, 450, 23458));
list.add(new User("乌鲁木齐", 100, 150, 50, 240, 1100, 450, 23458));
list.add(new User("乌鲁木齐", 100, 150, 50, 240, 1100, 450, 23458));
list.add(new User("乌鲁木齐", 100, 150, 50, 240, 1100, 450, 23458));
list.add(new User("乌鲁木齐", 100, 150, 50, 240, 1100, 450, 23458));
list.add(new User("沈阳", 100, 150, 50, 240, 1100, 450, 23458));
list.add(new User("沈阳", 100, 150, 50, 240, 1100, 450, 23458));
list.add(new User("沈阳", 100, 150, 50, 240, 1100, 450, 23458));
list.add(new User("沈阳", 100, 150, 50, 240, 1100, 450, 23458));
  • 步骤五:把数据绑定到 SmartTable 上
//表格数据 datas 是需要填充的数据
TableData<User> tableData = new TableData<>("表格名", list, city, name, count, restaurant, ka, wholesale, industry, other);

//设置数据
table = findViewById(R.id.table);
table.setTableData(tableData);
table.getConfig().setContentStyle(new FontStyle(50, Color.BLUE));

是不是也是分分钟的事,效果图是一样的就不贴了

优劣势:(个人看法,欢迎吐槽)

  • 注解方式
    • 使用上简单,几行代码就可以创建一个表格
    • 不能实现列的动态创建
    • 不能实现列的排序
  • 基本方式:
    • 使用上稍稍比注解方式麻烦一点
    • 可以实现列的动态创建(根据服务器返回的列的数量动态创建表格)
    • 可以实现点击列,对列进行升序以及倒序排列

注解的其他功能

  • @SmartTable:表格注解,用于生成表格

可用属性:

  • name:表格名
  • count:是否显示统计行
  • pageSize:页数量
  • currentPage:当前页
    目测没什么用,可能还没找到技巧,先记录下........
  • @SmartColumn列,用于注解列
  • name:列标题
  • id:列排列位置(id越小,位置越靠前)
  • parent:父列名称(不设置则没有父列)
  • align:列对其方式,默认居中
  • type:设置是否查询下一级,有 ColumnType.Own,ColumnType.Child,两个值可以设置,假设 UserInfo 有个属性是 Family family 对象,你想解析 faily 对象的属性 monther,father 两个属性,则需要设置 Child,并在 monther,father 下添加相对应的注解@SmartColumn,否则只解析到 Family,默认是 Own。
  • autoMerge:设置是否自动合并,假设你返回的数据格式化之后 该列附近数据有相同,则会自动合并成一个单元格,默认不开启合并。
  • maxMergeCount:合并最大数量
  • autoCount:是否开启统计,table 开启显示统计行,设置 autoCount 为 true,则该列可以自动统计,默认为 false。
  • fixed:是否固定该列, fixed 设置为 true,该列滚动到最左边时,可以自动固定住。

基本方法介绍

  • Column 类的常用方法
  • setAutoCount(boolean isAutoCount):设置自动排序(默认升序)
  • isReverseSort:是否是反序排列
  • setComparator:设置排序比较
  • setCountFormat:统计格式化
  • OnColumnItemClickListener:列内容点击事件
  • setFixed:滑动到表格左边时固定列
  • setTextAlign:设置开启自动合并
  • setMaxMergeCount:设置开启最大数量
  • setDrawFormat:设置绘制样式格式化
  • setFormat:设置文字格式化
  • TableData 类常用方法
  • setSortColumn:设置排序列
  • settitleDrawFormat:设置列标题格式化
  • setXSequenceFormat:设置顶部序列号格式化
  • setYSequenceFormat:设置左边序列号格式化
  • setShowCount:设置是否显示统计
  • setTitleDrawFormat:设置列标题绘制格式化
  • setXSequenceFormat :设置 X 序号行文字格式化
  • setYSequenceFormat :设置 Y 序号行文字格式化
  • setUserCellRange(List<CellRange> userCellRange) :设置添加自定义合并规则

TableConfig 类常用方法

  • setContentStyle :设置内容文字样式
  • setYSequenceStyle :设置左边序列文字样式
  • setXSequenceStyle :设置顶部序列文字样式
  • setColumnTitleStyle :设置列标题文字样式
  • setTableTitleStyle :设置表格标题文字样式
  • setCountStyle :设置统计行样式
  • setColumnTitleGridStyle :设置列标题网格样式
  • setGridStyle :设置内容网格样式
  • setVerticalPadding :设置网格列 padding
  • setHorizontalPadding :设置网格行 padding
  • setYSequenceBackgroundColor :设置左序列背景
  • setXSequenceBackgroundColor :设置横序行背景
  • setColumnTitleBackgroundColor :设置列标题背景
  • setContentBackgroundColor :设置内容背景
  • setCountBackgroundColor :设置统计行背景
  • setFixedYSequence :固定左侧
  • setFixedXSequence :固定顶部
  • setFixedTitle :固定列标题
  • setFixedCountRow :固定统计行
  • setColumnTitleVerticalPadding :列标题上下 padding
  • setColumnTitleHorizontalPadding :增加列标题左右 padding
  • setSequenceGridStyle :序列网格样式
  • columnTitleGridStyle :列标题网格样式
  • setShowXSequence :设置是否显示顶部序号列
  • setShowYSequence :设置是否显示左侧序号列
  • setShowTableTitle :设置是否显示表格标题
  • isShowColumnTitle :设置是否显示列标题
  • setMinTableWidth :设置表格最小宽度

SmartTable 类的常用方法

  • setOnColumnClickListener :设置列标题点击事件
  • setSortColumn :设置排序列
  • setZoom(boolean zoom,float maxZoom,float minZoom) :设置是否开启缩放
  • addData(List<T> t, boolean isFoot) :添加新数据
  • setSelectFormat :设置选中 Cell 样式
  • notifyDataChanged :重新计算布局

相关文章推荐:

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,761评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,953评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,998评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,248评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,130评论 4 356
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,145评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,550评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,236评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,510评论 1 291
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,601评论 2 310
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,376评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,247评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,613评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,911评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,191评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,532评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,739评论 2 335

推荐阅读更多精彩内容