Android : 半圆形进度条 [英] Android : Semi Circle Progress Bar

查看:65
本文介绍了Android : 半圆形进度条的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想要图像背景中的半圆形进度条.就像下图.

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