Je veux une barre de progression en demi-cercle en arrière-plan de l'image. tout comme l'image ci-dessous.
j'ai essayé de dessiner en utilisant la toile mais je n'ai pas réussi. j'ai également fatigué une bibliothèque de barre de progression personnalisée, mais le résultat est le même.
aucune suggestion.
à la recherche d'un développement unique et utilisé dans toutes les tailles d'écran.
Cela peut être mis en œuvre en découpant un canevas contenant une image à un angle (en dessinant un arc).
Vous pouvez utiliser une image quelque chose comme ça
Et découpez cette image en dessinant un arc.
Voici comment vous pouvez le faire.
//Convert the progress in range of 0 to 100 to angle in range of 0 180. Easy math.
float angle = (progress * 180) / 100;
mClippingPath.reset();
//Define a rectangle containing the image
RectF oval = new RectF(mPivotX, mPivotY, mPivotX + mBitmap.getWidth(), mPivotY + mBitmap.getHeight());
//Move the current position to center of rect
mClippingPath.moveTo(oval.centerX(), oval.centerY());
//Draw an arc from center to given angle
mClippingPath.addArc(oval, 180, angle);
//Draw a line from end of arc to center
mClippingPath.lineTo(oval.centerX(), oval.centerY());
Et une fois que vous obtenez le chemin, vous pouvez utiliser la fonction clipPath
pour découper le canevas dans ce chemin.
canvas.clipPath(mClippingPath);
Voici le code complet
SemiCircleProgressBarView.Java
import Android.app.Activity;
import Android.content.Context;
import Android.graphics.Bitmap;
import Android.graphics.BitmapFactory;
import Android.graphics.Canvas;
import Android.graphics.Path;
import Android.graphics.RectF;
import Android.util.AttributeSet;
import Android.util.DisplayMetrics;
import Android.view.View;
public class SemiCircleProgressBarView extends View {
private Path mClippingPath;
private Context mContext;
private Bitmap mBitmap;
private float mPivotX;
private float mPivotY;
public SemiCircleProgressBarView(Context context) {
super(context);
mContext = context;
initilizeImage();
}
public SemiCircleProgressBarView(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
initilizeImage();
}
private void initilizeImage() {
mClippingPath = new Path();
//Top left coordinates of image. Give appropriate values depending on the position you wnat image to be placed
mPivotX = getScreenGridUnit();
mPivotY = 0;
//Adjust the image size to support different screen sizes
Bitmap bitmap = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.circle);
int imageWidth = (int) (getScreenGridUnit() * 30);
int imageHeight = (int) (getScreenGridUnit() * 30);
mBitmap = Bitmap.createScaledBitmap(bitmap, imageWidth, imageHeight, false);
}
public void setClipping(float progress) {
//Convert the progress in range of 0 to 100 to angle in range of 0 180. Easy math.
float angle = (progress * 180) / 100;
mClippingPath.reset();
//Define a rectangle containing the image
RectF oval = new RectF(mPivotX, mPivotY, mPivotX + mBitmap.getWidth(), mPivotY + mBitmap.getHeight());
//Move the current position to center of rect
mClippingPath.moveTo(oval.centerX(), oval.centerY());
//Draw an arc from center to given angle
mClippingPath.addArc(oval, 180, angle);
//Draw a line from end of arc to center
mClippingPath.lineTo(oval.centerX(), oval.centerY());
//Redraw the canvas
invalidate();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//Clip the canvas
canvas.clipPath(mClippingPath);
canvas.drawBitmap(mBitmap, mPivotX, mPivotY, null);
}
private float getScreenGridUnit() {
DisplayMetrics metrics = new DisplayMetrics();
((Activity)mContext).getWindowManager().getDefaultDisplay().getMetrics(metrics);
return metrics.widthPixels / 32;
}
}
Et l'utiliser dans n'importe quelle activité est très facile.
activity_main.xml
<RelativeLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:tools="http://schemas.Android.com/tools"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
tools:context=".MainActivity" >
<com.example.progressbardemo.SemiCircleProgressBarView
Android:id="@+id/progress"
Android:layout_width="match_parent"
Android:layout_height="match_parent" />
</RelativeLayout>
Notez que la fonction clipPath
ne fonctionne pas si le hardware acceleration
Est activé. Vous pouvez désactiver l'accélération matérielle uniquement pour cette vue.
//Turn off hardware accleration
semiCircleProgressBarView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
MainActivity.Java
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
SemiCircleProgressBarView semiCircleProgressBarView = (SemiCircleProgressBarView) findViewById(R.id.progress);
semiCircleProgressBarView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
semiCircleProgressBarView.setClipping(70);
}
}
Au fur et à mesure que la progression change, vous pouvez définir la barre de progression en appelant la fonction,
semiCircleProgressBarView.setClipping(progress);
Ex: semiCircleProgressBarView.setClipping(50); //50% progress
semiCircleProgressBarView.setClipping(70); //70% progress
Vous pouvez utiliser votre propre image pour répondre aux exigences. J'espère que ça aide!!
Edit: Pour déplacer le demi-cercle en bas de l'écran, modifiez la valeur de mPivotY
. Quelque chose comme ça
//In `SemiCircleProgressBarView.Java`
//We don't get the canvas width and height initially, set `mPivoyY` inside `onWindowFocusChanged` since `getHeight` returns proper results by that time
public void onWindowFocusChanged(boolean hasWindowFocus) {
super.onWindowFocusChanged(hasWindowFocus);
mPivotX = getScreenGridUnit();
mPivotY = getHeight() - (mBitmap.getHeight() / 2);
}
Vous pouvez essayer SeekArc Library . Je sais que c'est un autre type de barre de recherche, mais avec une personnalisation mineure, vous pouvez l'utiliser pour votre application comme barre de progression. J'ai fait pareil. Vous avez juste besoin de changer certaines propriétés commeseekarc:touchInside="false"
.
C'est assez simple.
Maintenant, l'implémentation personnalisée sur mon application ressemble un peu à ceci:
img src: CleanMaster sur Google Play
Vous pouvez également utiliser le ProgressBar
natif pour réaliser un demi-cercle. Définissez ProgressBar
comme ceci:
<ProgressBar
Android:id="@+id/progressBar"
style="?android:attr/progressBarStyleHorizontal"
Android:layout_width="100dp"
Android:layout_height="100dp"
Android:layout_alignParentBottom="true"
Android:layout_centerHorizontal="true"
Android:max="200"
Android:progress="0"
Android:progressDrawable="@drawable/circular" />
Créez un dessin:
circular
(niveau API <21):
<shape
Android:innerRadiusRatio="2.3"
Android:shape="ring"
Android:thickness="5sp" >
<solid Android:color="@color/someColor" />
</shape>
circular
(Niveau API> = 21):
<shape
Android:useLevel="true"
Android:innerRadiusRatio="2.3"
Android:shape="ring"
Android:thickness="5sp" >
<solid Android:color="@color/someColor" />
</shape>
useLevel
est false
par défaut dans l'API niveau 21.
Maintenant que nous avons défini max = 200
, pour réaliser un demi-cercle, la plage de progression doit être 0
à 100
. Vous pouvez jouer avec ces valeurs pour obtenir la forme souhaitée.
Utilisez-le ainsi:
ProgressBar progressBar = (Progressbar) view.findViewById(R.id.progressBar);
progressBar.setProgress(value); // 0 <= value <= 100
Il s'agit d'une vue qui a une hauteur égale à la moitié de sa largeur. Utilisez les paramètres pour ajuster le comportement comme vous le souhaitez. Par défaut, la progression est 0 et la largeur de l'arc est de 20. L'appel à setProgress () invalidera la vue avec la progression donnée. L'ajout d'un arrière-plan dessinable est possible et la barre de progression sera dessinée en haut.
public class SemicircularProgressBar extends View {
private int mProgress;
private RectF mOval;
private RectF mOvalInner;
private Paint mPaintProgress;
private Paint mPaintClip;
private float ovalsDiff;
private Path clipPath;
public SemicircularProgressBar(Context context) {
super(context);
init();
}
public SemicircularProgressBar(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public SemicircularProgressBar(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
mProgress = 0;
ovalsDiff = 20;
mOval = new RectF();
mOvalInner = new RectF();
clipPath = new Path();
mPaintProgress = new Paint();
mPaintProgress.setColor(Color.GREEN);
mPaintProgress.setAntiAlias(true);
mPaintClip = new Paint();
mPaintClip.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
mPaintClip.setAlpha(0);
mPaintClip.setAntiAlias(true);
}
// call this from the code to change the progress displayed
public void setProgress(int progress) {
this.mProgress = progress;
invalidate();
}
// sets the width of the progress arc
public void setProgressBarWidth(float width) {
this.ovalsDiff = width;
invalidate();
}
// sets the color of the bar (#FF00FF00 - Green by default)
public void setProgressBarColor(int color){
this.mPaintProgress.setColor(color);
}
@Override
public void onDraw(Canvas c) {
super.onDraw(c);
mOval.set(0, 0, this.getWidth(), this.getHeight()*2);
mOvalInner.set(0+ovalsDiff, 0+ovalsDiff, this.getWidth()-ovalsDiff, this.getHeight()*2);
clipPath.addArc(mOvalInner, 180, 180);
c.clipPath(clipPath, Op.DIFFERENCE);
c.drawArc(mOval, 180, 180f * ((float) mProgress / 100), true, mPaintProgress);
}
// Setting the view to be always a rectangle with height equal to half of its width
@Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int parentWidth = MeasureSpec.getSize(widthMeasureSpec);
int parentHeight = MeasureSpec.getSize(heightMeasureSpec);
this.setMeasuredDimension(parentWidth/2, parentHeight);
ViewGroup.LayoutParams params = this.getLayoutParams();
params.width = parentWidth;
params.height = parentWidth/2;
this.setLayoutParams(params);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
Vous pouvez utiliser cette bibliothèque:
compile 'com.github.lzyzsd:circleprogress:1.1.1'
par exemple :
<com.github.lzyzsd.circleprogress.DonutProgress
Android:layout_marginLeft="50dp"
Android:id="@+id/donut_progress"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
custom:donut_progress="30"/>
<com.github.lzyzsd.circleprogress.ArcProgress
Android:id="@+id/arc_progress"
Android:background="#214193"
Android:layout_marginLeft="50dp"
Android:layout_width="100dp"
Android:layout_height="100dp"
custom:arc_progress="55"
custom:arc_bottom_text="MEMORY"/>
Pour plus d'informations, consultez le site Web suivant:
Vous pourrez peut-être utiliser ceci bibliothèque github - circularseekbar . Pour réaliser le demi-cercle, vous devrez manipuler les attributs suivants: "app: start_angle" & "app: end_angle"
Plus d'options :