在圆圈内创建右箭头
Creating right arrow inside circle
我想使用 android 如下所示绘制图像:
我可以做箭头,但是当我添加圆圈时,图像会变形。
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item>
<shape>
<solid android:color="@android:color/transparent"/>
<size android:width="2dp" android:height="50dp"/>
</shape>
</item>
<item android:bottom="20dp">
<rotate
android:fromDegrees="45"
android:toDegrees="45">
<shape android:shape="rectangle">
<solid android:color="#F0AD4E"/>
<corners
android:radius="0dp"
android:bottomRightRadius="0dp"
android:bottomLeftRadius="0dp"/>
</shape>
</rotate>
</item>
<item android:top="20dp">
<rotate
android:fromDegrees="-45"
android:toDegrees="45">
<shape android:shape="rectangle">
<solid android:color="#F0AD4E"/>
<corners
android:radius="0dp"
android:topRightRadius="0dp"
android:topLeftRadius="0dp"/>
</shape>
</rotate>
</item>
谁能帮我补图
谢谢。
不要为此使用可绘制对象,使用自定义视图和 canvas。
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;
/**
* Created by Bojan on 17.5.2015.
*/
public class CircleRightArrow extends View {
private int circleColor = 0xFF505070;
private int arrowColor = 0xFF505070;
private int measuredSize;
private int strokeWidth;
private Paint mCirclePiant, mArrowPaint;
public CircleRightArrow(Context context) {
super(context);
init(context, null, 0);
}
public CircleRightArrow(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs, 0);
}
public CircleRightArrow(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs, defStyleAttr);
}
private void init(Context context, AttributeSet attributeSet, int defStyle) {
mCirclePiant = new Paint(Paint.ANTI_ALIAS_FLAG);
mCirclePiant.setColor(circleColor);
mCirclePiant.setStyle(Paint.Style.STROKE);
mArrowPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mArrowPaint.setColor(arrowColor);
mArrowPaint.setStyle(Paint.Style.STROKE);
mArrowPaint.setStrokeCap(Paint.Cap.ROUND);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int measuredHeight = getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec);
int measuredWidth = getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec);
measuredSize = Math.min(measuredHeight, measuredWidth);
strokeWidth = Math.round(measuredSize * 0.05f);
mCirclePiant.setStrokeWidth(strokeWidth);
mArrowPaint.setStrokeWidth(strokeWidth);
// Make a square
setMeasuredDimension(measuredSize + strokeWidth, measuredSize + strokeWidth);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (measuredSize <= 0) {
// Not much we can draw, can we
return;
}
float center = (measuredSize + strokeWidth) * 0.5f;
canvas.drawCircle(center, center, measuredSize * 0.5f, mCirclePiant);
canvas.drawLine(center + 0.2f * measuredSize, center, center - 0.1f * measuredSize, center + 0.2f * measuredSize, mArrowPaint);
canvas.drawLine(center + 0.2f * measuredSize, center, center - 0.1f * measuredSize, center - 0.2f * measuredSize, mArrowPaint);
}
}
1920x1080p 下 50x50dp 的结果
根据 Bojan 的回答,我编辑了视图以根据触摸事件重绘并添加了 OnClickListener
部分。欢迎提出任何改进建议。
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
/**
* Created by noorul.ahmed on 5/18/2015.
*/
public class CircleRightArrow extends View {
private int viewColor;
private int backgroundColor;
private int normalColor = 0xFFF0AD4E;
private int normalBackground = 0xFFFFFFFF;
private int touchBackground = 0xFFEC971F;
private int touchColor = 0xFFFFFFFF;
private int disabledBackground = 0xFFFFFFFF;
private int disabledColor = 0xFFCECECE;
private int measuredSize;
private int strokeWidth;
private boolean touched = false;
private float startX, startY, endX, endY;
private OnClickListener listener;
private Paint mCirclePiant, mArrowPaint;
public CircleRightArrow(Context context) {
super(context);
init(context, null, 0);
setInitialColor();
}
public CircleRightArrow(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs, 0);
setInitialColor();
}
public CircleRightArrow(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs, defStyleAttr);
setInitialColor();
}
private void init(Context context, AttributeSet attributeSet, int defStyle) {
mCirclePiant = new Paint(Paint.ANTI_ALIAS_FLAG);
mCirclePiant.setColor(viewColor);
mCirclePiant.setStyle(Paint.Style.STROKE);
mArrowPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mArrowPaint.setColor(viewColor);
mArrowPaint.setStyle(Paint.Style.STROKE);
mArrowPaint.setStrokeCap(Paint.Cap.ROUND);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int measuredHeight = getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec);
int measuredWidth = getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec);
measuredSize = Math.min(measuredHeight, measuredWidth);
strokeWidth = Math.round(measuredSize * 0.025f);
mCirclePiant.setStrokeWidth(strokeWidth);
mArrowPaint.setStrokeWidth(strokeWidth);
// Make a square
setMeasuredDimension(measuredSize + strokeWidth, measuredSize + strokeWidth);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (measuredSize <= 0) {
// Not much we can draw, can we
return;
}
float center = (measuredSize + strokeWidth) * 0.5f;
canvas.drawCircle(center, center, measuredSize * 0.5f, mCirclePiant);
canvas.drawLine(center + 0.2f * measuredSize, center, center - 0.1f * measuredSize, center + 0.2f * measuredSize, mArrowPaint);
canvas.drawLine(center + 0.2f * measuredSize, center, center - 0.1f * measuredSize, center - 0.2f * measuredSize, mArrowPaint);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
boolean result = super.onTouchEvent(event);
switch (event.getAction()){
case MotionEvent.ACTION_DOWN :
touched = true;
startX = event.getX();
startY = event.getY();
togglePaintColor(event);
postInvalidate();
return true;
case MotionEvent.ACTION_UP :
endX = event.getX();
endY = event.getY();
togglePaintColor(event);
postInvalidate();
float diffX = Math.abs(startX - endX);
float diffY = Math.abs(startY - endY);
if (diffX <= 5 && diffY <= 5 && touched ) {
dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_UP,1));
}
return true;
default:
return false;
}
}
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
if(event.getAction() == KeyEvent.ACTION_UP) {
touched = false;
if(listener != null) listener.onClick(this);
}
return super.dispatchKeyEvent(event);
}
public void setListener(OnClickListener listener) {
this.listener = listener;
}
public void setInitialColor(){
if (isClickable()){
viewColor = normalColor;
backgroundColor = normalBackground;
}
else {
viewColor = disabledColor;
backgroundColor = disabledBackground;
this.listener = null;
}
mCirclePiant.setColor(viewColor);
mCirclePiant.setStyle(Paint.Style.STROKE);
mArrowPaint.setColor(viewColor);
}
@Override
public void setClickable(boolean isClickable){
super.setClickable(isClickable);
if (isClickable){
viewColor = normalColor;
backgroundColor = normalBackground;
}
else {
viewColor = disabledColor;
backgroundColor = disabledBackground;
this.listener = null;
}
mCirclePiant.setColor(viewColor);
mCirclePiant.setStyle(Paint.Style.STROKE);
mArrowPaint.setColor(viewColor);
postInvalidate();
}
private void togglePaintColor(MotionEvent event) {
if (isClickable()) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
viewColor = touchColor;
backgroundColor = touchBackground;
mCirclePiant.setColor(backgroundColor);
mCirclePiant.setStyle(Paint.Style.FILL);
mArrowPaint.setColor(viewColor);
} else if (event.getAction() == MotionEvent.ACTION_UP) {
viewColor = normalColor;
backgroundColor = normalBackground;
mCirclePiant.setColor(viewColor);
mCirclePiant.setStyle(Paint.Style.STROKE);
mArrowPaint.setColor(viewColor);
}
}
}
}
三种按钮状态是:
- 正常状态
- 按下状态
- 禁用状态
我想使用 android 如下所示绘制图像:
我可以做箭头,但是当我添加圆圈时,图像会变形。
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item>
<shape>
<solid android:color="@android:color/transparent"/>
<size android:width="2dp" android:height="50dp"/>
</shape>
</item>
<item android:bottom="20dp">
<rotate
android:fromDegrees="45"
android:toDegrees="45">
<shape android:shape="rectangle">
<solid android:color="#F0AD4E"/>
<corners
android:radius="0dp"
android:bottomRightRadius="0dp"
android:bottomLeftRadius="0dp"/>
</shape>
</rotate>
</item>
<item android:top="20dp">
<rotate
android:fromDegrees="-45"
android:toDegrees="45">
<shape android:shape="rectangle">
<solid android:color="#F0AD4E"/>
<corners
android:radius="0dp"
android:topRightRadius="0dp"
android:topLeftRadius="0dp"/>
</shape>
</rotate>
</item>
谁能帮我补图
谢谢。
不要为此使用可绘制对象,使用自定义视图和 canvas。
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;
/**
* Created by Bojan on 17.5.2015.
*/
public class CircleRightArrow extends View {
private int circleColor = 0xFF505070;
private int arrowColor = 0xFF505070;
private int measuredSize;
private int strokeWidth;
private Paint mCirclePiant, mArrowPaint;
public CircleRightArrow(Context context) {
super(context);
init(context, null, 0);
}
public CircleRightArrow(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs, 0);
}
public CircleRightArrow(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs, defStyleAttr);
}
private void init(Context context, AttributeSet attributeSet, int defStyle) {
mCirclePiant = new Paint(Paint.ANTI_ALIAS_FLAG);
mCirclePiant.setColor(circleColor);
mCirclePiant.setStyle(Paint.Style.STROKE);
mArrowPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mArrowPaint.setColor(arrowColor);
mArrowPaint.setStyle(Paint.Style.STROKE);
mArrowPaint.setStrokeCap(Paint.Cap.ROUND);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int measuredHeight = getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec);
int measuredWidth = getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec);
measuredSize = Math.min(measuredHeight, measuredWidth);
strokeWidth = Math.round(measuredSize * 0.05f);
mCirclePiant.setStrokeWidth(strokeWidth);
mArrowPaint.setStrokeWidth(strokeWidth);
// Make a square
setMeasuredDimension(measuredSize + strokeWidth, measuredSize + strokeWidth);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (measuredSize <= 0) {
// Not much we can draw, can we
return;
}
float center = (measuredSize + strokeWidth) * 0.5f;
canvas.drawCircle(center, center, measuredSize * 0.5f, mCirclePiant);
canvas.drawLine(center + 0.2f * measuredSize, center, center - 0.1f * measuredSize, center + 0.2f * measuredSize, mArrowPaint);
canvas.drawLine(center + 0.2f * measuredSize, center, center - 0.1f * measuredSize, center - 0.2f * measuredSize, mArrowPaint);
}
}
1920x1080p 下 50x50dp 的结果
根据 Bojan 的回答,我编辑了视图以根据触摸事件重绘并添加了 OnClickListener
部分。欢迎提出任何改进建议。
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
/**
* Created by noorul.ahmed on 5/18/2015.
*/
public class CircleRightArrow extends View {
private int viewColor;
private int backgroundColor;
private int normalColor = 0xFFF0AD4E;
private int normalBackground = 0xFFFFFFFF;
private int touchBackground = 0xFFEC971F;
private int touchColor = 0xFFFFFFFF;
private int disabledBackground = 0xFFFFFFFF;
private int disabledColor = 0xFFCECECE;
private int measuredSize;
private int strokeWidth;
private boolean touched = false;
private float startX, startY, endX, endY;
private OnClickListener listener;
private Paint mCirclePiant, mArrowPaint;
public CircleRightArrow(Context context) {
super(context);
init(context, null, 0);
setInitialColor();
}
public CircleRightArrow(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs, 0);
setInitialColor();
}
public CircleRightArrow(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs, defStyleAttr);
setInitialColor();
}
private void init(Context context, AttributeSet attributeSet, int defStyle) {
mCirclePiant = new Paint(Paint.ANTI_ALIAS_FLAG);
mCirclePiant.setColor(viewColor);
mCirclePiant.setStyle(Paint.Style.STROKE);
mArrowPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mArrowPaint.setColor(viewColor);
mArrowPaint.setStyle(Paint.Style.STROKE);
mArrowPaint.setStrokeCap(Paint.Cap.ROUND);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int measuredHeight = getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec);
int measuredWidth = getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec);
measuredSize = Math.min(measuredHeight, measuredWidth);
strokeWidth = Math.round(measuredSize * 0.025f);
mCirclePiant.setStrokeWidth(strokeWidth);
mArrowPaint.setStrokeWidth(strokeWidth);
// Make a square
setMeasuredDimension(measuredSize + strokeWidth, measuredSize + strokeWidth);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (measuredSize <= 0) {
// Not much we can draw, can we
return;
}
float center = (measuredSize + strokeWidth) * 0.5f;
canvas.drawCircle(center, center, measuredSize * 0.5f, mCirclePiant);
canvas.drawLine(center + 0.2f * measuredSize, center, center - 0.1f * measuredSize, center + 0.2f * measuredSize, mArrowPaint);
canvas.drawLine(center + 0.2f * measuredSize, center, center - 0.1f * measuredSize, center - 0.2f * measuredSize, mArrowPaint);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
boolean result = super.onTouchEvent(event);
switch (event.getAction()){
case MotionEvent.ACTION_DOWN :
touched = true;
startX = event.getX();
startY = event.getY();
togglePaintColor(event);
postInvalidate();
return true;
case MotionEvent.ACTION_UP :
endX = event.getX();
endY = event.getY();
togglePaintColor(event);
postInvalidate();
float diffX = Math.abs(startX - endX);
float diffY = Math.abs(startY - endY);
if (diffX <= 5 && diffY <= 5 && touched ) {
dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_UP,1));
}
return true;
default:
return false;
}
}
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
if(event.getAction() == KeyEvent.ACTION_UP) {
touched = false;
if(listener != null) listener.onClick(this);
}
return super.dispatchKeyEvent(event);
}
public void setListener(OnClickListener listener) {
this.listener = listener;
}
public void setInitialColor(){
if (isClickable()){
viewColor = normalColor;
backgroundColor = normalBackground;
}
else {
viewColor = disabledColor;
backgroundColor = disabledBackground;
this.listener = null;
}
mCirclePiant.setColor(viewColor);
mCirclePiant.setStyle(Paint.Style.STROKE);
mArrowPaint.setColor(viewColor);
}
@Override
public void setClickable(boolean isClickable){
super.setClickable(isClickable);
if (isClickable){
viewColor = normalColor;
backgroundColor = normalBackground;
}
else {
viewColor = disabledColor;
backgroundColor = disabledBackground;
this.listener = null;
}
mCirclePiant.setColor(viewColor);
mCirclePiant.setStyle(Paint.Style.STROKE);
mArrowPaint.setColor(viewColor);
postInvalidate();
}
private void togglePaintColor(MotionEvent event) {
if (isClickable()) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
viewColor = touchColor;
backgroundColor = touchBackground;
mCirclePiant.setColor(backgroundColor);
mCirclePiant.setStyle(Paint.Style.FILL);
mArrowPaint.setColor(viewColor);
} else if (event.getAction() == MotionEvent.ACTION_UP) {
viewColor = normalColor;
backgroundColor = normalBackground;
mCirclePiant.setColor(viewColor);
mCirclePiant.setStyle(Paint.Style.STROKE);
mArrowPaint.setColor(viewColor);
}
}
}
}
三种按钮状态是:
- 正常状态
- 按下状态
- 禁用状态