Android: Barre De Progression Semi-Cercle
je veux la 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 ne peux pas obtenir de succès. j'ai également fatigué certains custom progress bar library mais le résultat est le même.
n'importe quelles suggestions.
recherche de développement unique et utilisé dans toutes les tailles d'écran.
6 réponses
ceci peut être réalisé en découpant une toile contenant une image à un angle (en dessinant un arc).
Vous pouvez utiliser une image de quelque chose comme ceci
et clip 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 obtenir le chemin d'accès, vous pouvez utiliser clipPath
fonction pour couper la toile dans ce chemin.
canvas.clipPath(mClippingPath);
Voici la code
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 clipPath
ne fonctionne pas si le hardware acceleration
est activé. Vous pouvez désactiver l'accélération matérielle uniquement pour la 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);
}
}
lorsque la progression change, vous pouvez définir la barre de progression en appelant 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. Espérons que cela aide!!
Edit : pour déplacer le demi-cercle au bas de l'écran, Changez mPivotY
valeur. Quelque chose comme ceci
//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 type différent de seekbar, mais avec un peu de personnalisation, vous pouvez l'utiliser pour votre application comme une barre de progression. J'ai fait la même chose. Vous avez juste besoin de changer certaines propriétés comme seekarc:touchInside="false"
.
Son assez simple.
maintenant, l'implémentation personnalisée sur mon application ressemble un peu à ceci:
img src: CleanMaster chez Google Jouer
vous pouvez aussi utiliser native ProgressBar
pour réaliser le semi-cercle.
Définir 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éer un drawable:
circular
(niveau API < 21):
<shape
android:innerRadiusRatio="2.3"
android:shape="ring"
android:thickness="5sp" >
<solid android:color="@color/someColor" />
</shape>
circular
API (Niveau >= 21):
<shape
android:useLevel="true"
android:innerRadiusRatio="2.3"
android:shape="ring"
android:thickness="5sp" >
<solid android:color="@color/someColor" />
</shape>
useLevel
false
par défaut au niveau 21 de L'API.
Maintenant, depuis que nous avons mis en max = 200
, pour atteindre le demi cercle, la portée du progrès devrait être 0
100
. Vous pouvez jouer avec ces valeurs atteindre la forme désirée.
Donc l'utiliser comme ceci:
ProgressBar progressBar = (Progressbar) view.findViewById(R.id.progressBar);
progressBar.setProgress(value); // 0 <= value <= 100
c'est une vue qui a une hauteur égale à la moitié de sa largeur. Utiliser les opérateurs d'ajuster le comportement souhaité. Par défaut la progression est 0 et la largeur de l'arc est 20. L'appel de setProgress () invalidera la vue avec le progrès donné. L'ajout d'un fond de dessin est possible et la barre de progression sera dessinée sur le dessus.
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 pouvez être en mesure d'utiliser ce github bibliothèque - circularseekbar. Pour réaliser le demi-cercle, vous devrez manipuler les attributs suivants: "app: start_angle" & "app: end_angle"
Plus D'Options:
- Le Holo Seekbar bibliothèque
- tutoriel montrant le seekbar semi-circulaire lien vers le tutoriel