Нарисуйте полукруг на фоне представления
Я пытаюсь создать TextView, чей фон представляет собой половину круга. Я создаю овал с помощью ShapeDrawable. Я попытался создать полукруг, используя ScaleDrawable, чтобы удвоить размер вертикального размера овала и кликнуть его. Однако ScaleDrawable не влияет. Почему нет? Каков наилучший способ нарисовать полукруг на фоне представления?
Рез/макет/activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<TextView
android:id="@+id/main_view"
android:background="@drawable/semicircle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:gravity="center_horizontal"
/>
</RelativeLayout>
Рез/вытяжка/semicircle.xml
<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/circle"
android:scaleGravity="top|clip_vertical"
android:scaleHeight="200%"
android:scaleWidth="100%" >
</scale>
Рез/вытяжка/circle.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval"
<solid
android:color="#444" />
</shape>
SRC/.../MainActivity.java
//...
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
findViewById(R.id.main_view).getBackground().setLevel(10000);
}
//...
Ответы
Ответ 1
Вы можете реализовать свой собственный Drawable. Но это не может быть завышено из XML. Вам нужно установить рисование из кода, используя View.setBackgroundDrawable();
Смотрите мой пример реализации, чтобы нарисовать полукруг, используя drawable.
public class SemiCircleDrawable extends Drawable {
private Paint paint;
private RectF rectF;
private int color;
private Direction angle;
public enum Direction
{
LEFT,
RIGHT,
TOP,
BOTTOM
}
public SemiCircleDrawable() {
this(Color.BLUE, Direction.LEFT);
}
public SemiCircleDrawable(int color, Direction angle) {
this.color = color;
this.angle = angle;
paint = new Paint();
paint.setColor(color);
paint.setStyle(Style.FILL);
paint.setAntiAlias(true);
rectF = new RectF();
}
public int getColor() {
return color;
}
/**
* A 32bit color not a color resources.
* @param color
*/
public void setColor(int color) {
this.color = color;
paint.setColor(color);
}
@Override
public void draw(Canvas canvas) {
canvas.save();
Rect bounds = getBounds();
if(angle == Direction.LEFT || angle == Direction.RIGHT)
{
canvas.scale(2, 1);
if(angle == Direction.RIGHT)
{
canvas.translate(-(bounds.right / 2), 0);
}
}
else
{
canvas.scale(1, 2);
if(angle == Direction.BOTTOM)
{
canvas.translate(0, -(bounds.bottom / 2));
}
}
rectF.set(bounds);
if(angle == Direction.LEFT)
canvas.drawArc(rectF, 90, 180, true, paint);
else if(angle == Direction.TOP)
canvas.drawArc(rectF, -180, 180, true, paint);
else if(angle == Direction.RIGHT)
canvas.drawArc(rectF, 270, 180, true, paint);
else if(angle == Direction.BOTTOM)
canvas.drawArc(rectF, 0, 180, true, paint);
canvas.restore()
}
@Override
public void setAlpha(int alpha) {
// Has no effect
}
@Override
public void setColorFilter(ColorFilter cf) {
// Has no effect
}
@Override
public int getOpacity() {
// Not Implemented
return PixelFormat.UNKNOWN;
}
}
Ответ 2
Чтобы скопировать овальную форму, просто вставьте ее в ClipDrawable следующим образом:
Рез/рисуем/semicircle.xml
<?xml version="1.0" encoding="utf-8"?>
<clip
xmlns:android="http://schemas.android.com/apk/res/android"
android:clipOrientation="vertical"
android:gravity="bottom">
<shape android:shape="oval">
<solid android:color="#444"/>
</shape>
</clip>
ClipDdrawable
общей целью является создание пользовательских индикаторов выполнения. Он зажимает часть своего содержимого и постепенно отображает его, когда его свойство "уровня" увеличивается в диапазоне [0; 10000] (0 = скрыто, 10000 = полностью отображается).
-
clipOrientation
- это ориентация хода отсечения.
-
gravity
- начальный край/сторона запуска клипа.
Чтобы получить половину круга, установите этот ClipDrawable
в качестве фона вашего представления и программно настройте его "уровень":
//...
findViewById(R.id.my_view).getBackground().setLevel(5000)
//...
Работает со всеми версиями Android ( "Добавлен в уровень API 1" ) и не требует пользовательского представления.
; -)
Ответ 3
Я сделал этот класс надежду, что он вам поможет, все переменные находятся на испанском языке, но его довольно просто,
конструктор SemiCirculo использует в качестве параметров rgb для полуокружности и разрешения (количество треугольников для вашего полукруга)
Метод CalcularPuntosPorcentaje использует в качестве параметров центр круга, начальный угол, ширину угла и радио.
метод ImprimeCirculo использует параметр canvas как параметр, он используется для рисования полукруга, как только он уже был вычислен точками полукруга с использованием указанного выше метода.
Метод CalcularPuntosPorcentaje аналогичен методу CalcularPuntosPorcentaje, но при настройке параметров начального и вертикального углов он использует% от 0 до 100
finaly SetOffset и SetColor используются для изменения начального позиционирования по умолчанию o ссылки для угла и цвета полукруг
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
public class SemiCirculo {
private Path circulo;
private Paint color;
private float px, py, radio, anguloI, anchoa,offset;
private int r, g, b;
private int resolucion;
private float puntox[],puntoy[];
public SemiCirculo(int r1, int g1, int b1, int resolucion1) {
this.offset = 0;
this.color = new Paint();
this.r = r1;
this.g = g1;
this.b = b1;
this.color.setColor(Color.rgb(r, g, b));
color.setAntiAlias(true);
circulo = new Path();
this.resolucion = resolucion1;
this.puntox = new float[this.resolucion];
this.puntoy = new float[this.resolucion];
this.anguloI = 0;
this.anchoa = 1;
}
public void SetOffset(float off) {
this.offset = off;
}
public void SetColor(int r1,int g1, int b1){
this.r=r1;
this.g=g1;
this.b=b1;
this.color.setColor(Color.rgb(r, g, b));
}
public void CalcularPuntosPorcentaje(float px1, float py1,
float porcentaje, float radio1) {
this.anguloI = 0 + this.offset;
this.px = px1;
this.py = py1;
this.radio = radio1;
this.anguloI = 0;
this.anchoa = porcentaje / 100 * 360;
this.CalcularPuntos(px, py, anguloI, anchoa, radio);
}
public void CalcularPuntos(float px1, float py1, float anguloI1,
float anchoangulo, float radio1) {
this.anguloI = anguloI1 + this.offset;
this.anchoa = anchoangulo;
this.px = px1;
this.py = py1;
this.radio = radio1 ;
float angulo = 360 - this.anguloI - this.anchoa;
for (int i = 0; i < resolucion; i++) {
this.puntox[i] = this.px - (float) Math.sin(Math.toRadians(angulo))
* this.radio;
this.puntoy[i] = this.py - (float) Math.cos(Math.toRadians(angulo))
* this.radio;
angulo = (360 - this.anguloI - this.anchoa)
+ ((this.anchoa / (float) (this.resolucion)) * (i + 2));
}
this.circulo.reset();
this.circulo.moveTo(this.px, this.py);
for (int i = 0; i < resolucion; i++) {
this.circulo.lineTo(this.puntox[i], this.puntoy[i]);
}
}
public void ImprimeCirculo(Canvas canvas) {
canvas.drawPath(this.circulo, this.color);
}
}
Ответ 4
вместо этого вы можете использовать изображение для установки в качестве фона...
1 > создайте любое изображение, используя краску, и сохраните его в любом поддерживаемом формате, например .jpg или .png. Это будет ваше изображение с полукругом, который вы хотите.
2 > сохранить изображение в папке res/drawable
3 > установите для фона вашего текста текст с помощью android:background="@drawable/yourimage.jpg"
надеюсь, что это поможет...