173

好用漂亮的Android 表格框架

 6 years ago
source link: https://juejin.im/post/5a55ae6c5188257350511a8c
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

好用漂亮的Android 表格框架

2018年01月11日 02:21 ·  阅读 56615

Android 表格使用的频率并不高,之前花了心思写了SmartTable表格,觉得android移动端表格就应该是这个样子的,地址github.com/huangyanbin…,一直放在github上无人问津,最近有同学说蛮好用的,为啥没更新下去。便想写这边文章推销推销。也算值了!我按功能点一一介绍下:

附上其他文章:

好用漂亮的Android 表格框架2

好用漂亮的Android 表格框架3

如何生成一个表格
 <com.bin.david.form.core.SmartTable
       android:id="@+id/table"
       android:layout_width="match_parent"
       android:layout_height="300dp"

      />复制代码

可以通过注解@SmartTable表格注解 @SmartColumn字段注解

@SmartTable(name="用户信息列表")
public class UserInfo {
    @SmartColumn(id =1,name = "姓名")
    private String name;
    @SmartColumn(id=2,name="年龄")
    private int age;
    ...
}

    List<UserInfo> list = new ArrayList<>();
    ...
    table = (SmartTable<UserInfo>) findViewById(R.id.table);
    table.setData(list);复制代码

OK,这就是最简单的注解版。下面看下强大功能的普通版。只需要创建需要显示的列,设置需要解析的字段就可以,假设需要解析到UserInfo.parent.name,只需parent.name即可。

160dee60c46162f8~tplv-t2oaga2asx-zoom-in-crop-mark:3024:0:0:0.awebp
final Column<String> nameColumn = new Column<>("姓名", "name");
final Column<Integer> ageColumn = new Column<>("年龄", "age");
 ...
 tableData = new TableData<>("测试",list,nameColumn,ageColumn...);
 table.setTableData(tableData);
 复制代码

肯定有人说,这点功能,呵呵。来来,我们坐一下,开始展示丰富的功能。界面不美观,看这里,格式化一下内容背景:

 table.getConfig().setContentBackgroundFormat(new BaseBackgroundFormat<CellInfo>() {
            @Override
            public int getBackGroundColor() {
                return ContextCompat.getColor(AnnotationModeActivity.this,R.color.content_bg);
            }
            @Override
            public boolean isDraw(CellInfo cellInfo) {
                return cellInfo.position%2 ==0;
            }
        });复制代码


160dee634b172184~tplv-t2oaga2asx-zoom-in-crop-mark:3024:0:0:0.awebp
格式化数据

发现时间这个列很不美观,我们想要格式化一下时间这列


 final IFormat<Long> format =  new IFormat<Long>() {
            @Override
            public String format(Long aLong) {
                Calendar calendar = Calendar.getInstance();
                calendar.setTimeInMillis(aLong);
                return calendar.get(Calendar.YEAR)+"-"+(calendar.get(Calendar.MONTH)+1)+"-"+calendar.get(Calendar.DAY_OF_MONTH);
            }
        };
final Column<Long> timeColumn = new Column<>("时间", "time",format);
复制代码

还支持表格图文、序列号、列标题格式化;表格各组成背景、文字、网格、padding等配置,你可以参考demo;

勾选这列,我们想展示勾选的图标

 int size = DensityUtils.dp2px(this,15); //指定图标大小
 Column<Boolean> checkColumn = new Column<>("勾选", "isCheck",new ImageResDrawFormat<Boolean>(size,size) {
            @Override
            protected Context getContext() {
                return AnnotationModeActivity.this;
            }

            @Override
            protected int getResourceID(Boolean isCheck, String value, int position) {
                if(isCheck){
                    return R.mipmap.check;
                }
                return 0;
            }
        });复制代码


160dee66fd887455~tplv-t2oaga2asx-zoom-in-crop-mark:3024:0:0:0.awebp

提供支持文字,多行文字,文字和图标组合(上下左右)

表格一般可以统计功能,我们开启统计功能setShowCount(true),哪列需要统计开启setAutoCount即可,数字如果统计就是相加,文字就是取最长的大小

 tableData.setShowCount(true);
 nameColumn.setAutoCount(true);复制代码

但是这样不满足真实需求,需求往往很坑爹。所以提供了统计接口。下面是统计最大时间示例:

 timeColumn.setAutoCount(true);
        timeColumn.setCountFormat(new ICountFormat<Long, Long>() {
            private long maxTime;
            @Override
            public void count(Long aLong) {
                if(aLong > maxTime){
                    maxTime = aLong;
                }
            }

            @Override
            public Long getCount() {
                return maxTime;
            }

            @Override
            public String getCountString() {
                return format.format(maxTime);
            }

            @Override
            public void clearCount() {
                maxTime =0;
            }
        });复制代码

有时候我们需要标题组合,这个时候就可以这样玩:

Column groupColumn = new Column("组合",nameColumn,ageColumn);
TableData<UserInfo> tableData = new TableData<>("用户表",userInfos,groupColumn,timeColumn,checkColumn);复制代码

