方式2与方式1差不多,不同为所有计算都在onDraw函数中:
/** * 该方式与方式1很类似,只是所有的计算都放在了onDraw方法中。 */ { private Paint paint1 = new Paint(); private Paint paint2 = new Paint(); private int middlePadding = 0; int width; private float textSize; private JSONArray array; public TypographyView2(Context context) { super(context); init(); } public TypographyView2(Context context, AttributeSet attrs) { super(context, attrs); init(); } public TypographyView2(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } () { textSize = getResources().getDimensionPixelSize(R.dimen.text_size_13); paint1.setAntiAlias(true); paint1.setTextSize(textSize); paint1.setColor(getResources().getColor(R.color.color_black_999999)); paint2.setAntiAlias(true); paint2.setTextSize(textSize); paint2.setColor(getResources().getColor(R.color.color_black)); middlePadding = getResources().getDimensionPixelSize(R.dimen.padding_value); } (int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); width = getWidth();// 整个textView的宽度 } (JSONArray array) { this.array = array; if (array != null) { invalidate(); } } boolean setHeight = false; (Canvas canvas) { // super.onDraw(canvas); int lineCount = 0; int size = array.length(); float maxLeftWidth = 0; float drawWidth = 0; try { for (int i = 0; i < size; ++i) { JSONArray o = (JSONArray) array.get(i); String key = o.getString(0); float v = paint1.measureText(key); if (v > maxLeftWidth) { maxLeftWidth = v; } } maxLeftWidth = maxLeftWidth + middlePadding; for (int i = 0; i < size; ++i) { JSONArray o = (JSONArray) array.get(i); String key = o.getString(0); canvas.drawText(key, 0, (lineCount + 1) * textSize, paint1); String value = o.getString(1); char[] textCharArray = value.toCharArray(); float charWidth; drawWidth = maxLeftWidth; for (int j = 0; j < textCharArray.length; j++) { charWidth = paint1.measureText(textCharArray, j, 1); if (width - drawWidth < charWidth) { lineCount++; drawWidth = maxLeftWidth; } canvas.drawText(textCharArray, j, 1, drawWidth, (lineCount + 1) * textSize, paint2); drawWidth += charWidth; } lineCount += 2; } if (!setHeight) { setHeight((lineCount + 1) * (int) textSize + 5); setHeight = true; } } catch (JSONException e) { e.printStackTrace(); } } }该方案的实现是不太好的,方案1也是在此基础上进行调整的,在这里放出来只是为了说明,所有的计算不要全部放在onDraw里面,因为该方法可能会反复调用多次,这样就降低了性能。
方案3将数据源拼接成SpannableString,重写onDraw函数,根据内容draw每一个字符:
/** * 该方法,是需要显示的内容先拼接成SpannableString,在onDraw方法中获取所有的char字符,一个一个比较 * 当为分号是,表示为key与value的分隔符。 */ { private Paint leftPaint = new Paint(); private Paint rightPaint = new Paint(); int width; private String text; private float textSize; float maxLeftWidth = 0; private int middlePadding = 0; public TypographyView3(Context context) { super(context); init(); } public TypographyView3(Context context, AttributeSet attrs) { super(context, attrs); init(); } public TypographyView3(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } () { textSize = getResources().getDimensionPixelSize(R.dimen.text_size_13); textSize = getResources().getDimensionPixelSize(R.dimen.text_size_13); leftPaint.setAntiAlias(true); leftPaint.setTextSize(textSize); leftPaint.setColor(getResources().getColor(R.color.color_black_999999)); rightPaint.setAntiAlias(true); rightPaint.setTextSize(textSize); rightPaint.setColor(getResources().getColor(R.color.color_black)); middlePadding = getResources().getDimensionPixelSize(R.dimen.padding_value); } (int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); width = getWidth();// 整个textView的宽度 } (JSONArray data) { if (data == null) { return; } try { int size = data.length(); for (int i = 0; i < size; ++i) { JSONArray o = (JSONArray) data.get(i); String key = o.getString(0); float v = leftPaint.measureText(key); if (v > maxLeftWidth) { maxLeftWidth = v; } } maxLeftWidth += middlePadding; SpannableStringBuilder ssb = new SpannableStringBuilder(); for (int i = 0; i < size; ++i) { addItem((JSONArray) data.get(i), ssb, i != 0); } setText(ssb, BufferType.SPANNABLE); } catch (Exception e) { } } (JSONArray item, SpannableStringBuilder ssb, boolean breakLine) { try { if (item == null || item.length() == 0) { return; } String key = item.getString(0); String value = (item.length() >= 2) ? item.getString(1) : ""; if (TextUtils.isEmpty(key) && TextUtils.isEmpty(value)) { return; } if (breakLine) {// 换行 ssb.append("\r\n"); ssb.append("\r\n"); } SpannableString span = new SpannableString(key); ssb.append(span); ssb.append(value); } catch (JSONException e) { e.printStackTrace(); } } (Canvas canvas) { // super.onDraw(canvas); int lineCount = 0; text = this.getText().toString(); if (text == null) return; char[] textCharArray = text.toCharArray(); // 已绘的宽度 float drawWidth = 0; float charWidth; Paint paint = leftPaint; for (int i = 0; i < textCharArray.length; i++) { charWidth = leftPaint.measureText(textCharArray, i, 1); if (textCharArray[i] == '\n') { lineCount++; drawWidth = 0; paint = leftPaint; continue; } if (width - drawWidth < charWidth) { lineCount++; drawWidth = maxLeftWidth; } if (i > 1 && textCharArray[i - 1] == ':') { drawWidth = maxLeftWidth; paint = rightPaint; } canvas.drawText(textCharArray, i, 1, drawWidth, (lineCount + 1) * textSize, paint); drawWidth += charWidth; } //may be need set height //setHeight((lineCount + 1) * (int) textSize + 5); } }