/
TiBorderWrapperView.java
148 lines (130 loc) Β· 3.96 KB
/
TiBorderWrapperView.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
/**
* Appcelerator Titanium Mobile
* Copyright (c) 2012-2017 by Axway, Inc. All Rights Reserved.
* Licensed under the terms of the Apache Public License
* Please see the LICENSE included with this distribution for details.
*/
package org.appcelerator.titanium.view;
import com.nineoldandroids.view.ViewHelper;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Path.Direction;
import android.graphics.PorterDuff;
import android.graphics.Rect;
import android.graphics.RectF;
import android.os.Build;
import android.view.View;
import android.widget.FrameLayout;
import android.view.ViewOutlineProvider;
import android.graphics.Outline;
/**
* This class is a wrapper for Titanium Views with borders. Any view that specifies a border
* related property will have a border wrapper view to maintain its border.
*/
public class TiBorderWrapperView extends FrameLayout
{
private static final String TAG = "TiBorderWrapperView";
private int color = Color.TRANSPARENT;
private int backgroundColor = Color.TRANSPARENT;
private float radius = 0;
private float borderWidth = 0;
private int alpha = -1;
private Paint paint;
private Rect bounds;
private ViewOutlineProvider viewOutlineProvider;
public TiBorderWrapperView(Context context)
{
super(context);
setWillNotDraw(false);
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
bounds = new Rect();
}
@Override
protected void onDraw(Canvas canvas)
{
getDrawingRect(bounds);
int maxPadding = (int) Math.min(bounds.right / 2, bounds.bottom / 2);
int padding = (int) Math.min(borderWidth, maxPadding);
RectF innerRect =
new RectF(bounds.left + padding, bounds.top + padding, bounds.right - padding, bounds.bottom - padding);
RectF outerRect = new RectF(bounds);
paint.setColor(color);
if (alpha > -1) {
paint.setAlpha(alpha);
}
Path outerPath = new Path();
if (radius > 0f) {
float innerRadius = radius - padding;
if (innerRadius > 0f) {
outerPath.addRoundRect(innerRect, innerRadius, innerRadius, Direction.CW);
} else {
outerPath.addRect(innerRect, Direction.CW);
}
Path innerPath = new Path(outerPath);
// draw border
outerPath.addRoundRect(outerRect, radius, radius, Direction.CCW);
canvas.drawPath(outerPath, paint);
// TIMOB-16909: hack to fix anti-aliasing
if (backgroundColor != Color.TRANSPARENT) {
paint.setColor(backgroundColor);
canvas.drawPath(innerPath, paint);
}
canvas.clipPath(innerPath);
if (backgroundColor != Color.TRANSPARENT) {
canvas.drawColor(0, PorterDuff.Mode.CLEAR);
}
} else {
outerPath.addRect(outerRect, Direction.CW);
outerPath.addRect(innerRect, Direction.CCW);
canvas.drawPath(outerPath, paint);
canvas.clipRect(innerRect);
}
// TIMOB-20076: set the outline for the view in order to use elevation
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && viewOutlineProvider == null) {
viewOutlineProvider = new ViewOutlineProvider() {
@Override
public void getOutline(View view, Outline outline)
{
outline.setRoundRect(bounds, radius);
}
};
setOutlineProvider(viewOutlineProvider);
}
}
public void setColor(int color)
{
this.color = color;
}
public void setBgColor(int color)
{
this.backgroundColor = color;
}
public void setRadius(float radius)
{
this.radius = radius;
}
public void setBorderWidth(float borderWidth)
{
this.borderWidth = borderWidth;
}
@Override
public boolean onSetAlpha(int alpha)
{
if (Build.VERSION.SDK_INT < 11) {
/*
* TIMOB-17287: This is an ugly hack. ViewHelper.setAlpha does not work on border
* when alpha < 1. So we are going to manage alpha animation for ourselves and our
* child view manually. This needs to be researched and factored out.
*/
this.alpha = alpha;
if (getChildCount() > 0) {
ViewHelper.setAlpha(getChildAt(0), alpha / 255.0f);
}
return true;
}
return false;
}
}