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

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

问题描述

我想在图像的背景半圆形进度条。就像下面的图片。

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.

下面是你如何能做到这一点。

Here is how you can do it.

//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);

下面是完整的code

Here is the Complete code

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);
        }

这篇关于安卓:半圆形进度条的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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