固定指定列和X序号列,Y序号列,列标题,统计行。你可以根据需求开启,组合效果真的很棒

//固定指定列
   timeColumn.setFixed(true);
   //Y序号列
   table.getConfig().setFixedYSequence(true);
   //X序号列
   table.getConfig().setFixedXSequence(true);
   //列标题
   table.getConfig().setFixedCountRow(true);
   //统计行
   table.getConfig().setFixedTitle(true);
 复制代码

当然肯定少不了放大和缩小

table.setZoom(true);
//可以设置放大最大和最小值
 setZoom(boolean zoom,float maxZoom,float minZoom);复制代码

批注和点击事件

table.setOnColumnClickListener();

 MultiLineBubbleTip<Column> tip = new MultiLineBubbleTip<Column>(this,R.mipmap.round_rect,R.mipmap.triangle,fontStyle) {
            @Override
            public boolean isShowTip(Column column, int position) {
                if(column == nameColumn){
                    return true;
                }
                return false;
            }


            @Override
            public String[] format(Column column, int position) {
                UserInfo data = testData.get(position);
                String[] strings = {"批注","姓名:"+data.getName(),"年龄:"+data.getAge()};
                return strings;
            }
        };复制代码

可以通过设置列,然后列条件来排序。

//设置排序列,设置是否反序
 table.setSortColumn(ageColumn,false);复制代码

如果觉得还是不满足,可以自己定义排序规则

ageColumn.setComparator(new Comparator<Integer>() {
   @Override
   public int compare(Integer o1, Integer o2) {
      return o1- o2;
   }
 });复制代码

支持二维数组

你可以使用ArrayTableData来代替TableData。就可以愉快的使用二维数组,你甚至可以不用设置列标题。这样可以实现一些类似选票和选座app需求。

 String[] week = {"日","一","二","三","四","五","六"};
       Integer[][] infos = {{0,1,2,1,1,0,1,1,0,1,1,2,3}, {4,2,1,1,0,1,1,0,1,1,2,2,3},
               {2,2,0,1,2,4,1,0,1,3,0,1,1},{2,1,1,0,1,4,0,1,1,2,2,0,3},
               {0,1,2,4,1,0,1,4,0,1,1,2,2}, {1,0,1,3,2,2,0,1,2,1,1,0,4},
               {3,1,2,4,0,1,2,1,1,0,1,1,0}};
 ArrayTableData<Integer> tableData = ArrayTableData.create("日程表",week,infos,new IDrawFormat<Integer>(){

           @Override
           public int measureWidth(Column<Integer> column, TableConfig config) {
               return DensityUtils.dp2px(ArrayModeActivity.this,50);
           }

           @Override
           public int measureHeight(Column<Integer> column, int position, TableConfig config) {
               return DensityUtils.dp2px(ArrayModeActivity.this,50);
           }

           @Override
           public void draw(Canvas c, Column<Integer> column, Integer integer, String value, Rect rect, int position, TableConfig config) {
               Paint paint = config.getPaint();
               int color;
               switch (integer){
                   case 1:
                       color =R.color.github_con_1;
                       break;
                   case 2:
                       color =R.color.github_con_2;
                       break;
                   case 3:
                       color =R.color.github_con_3;
                       break;
                   case 4:
                       color =R.color.github_con_4;
                       break;
                   default:
                       color =R.color.github_con_0;
                       break;
               }
               paint.setStyle(Paint.Style.FILL);
               paint.setColor(ContextCompat.getColor(ArrayModeActivity.this, color));
               c.drawRect(rect.left+5,rect.top+5,rect.right-5,rect.bottom-5,paint);
           }
       });复制代码

还有很多功能点,包括动态添加首尾数据,分页,格式化字体,背景等。这里不一一介绍了。

  • 支持首尾动态添加数据

首尾动态添加数据 SmartTable.addData(List<T> t,boolean isFoot)来实现添加数据.

  • 设置单个格子背景

在网上参考了htmltable,发现样式好看多了,按到这个思路,SmartTable增加了支持对单个格子的不同背景支持,在TableConfig里面有5个IBackgroundFormat样式,可以根据boolean isDraw(T t)返回数据做出判断是否绘制背景drawBackground,默认绘制整个背景,当然你可以自己定义IBackgroundFormat使用其他形状。

  • 设置单个格子字体

由于支持到单个格子背景的支持,字体颜色也需要根据背景还进行调整,所以又支持单个格子的字体设置,IBackgroundFormat中有 int getTextColor(T t),你只需重写它,根据需求设置不同颜色。

在客户端太多数据体验不好,所以开发分页模式,在未使用注解情况下,只需要使用PageTableData分页表格数据类 代替之前TableData表格数据类即可,使用PageTableDatasetPageSize方法设置每页数量。分页就完成了。 如果你使用注解,请在@SmartTable注解元素添加pageSize属性即可,setData会返回PageTableData对象,你可以使用它完成后面其他的设置。

SmartTable 增加notifyDataChanged方法用于重新解析计算布局;

提供back方法fling到原点。

github地址

github.com/huangyanbin…


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK