画一个由圆圈围成的正方形
Drawing a square bound by a circle
我正在尝试制作一个自定义视图,基本上是一个实心圆,其中有一个包围着一些文本的有界正方形视图。
所以我创建了一个 CircleRelativeLayout,它嵌套了包含文本的 CircleHolderRelativeLayout。 CircleHolderRelativeLayout 的宽度为 (parent_width/2)*sqrt(2) - 对于边界。
public class CircleRelativeLayout extends RelativeLayout {
private int circleColor = Color.TRANSPARENT;
private Paint drawPaint;
private int mSize;
public CircleRelativeLayout(Context context) {
super(context);
}
public CircleRelativeLayout(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs, 0);
}
public CircleRelativeLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs, 0);
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public CircleRelativeLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init(context, attrs, 0);
}
private void setupPaint() {
drawPaint = new Paint();
drawPaint.setColor(circleColor);
drawPaint.setAntiAlias(true);
drawPaint.setStyle(Paint.Style.FILL);
}
private void init(Context context, AttributeSet attrs, int defStyle) {
TypedArray ta = context.getTheme().obtainStyledAttributes(attrs, R.styleable.CircleView, 0, 0);
circleColor = ta.getColor(R.styleable.CircleView_circleColor, 0);
ta.recycle();
setupPaint();
}
@Override
protected void dispatchDraw(Canvas canvas) {
canvas.drawCircle(Math.min(this.getWidth(), this.getHeight()) / 2, Math.min(this.getWidth(), this.getHeight()) / 2, Math.min(this.getWidth(), this.getHeight()) / 2, drawPaint);
}
public void setCircleColor(int newColor){
//update the instance variable
circleColor=newColor;
//redraw the view
invalidate();
requestLayout();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int originalWidth = MeasureSpec.getSize(widthMeasureSpec);
int originalHeight = MeasureSpec.getSize(heightMeasureSpec);
int required = Math.min(originalWidth, originalHeight);
super.onMeasure(
MeasureSpec.makeMeasureSpec(required, MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(required, MeasureSpec.EXACTLY));
}
}
和
public class CircleHolderRelativeLayout extends RelativeLayout {
public CircleHolderRelativeLayout(Context context) {
super(context);
}
public CircleHolderRelativeLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CircleHolderRelativeLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public CircleHolderRelativeLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int size = (int)((Math.min(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.getSize(heightMeasureSpec))/2)*(Math.sqrt(2)));
super.onMeasure(MeasureSpec.makeMeasureSpec(size, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(size, MeasureSpec.EXACTLY));
}
}
而 xml 是
<ro.cloud.onebox.ui.layout.CircleRelativeLayout
android:id="@+id/circleView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
custom:circleColor="@color/status_new"
android:layout_margin="@dimen/main_margin">
<ro.cloud.onebox.ui.layout.CircleHolderRelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true"
android:background="@color/colorAccent">
<ro.cloud.onebox.ui.text.CustomTextViewNormal
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textColor="@color/primary_text_color_dark"
android:gravity="center"
android:layout_centerInParent="true"
android:text="1asdasdasasdasdasdd2"/>
</ro.cloud.onebox.ui.layout.CircleHolderRelativeLayout>
</ro.cloud.onebox.ui.layout.CircleRelativeLayout>
问题是 Circle 绘制在布局子项上。因此我看不到文字。如果我将绘画更改为 STROKE,我可以清楚地看到文字在那里。帮助:)
使用 FrameLayout 作为容器
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ro.cloud.onebox.ui.layout.CircleRelativeLayout
android:id="@+id/circleView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
custom:circleColor="@color/status_new"
android:layout_margin="@dimen/main_margin">
</ro.cloud.onebox.ui.layout.CircleRelativeLayout>
<ro.cloud.onebox.ui.layout.CircleHolderRelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true"
android:background="@color/colorAccent">
</ro.cloud.onebox.ui.layout.CircleHolderRelativeLayout>
<ro.cloud.onebox.ui.text.CustomTextViewNormal
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textColor="@color/primary_text_color_dark"
android:gravity="center"
android:layout_centerInParent="true"
android:text="1asdasdasasdasdasdd2"/>
</FrameLayout>
更改您的代码
@Override
protected void dispatchDraw(Canvas canvas) {
canvas.drawCircle(Math.min(this.getWidth(), this.getHeight()) / 2, Math.min(this.getWidth(), this.getHeight()) / 2, Math.min(this.getWidth(), this.getHeight()) / 2, drawPaint);
}
至
@Override
protected void dispatchDraw(Canvas canvas) {
canvas.drawCircle(Math.min(this.getWidth(), this.getHeight()) / 2, Math.min(this.getWidth(), this.getHeight()) / 2, Math.min(this.getWidth(), this.getHeight()) / 2, drawPaint);
for(int i = 0; i<getChildCount(); i++) {
getChildAt(i).draw(canvas);
}
}
这将显示您的文本。
我正在尝试制作一个自定义视图,基本上是一个实心圆,其中有一个包围着一些文本的有界正方形视图。 所以我创建了一个 CircleRelativeLayout,它嵌套了包含文本的 CircleHolderRelativeLayout。 CircleHolderRelativeLayout 的宽度为 (parent_width/2)*sqrt(2) - 对于边界。
public class CircleRelativeLayout extends RelativeLayout {
private int circleColor = Color.TRANSPARENT;
private Paint drawPaint;
private int mSize;
public CircleRelativeLayout(Context context) {
super(context);
}
public CircleRelativeLayout(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs, 0);
}
public CircleRelativeLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs, 0);
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public CircleRelativeLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init(context, attrs, 0);
}
private void setupPaint() {
drawPaint = new Paint();
drawPaint.setColor(circleColor);
drawPaint.setAntiAlias(true);
drawPaint.setStyle(Paint.Style.FILL);
}
private void init(Context context, AttributeSet attrs, int defStyle) {
TypedArray ta = context.getTheme().obtainStyledAttributes(attrs, R.styleable.CircleView, 0, 0);
circleColor = ta.getColor(R.styleable.CircleView_circleColor, 0);
ta.recycle();
setupPaint();
}
@Override
protected void dispatchDraw(Canvas canvas) {
canvas.drawCircle(Math.min(this.getWidth(), this.getHeight()) / 2, Math.min(this.getWidth(), this.getHeight()) / 2, Math.min(this.getWidth(), this.getHeight()) / 2, drawPaint);
}
public void setCircleColor(int newColor){
//update the instance variable
circleColor=newColor;
//redraw the view
invalidate();
requestLayout();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int originalWidth = MeasureSpec.getSize(widthMeasureSpec);
int originalHeight = MeasureSpec.getSize(heightMeasureSpec);
int required = Math.min(originalWidth, originalHeight);
super.onMeasure(
MeasureSpec.makeMeasureSpec(required, MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(required, MeasureSpec.EXACTLY));
}
}
和
public class CircleHolderRelativeLayout extends RelativeLayout {
public CircleHolderRelativeLayout(Context context) {
super(context);
}
public CircleHolderRelativeLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CircleHolderRelativeLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public CircleHolderRelativeLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int size = (int)((Math.min(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.getSize(heightMeasureSpec))/2)*(Math.sqrt(2)));
super.onMeasure(MeasureSpec.makeMeasureSpec(size, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(size, MeasureSpec.EXACTLY));
}
}
而 xml 是
<ro.cloud.onebox.ui.layout.CircleRelativeLayout
android:id="@+id/circleView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
custom:circleColor="@color/status_new"
android:layout_margin="@dimen/main_margin">
<ro.cloud.onebox.ui.layout.CircleHolderRelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true"
android:background="@color/colorAccent">
<ro.cloud.onebox.ui.text.CustomTextViewNormal
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textColor="@color/primary_text_color_dark"
android:gravity="center"
android:layout_centerInParent="true"
android:text="1asdasdasasdasdasdd2"/>
</ro.cloud.onebox.ui.layout.CircleHolderRelativeLayout>
</ro.cloud.onebox.ui.layout.CircleRelativeLayout>
问题是 Circle 绘制在布局子项上。因此我看不到文字。如果我将绘画更改为 STROKE,我可以清楚地看到文字在那里。帮助:)
使用 FrameLayout 作为容器
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ro.cloud.onebox.ui.layout.CircleRelativeLayout
android:id="@+id/circleView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
custom:circleColor="@color/status_new"
android:layout_margin="@dimen/main_margin">
</ro.cloud.onebox.ui.layout.CircleRelativeLayout>
<ro.cloud.onebox.ui.layout.CircleHolderRelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true"
android:background="@color/colorAccent">
</ro.cloud.onebox.ui.layout.CircleHolderRelativeLayout>
<ro.cloud.onebox.ui.text.CustomTextViewNormal
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textColor="@color/primary_text_color_dark"
android:gravity="center"
android:layout_centerInParent="true"
android:text="1asdasdasasdasdasdd2"/>
</FrameLayout>
更改您的代码
@Override
protected void dispatchDraw(Canvas canvas) {
canvas.drawCircle(Math.min(this.getWidth(), this.getHeight()) / 2, Math.min(this.getWidth(), this.getHeight()) / 2, Math.min(this.getWidth(), this.getHeight()) / 2, drawPaint);
}
至
@Override
protected void dispatchDraw(Canvas canvas) {
canvas.drawCircle(Math.min(this.getWidth(), this.getHeight()) / 2, Math.min(this.getWidth(), this.getHeight()) / 2, Math.min(this.getWidth(), this.getHeight()) / 2, drawPaint);
for(int i = 0; i<getChildCount(); i++) {
getChildAt(i).draw(canvas);
}
}
这将显示您的文本。