Android : 半圆形进度条 [英] Android : Semi Circle Progress Bar
问题描述
我想要图像背景中的半圆形进度条.就像下图.
I want semi circle progress bar in background of image. just like below image.
我曾尝试使用画布绘图,但无法成功.我也厌倦了一些自定义进度条库,但结果是一样的.
i have tried to draw using canvas but can't get success. i have also tired some custom progress bar library but result is same.
任何建议.
寻找一次性开发并用于各种屏幕尺寸.
looking for one time development and used in every screen size.
推荐答案
这可以通过以一定角度剪切包含图像的画布(通过绘制圆弧)来实现.
This can be implemented by clipping a canvas containing an image at an angle (By drawing an arc).
你可以使用这样的图像
然后通过绘制弧线来剪辑该图像.
And clip that image by drawing an arc.
这是您的方法.
//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());
获得路径后,您可以使用 clipPath
函数在该路径中剪切画布.
And once you get the path, you can use clipPath
function to clip the canvas in that path.
canvas.clipPath(mClippingPath);
这是完整的代码
SemiCircleProgressBarView.java
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;
}
}
在任何活动中使用它都非常容易.
And using it in any activity is very easy.
activity_main.xml
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>
请注意,如果硬件加速
打开,clipPath
功能将不起作用.您只能为该视图关闭硬件加速.
Note that clipPath
function doesn't work if the hardware acceleration
is turned on. You can turn off the hardware acceleration only for that view.
//Turn off hardware accleration
semiCircleProgressBarView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
MainActivity.java
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);
}
}
当进度发生变化时,您可以通过调用函数来设置进度条,
As and when the progress changes you can set the progressbar by calling function,
semiCircleProgressBarView.setClipping(progress);
例如:semiCircleProgressBarView.setClipping(50);//50% 进度
semiCircleProgressBarView.setClipping(70); //70% progress
您可以使用自己的图片来满足要求.希望能帮到你!!
You can use your own Image to match the requirements. Hope it helps!!
要将半圆移动到屏幕底部,请更改 mPivotY
值.像这样
Edit : To move the semi circle to bottom of the screen, change mPivotY
value. Something like this
//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);
}
这篇关于Android : 半圆形进度条的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!