CBeTJlu4ok
CBeTJlu4ok

Reputation: 1112

Android access canvas from different class

I need to access canvas I created from another class.

So I have a class which extends LinearLayout drawing arc.

Now from main activity I need to access this canvas it is drawn on and redraw it. Ideally only some parts of it.

Here are some codes stripped to main.

ArchProgressBar.java (the one with canvas)

public class ArchProgressBar extends LinearLayout {

    public ArchProgressBar(Context context, AttributeSet attrs) {

    private void init(Context context) {
        this.setWillNotDraw(false);
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        inflater.inflate(R.layout.arch_progress_bar, this, true);
        this.postInvalidate();
    }

    static void drawMeCircle(int aka) {

    }

    @Override
    public void onDraw(Canvas canvas) {

        int mPaintHex = 0xFFFFFFFF;
        int mPaintColor = Color.argb(100, Color.red(mPaintHex), Color.green(mPaintHex), Color.blue(mPaintHex));

        float left = 295;
        float top = 712;
        float right = 788;
        float bottom = 1208;

        Paint mPaintBackground = new Paint();
        mPaintBackground.setAntiAlias(true);
        mPaintBackground.setStyle(Paint.Style.STROKE);
        mPaintBackground.setStrokeWidth(13);
        mPaintBackground.setColor(mPaintColor);

        RectF mRectF = new RectF(left, top, right, bottom);

        // THIS IS BACKGROUND LINE! draw background line
        canvas.drawArc(mRectF, START_ANGLE, ARCH_LENGTH, false, mPaintBackground);

        int mHourHex = 0xFF00FF00;
        int mHourColor = Color.argb(255, Color.red(mHourHex), Color.green(mHourHex), Color.blue(mHourHex));

        Paint mPaintHours = new Paint();
        mPaintHours.setAntiAlias(true);
        mPaintHours.setStyle(Paint.Style.STROKE);
        mPaintHours.setStrokeWidth(13);
        mPaintHours.setColor(mHourColor);

        RectF mRectH = new RectF(left, top, right, bottom);

        // THIS IS HOUR LINE!draw hour line
        Calendar hCal = Calendar.getInstance();
        int hHour = hCal.get(Calendar.HOUR);
        if(hHour != 0) {
            for(int i=0; i<hHour-1; i++){
                canvas.drawArc(mRectH, START_ANGLE + ARCH_LENGTH + (i*30) +2, ARCH_LENGTH, false, mPaintHours);
            }
        }
    }

HomeActivity.java main activity for app (extends Activity)

public class HomeActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_home);

        IntentFilter mIntentFilter = new IntentFilter();
        mIntentFilter.addAction(Intent.ACTION_TIME_TICK);
        mIntentFilter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
        mIntentFilter.addAction(Intent.ACTION_TIME_CHANGED);
        registerReceiver(m_timeChangedReceiver, mIntentFilter);
    }
    //clock thing start
    private final BroadcastReceiver m_timeChangedReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            final String action = intent.getAction();
                Calendar hCal = Calendar.getInstance();
                int hHour = hCal.get(Calendar.HOUR);
                ArchProgressBar.drawMeCircle(1);
        }
    };

    public void showApps(View v){
        Intent i = new Intent(this, AppsListActivity.class);
        startActivity(i);
    }
}

now When BroadcastRecieved is triggered I want to access ArchProgressBar's canvas, delete the hour line (or whole thing if not possible to delete just that part) and redraw something new on it.

if you are wandering whats with drawMeCircle. It is just something I was playing with. included to show how I think it must work.

Upvotes: 0

Views: 579

Answers (1)

Mimmo Grottoli
Mimmo Grottoli

Reputation: 5773

You just need to change some value inside your view object and call invalidate() to get what you need. This will redraw the canvas as soon as it can. About your code I'd suggest to modify it in this way (let's suppose that your view has an id = @+id/arch_progress_bar)

HomeActivity

private final BroadcastReceiver m_timeChangedReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        final String action = intent.getAction();
        Calendar hCal = Calendar.getInstance();
        int hHour = hCal.get(Calendar.HOUR);
        ArchProgressBar bar = (ArchProgressBar) findViewById(R.id.arch_progress_bar);
        if (bar != null) {
            bar.drawMeCircle(1);
        }
    }
};

// remember to unregister the broadcast receiver in your onDestroy()
// as further optimization, you can also move the findViewById inside your onCreate(), so you don't have to repeat it for every broadcast you get

ArchProgressBar

pubic void drawMeCircle(int aka) {
     // your business logic
     invalidate();
}   // Remove the static keyword, it's not necessary

Last consideration: you should take care of activity recreation because of display rotation. To manage this case, you should save the value you got from the broadcast receiver (1 in this example?) during onSaveInstanceState() activity callback, retrieve it via the bundle you get as onCreate parameter and set it again to your view.

Upvotes: 1

Related Questions