0

I realized a custom progress bar, and to do that I have extended a View. This progress bar is filled in base of some value received from a thread, moreover this view also contains a vertical line that change position related to pression button, a counter that indicate the position of the vertical line. And the shape of progress bar is a triangle rectangle.

In my extendev view I implemented this method :

public void setPowerBar(int Power)
    {
        pbIndex = 0;


        invalidate();
        requestLayout();

    }

this is the ondraw :

@Override
public void onDraw(Canvas canvas)
{
    super.onDraw(canvas);
    canvas.drawColor(Color.TRANSPARENT);

    int width = ((pbIndex-20) * pb_i[0].getScaledWidth(canvas.getDensity())) / 180;
    int height = pb_i[0].getScaledHeight(canvas.getDensity())-(((pbIndex-20) * pb_i[0].getScaledHeight(canvas.getDensity())) / 180);

    dst.set(0, height, width, pb_i[0].getScaledHeight(canvas));

    canvas.drawBitmap(pb_i[0], 0, 0, null);

    canvas.drawBitmap(pb_i[1],null,dst,null);



    float dim = (pb_i[0].getScaledWidth(canvas.getDensity()));
    float step = dim/180;
    float xPos = ((orangePower-20)*step);

    canvas.drawLine(xPos, 0, xPos, pb_i[0].getScaledHeight(canvas), paintLine);

    canvas.drawText("" + orangePower, (dim / 2), pb_i[0].getScaledHeight(canvas), textPaint);

}

where

  • pbIndex is the power
  • pb_i[0] is the background image

This is the result : enter image description here

Can you help me to improve my implementation ?

Problem list:

  1. I have to optimize the code with @pskink suggestion.

  2. I want to add some animator, because I want much fluidity

  3. The ram consumption

  4. The vertical line appears different on different device.

        paintLine = new Paint();
        paintLine.setColor(Color.parseColor("#FD8F40"));
        paintLine.setAntiAlias(true);
        paintLine.setStrokeWidth(7);
    

In particular the stroke width appears different


Second implementation : in my layout xml I insert this :

 <com.example.canvastest.PowerBar
                android:id="@+id/power_bar"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:max="200"
                android:progress="0"
                style="?android:attr/progressBarStyleHorizontal"
                android:maxHeight="12dip"
                android:minHeight="12dip"
                />

Then I add this drawable :

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
    <item android:id="@android:id/background">
        <clip>
            <bitmap android:src="@drawable/pb_0" />
        </clip>
    </item>
    <item android:id="@android:id/progress">
        <clip>
            <bitmap android:src="@drawable/pb_100" />
        </clip>
    </item>
</layer-list>

Then I extend progressbar and its ondraw method :

@Override
    public synchronized void onDraw(Canvas canvas)
    {
        super.onDraw(canvas);
        float dim = (canvas.getWidth());
        float step = dim/180;
        float xPos = ((orangePower-20)*step);

        canvas.drawLine(xPos, 0, xPos, canvas.getHeight(), paintLine);

        canvas.drawText("" + orangePower, (dim / 2),canvas.getHeight(), textPaint);
    }

But I have two problems :

1- when the progress is 20 the progress bar must be empty 2- the background is white and not the @drawable/pb_0 3- I have to insert some animator inside ondraw method


aeroxr1
  • 1,014
  • 1
  • 14
  • 36
  • 1
    why dont you use a normal `ProgressBar` view? – pskink Sep 26 '15 at 17:20
  • @pskink Hi :) Because this progress bar also contains a vertical line that change position related to a button pression, a counter that indicate the position of the vertical line. And the shape of progress bar is a triangle rectangle. I add some more information in the first post :) – aeroxr1 Sep 26 '15 at 17:32
  • 1
    so no need for a custom View, use custom progress Drawable (`ProgressBar#setProgressDrawable`) – pskink Sep 26 '15 at 17:33
  • it's all day that I try to find how can I customize the progressbar to obtain the same result, but i can't.. @pskink : So i need to extend progressbar, right ? – aeroxr1 Sep 26 '15 at 17:41
  • 1
    no you should use `ProgressBar#setProgressDrawable` with your custom `Drawable`: `A Drawable is a general abstraction for "something that can be drawn."` a sample implementation [here](http://stackoverflow.com/a/30873744/2252830) – pskink Sep 26 '15 at 17:43
  • But if I don't extend the progressbar how can I add the text and the vertical orange line ? I have to add the handle of it to the drawable ? :) – aeroxr1 Sep 26 '15 at 17:50
  • 1
    have you seen the link i posted? – pskink Sep 26 '15 at 17:50
  • No, i'm reading now :) – aeroxr1 Sep 26 '15 at 17:51
  • An ulterior question : when should I extend a View ? – aeroxr1 Sep 26 '15 at 17:55
  • 1
    when you need some custom actions, not for drawing progress bar (or drawing whatever which cannot be drawn by a Drawable) – pskink Sep 26 '15 at 17:58
  • ok, and why not extend progress bar ? :D For example : http://stackoverflow.com/questions/8929062/how-to-make-a-custom-progressbar-in-android . I know i'm boring but I think that I can learn much from you. You are very clear :) Thanks a lot ! P.s : are there some book on that argoument ? – aeroxr1 Sep 26 '15 at 18:06
  • i see you are stubborn: ok you can extend `ProgressBar` but `setProgressDrawable` is for some purpose, it is not a mistake they wrote it – pskink Sep 26 '15 at 18:09
  • no I only ask :) In reality I was trying to extend drawable, I have to implement in it the function to move the vertical line and change test, and I think that I have to load two drawable : empty and full progress bar. I'm studyng the answer in the link that you have posted before :) – aeroxr1 Sep 26 '15 at 18:22
  • My first progress bar use 40mb of ram and the consumption grows :/ now I have some problem to add all function to the drawable and to add to it image from the resources .. Tomorrow I tell to you what I do :) – aeroxr1 Sep 26 '15 at 19:56
  • 40mb of ram? you mean 40 kb? – pskink Sep 26 '15 at 20:04
  • I test the above progress bar in an simple application : 1 activity, 1 thread that generate 30hz data and setprogress bar, two buttons one for increment the orange vertical line position and one to decrement. And the ram amount was 40mb – aeroxr1 Sep 27 '15 at 00:49
  • @pskink Hi :) I have edited the first post and ondraw methof of my custom view. Now I want to report the above behaviour in an drawable or in a custom progress bar.. But I don't understand in what way can I do :( – aeroxr1 Sep 27 '15 at 14:49
  • i have no idea: what is 40? 40 what? what is blue triangle and what is orange vertical line? – pskink Sep 27 '15 at 14:53
  • This progress bar is filled in base of some value received from a thread, moreover this view also contains a vertical line that change position related to pression button, a counter that indicate the position of the vertical line. And the shape of progress bar is a triangle rectangle – aeroxr1 Sep 27 '15 at 15:16
  • @pskink I did some edit in my code, and now I use some yours suggestion. But I also have some problems. – aeroxr1 Sep 27 '15 at 15:49
  • 1
    see [this](http://codeshare.io/I6pgl) – pskink Sep 27 '15 at 15:50
  • thanks :) But one question : in what way can I change the "orangePower" variable ? If I implement a setter method inside class D in what way can I call this from my activity ? – aeroxr1 Sep 27 '15 at 16:03
  • 1
    just call drawable.setOrangePower(xxx) – pskink Sep 27 '15 at 16:04
  • oh wonderful :) I continue to study your code, is much clear than mine :D – aeroxr1 Sep 27 '15 at 16:14

1 Answers1

1

Please check another drawBitmap method of canvas here.

For instance:

@Override
public void onDraw(Canvas canvas)
{
    super.onDraw(canvas);
    canvas.drawColor(Color.TRANSPARENT);
    // VIEW_WIDTH & VIEW_HEIGHT is the size of your progress bar, MAX_POWER is the max value of the Power
    int width = (Power * VIEW_WIDTH) / MAX_POWER;
    Rect dst = new Rect(0, 0, width, VIEW_HEIGHT);
    // only need one bitmap
    canvas.drawBitmap(pb_i[10], null, 0, null);
}
Hong Duan
  • 4,234
  • 2
  • 27
  • 50
  • if I use drawBitmap (Bitmap bitmap, Rect src, Rect dst, Paint paint), bitmap is the full progress bar (is a triangle rectangle png), but if I set the dst the image will be stretched ? I want to show background png (empty progress bar) and only part of full png . – aeroxr1 Sep 26 '15 at 17:19
  • 1
    You can specify the `Rect src` (The subset of the bitmap to be drawn) if possible. – Hong Duan Sep 26 '15 at 17:24
  • I update the first post, and I'm trying to use "another drawBitmap method of canvas" – aeroxr1 Sep 27 '15 at 09:00
  • Why not to calculate the `Rect dst` based on the `Power`? – Hong Duan Sep 27 '15 at 09:14
  • Now i'm doing in this way int width = (pbIndex * pb_i[0].getScaledWidth(canvas.getDensity())) / 300; int height = pb_i[0].getScaledHeight(canvas.getDensity())-((pbIndex * pb_i[0].getScaledHeight(canvas.getDensity())) / 300); dst.set(0, height, width, pb_i[0].getScaledHeight(canvas)); pbIndex is the power pb_i[0] is the background image – aeroxr1 Sep 27 '15 at 09:23
  • with code at my "EDIT5" inside first post the progress bar load itself in base of the power. Now I have to change : the progress bar have to start from 20 and not from 0; I have to optimize the code with @pskink suggestion. – aeroxr1 Sep 27 '15 at 09:33
  • 1
    OK, go ahead. If you want the progress bar start from 20, just modify the Rect as needed. – Hong Duan Sep 27 '15 at 09:40
  • I edited my first post :) Now is much clear :) Thanks a lot for the help :) – aeroxr1 Sep 27 '15 at 14:32