Llenando un círculo gradualmente de abajo a arriba android

He creado un círculo con un movimiento y un fondo blanco usando xml. ¿Cómo se puede llenar gradualmente de abajo hacia arriba en las acciones de los usuarios (por ejemplo, en sucesivas pulsaciones de botones)? Introduzca aquí la descripción de la imagen

¿Hay alguna biblioteca gratuita que se puede utilizar para lograr algo similar?

He creado una clase de vista personalizada que hará lo que quiera. Hay cuatro atributos personalizados que se pueden configurar en su diseño xml:

  • fillColor , color – Establece el color del área de relleno. El valor predeterminado es Color.WHITE .
  • strokeColor , color – Establece el color del círculo delimitador. El valor predeterminado es Color.BLACK .
  • strokeWidth , float – Establece el grosor del círculo delimitador. El valor predeterminado es 1.0 .
  • value , entero: 0-100 – Establece el valor para el área de relleno. El valor predeterminado es 0 .

Tenga en cuenta que estos atributos deben tener el prefijo custom en lugar del prefijo de android en su xml de diseño. La View raíz también debe contener el espacio de nombres xml custom . (Consulte el ejemplo a continuación.) Los otros atributos estándar de View , como layout_width , background , etc., están disponibles.

En primer lugar, la clase CircleFillView :

 public class CircleFillView extends View { public static final int MIN_VALUE = 0; public static final int MAX_VALUE = 100; private PointF center = new PointF(); private RectF circleRect = new RectF(); private Path segment = new Path(); private Paint strokePaint = new Paint(); private Paint fillPaint = new Paint(); private int radius; private int fillColor; private int strokeColor; private float strokeWidth; private int value; public CircleFillView(Context context) { this(context, null); } public CircleFillView(Context context, AttributeSet attrs) { super(context, attrs); TypedArray a = context.getTheme().obtainStyledAttributes( attrs, R.styleable.CircleFillView, 0, 0); try { fillColor = a.getColor(R.styleable.CircleFillView_fillColor, Color.WHITE); strokeColor = a.getColor(R.styleable.CircleFillView_strokeColor, Color.BLACK); strokeWidth = a.getFloat(R.styleable.CircleFillView_strokeWidth, 1f); value = a.getInteger(R.styleable.CircleFillView_value, 0); adjustValue(value); } finally { a.recycle(); } fillPaint.setColor(fillColor); strokePaint.setColor(strokeColor); strokePaint.setStrokeWidth(strokeWidth); strokePaint.setStyle(Paint.Style.STROKE); } public void setFillColor(int fillColor) { this.fillColor = fillColor; fillPaint.setColor(fillColor); invalidate(); } public int getFillColor() { return fillColor; } public void setStrokeColor(int strokeColor) { this.strokeColor = strokeColor; strokePaint.setColor(strokeColor); invalidate(); } public int getStrokeColor() { return strokeColor; } public void setStrokeWidth(float strokeWidth) { this.strokeWidth = strokeWidth; strokePaint.setStrokeWidth(strokeWidth); invalidate(); } public float getStrokeWidth() { return strokeWidth; } public void setValue(int value) { adjustValue(value); setPaths(); invalidate(); } public int getValue() { return value; } private void adjustValue(int value) { this.value = Math.min(MAX_VALUE, Math.max(MIN_VALUE, value)); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); center.x = getWidth() / 2; center.y = getHeight() / 2; radius = Math.min(getWidth(), getHeight()) / 2 - (int) strokeWidth; circleRect.set(center.x - radius, center.y - radius, center.x + radius, center.y + radius); setPaths(); } private void setPaths() { float y = center.y + radius - (2 * radius * value / 100 - 1); float x = center.x - (float) Math.sqrt(Math.pow(radius, 2) - Math.pow(y - center.y, 2)); float angle = (float) Math.toDegrees(Math.atan((center.y - y) / (x - center.x))); float startAngle = 180 - angle; float sweepAngle = 2 * angle - 180; segment.rewind(); segment.addArc(circleRect, startAngle, sweepAngle); segment.close(); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawPath(segment, fillPaint); canvas.drawCircle(center.x, center.y, radius, strokePaint); } } 

Ahora, para que los atributos xml personalizados funcionen, necesitará colocar el siguiente archivo en la carpeta /res/values de su proyecto.

attrs.xml :

 <resources> <declare-styleable name="CircleFillView" > <attr name="fillColor" format="color" /> <attr name="strokeColor" format="color" /> <attr name="strokeWidth" format="float" /> <attr name="value" format="integer" /> </declare-styleable> </resources> 

A continuación se muestran los archivos de una aplicación de demostración simple, donde el valor de CircleFillView se controla con SeekBar .

El archivo de diseño de nuestra Activity , main.xml :

 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:custom="http://schemas.android.com/apk/res/com.example.circlefill" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center_horizontal" android:orientation="vertical" > <com.example.circlefill.CircleFillView android:id="@+id/circleFillView" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:background="#ffffff" custom:fillColor="#6bcae2" custom:strokeColor="#75b0d0" custom:strokeWidth="20" custom:value="65" /> <SeekBar android:id="@+id/seekBar" android:layout_width="match_parent" android:layout_height="wrap_content" /> </LinearLayout> 

Y, la clase MainActivity :

 public class MainActivity extends Activity { CircleFillView circleFill; SeekBar seekBar; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); circleFill = (CircleFillView) findViewById(R.id.circleFillView); seekBar = (SeekBar) findViewById(R.id.seekBar); seekBar.setProgress(circleFill.getValue()); seekBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() { @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { if (fromUser) circleFill.setValue(progress); } @Override public void onStartTrackingTouch(SeekBar seekBar) {} @Override public void onStopTrackingTouch(SeekBar seekBar) {} } ); } } 

Y una captura de pantalla de la aplicación demo:

captura de pantalla

  • Android: LinearLayout addView Animación
  • ¿Cuál es la diferencia entre los estados seleccionados, seleccionados y activados en Android?
  • ¿Cómo puedo definir el tamaño de los dibujables en el archivo de estilo?
  • Android - Cómo superponer un camino encima de otro
  • Espacio vacío cuando vuelvo a Actividad (Soft Keyboard forzado)
  • CookieSyncManager :: createInstance () necesita ser llamado antes de CookieSyncManager :: getInstance ()
  • Uso de Android AutoCompleteTextView con ArrayAdapter <Objects> en lugar de ArrayAdapter <Strings>
  • Android WebView pierde cookies en los redireccionamientos
  • ¿Lista de animaciones de la transición de la visión de androide?
  • Cambiar el comportamiento de un GridView para que se desplace horizontalmente en lugar de verticalmente
  • Cambiar el contenido de la vista de la actividad dinámicamente
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.