zoukankan      html  css  js  c++  java
  • 【原创】【Andriod】自定义多行多列视图

    【需求描述】最近要开发一个文本视图组件,满足如下几种样式:

                    case 1: 三行两列,第一列的文字字数一样多

                  case 2: 三行两列,第一列的文字字数不一样多,第一列的右边线与第二列的左边线的间距是一定的,第二列里的每一项,可能有1~3行

               case 3: 可能有1~3行

    总结一下特点: 

    1)第一列左对齐(每一项为单行文字),第二列左对齐(每一项为1~3行文字)
    2)第二列距离第一列的最小间距是固定值
    3)第一列第一条与第二列第一条顶对齐,以此类推,第一列第二条与第二列第二条顶对齐……

    【技术方案】

             方案1:定义一个LinearLayout, 根据第一列文本的size和下发的文本来计算第一列的最大宽度,计算完成后,动态添加1~3个FrameLayout,1个FrameLayout中放每一行的子元素

             方案2:定义一个FrameLayout,根据第一列文本的size和下发的文本来计算第一列的最大宽度,然后计算出每一项的高度,分别对每个子元素进行布局。

      优点 缺点
    方案1 方案简单,将每一行元素的高度计算交给FrameLayout 会多3个FrameLayout,需要多Measure和layout 3次
    方案2 布局层次少,性能更优 需要考虑第二列的多行文本的高度计算

     

     方案1 核心代码如下:

     1 /**
     2      * 获取文本的长度
     3      *
     4      * @param displayText 待显示的文本
     5      * @return
     6      */
     7     private int getTextLength(String displayText) {
     8         Paint mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
     9         mTextPaint.setColor(getContext().getResources()
    10                 .getColor(R.color.msg_pay_notify_producer_name_key_color));
    11         mTextPaint.setTextSize(getContext().getResources().getDimensionPixelSize(
    12                         R.dimen.msg_pay_notify_producer_name_size));
    13         return (int) mTextPaint.measureText(displayText);
    14     }
    15 
    16 
    17 1、计算第一列的最大宽度
    18         ArrayList<String> displayLists = new ArrayList<>();
    19         for (PayCardModel.BodyItem item : bodys) {
    20             displayLists.add(item.getMName());
    21         }
    22         
    23         mFirstColumnWidth = 0;
    24         for (String displayText : displayLists) {
    25             mFirstColumnWidth = Math.max(mFirstColumnWidth, getTextLength(displayText));
    26         }
    27         
    28         if (mFirstColumnWidth == 0) {
    29             setVisibility(GONE);
    30             return;
    31         }
    32         setVisibility(VISIBLE);
    33         mFirstColumnWidth = mFirstColumnWidth > MAX_FIRST_COLUMN_WIDTH ?
    34                 MAX_FIRST_COLUMN_WIDTH : mFirstColumnWidth;
    35         mSecColumnLeftMargin = mFirstColumnWidth + getContext().getResources()
    36                 .getDimensionPixelSize(R.dimen.msg_pay_notify_producer_name_margin_left);
    37 
    38 
    39 2、动态添加子元素
    40 /**
    41      * 构造每一对数据需要的两个TextView
    42      *
    43      * @param item 数据对
    44      * @return
    45      */
    46     private ViewGroup buildItemViews(PayCardModel.BodyItem item) {
    47         if (!isDataValid(item)) {
    48             return null;
    49         }
    50         FrameLayout layout = new FrameLayout(getContext());
    51         LayoutParams layoutParams = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
    52                 ViewGroup.LayoutParams.WRAP_CONTENT);
    53         TextView titleView = new TextView(getContext());
    54         titleView.setText(item.getMName());
    55         titleView.setTextColor(getContext().getResources()
    56                 .getColor(R.color.msg_pay_notify_producer_name_key_color));
    57         titleView.setTextSize(TypedValue.COMPLEX_UNIT_PX,
    58                 getContext().getResources().getDimensionPixelSize(
    59                         R.dimen.msg_pay_notify_producer_name_size));
    60         titleView.setMaxLines(MAX_TITLE_LINE);
    61         titleView.setMaxEms(MAX_TITLE_EMS);
    62         FrameLayout.LayoutParams titleParams = new FrameLayout.LayoutParams(mFirstColumnWidth,
    63                 ViewGroup.LayoutParams.WRAP_CONTENT);
    64         layout.addView(titleView, titleParams);
    65     
    66         TextView view = new TextView(getContext());
    67         view.setText(item.getMValue());
    68         view.setTextColor(getContext().getResources()
    69                 .getColor(R.color.msg_pay_notify_source_color));
    70         view.setTextSize(TypedValue.COMPLEX_UNIT_PX,
    71                 getContext().getResources().getDimensionPixelSize(
    72                         R.dimen.msg_pay_notify_producer_name_size));
    73         view.setMaxLines(MAX_NAME_LINE);
    74         view.setEllipsize(TextUtils.TruncateAt.END);
    75         FrameLayout.LayoutParams viewParams = new FrameLayout.LayoutParams(
    76                 ViewGroup.LayoutParams.WRAP_CONTENT,
    77                 ViewGroup.LayoutParams.WRAP_CONTENT);
    78         viewParams.leftMargin = mSecColumnLeftMargin;
    79         layout.addView(view, viewParams);
    80         addView(layout, layoutParams);
    81         return layout;
    82     }

     

     

  • 相关阅读:
    Linux nfs服务讲解
    Linux nfs服务介绍
    牛客网题目-数组中只出现1次的数字
    牛客网中矩阵中的路径
    求链表的第一个公共节点
    C++中STL中简单的Vector的实现
    牛客网栈的压入,和弹出序列
    C++智能指针
    CI Weekly #22 | flow.ci 新版 iOS 构建流程的 4 大变化
    CI Weekly #21 | iOS 持续集成快速入门指南
  • 原文地址:https://www.cnblogs.com/meizixiong/p/13210087.html
Copyright © 2011-2022 走看看