android - Programmatically refresh (draw, erase, and update) shapes on custom View in background asynchoronously wihtout blocking the UI

StackOverflow https://stackoverflow.com/questions/11728212

Question

Below is the CustomView class extending the View class. It works good statically.

I am clicking a button, it shows the targeted shelf, which I am headed to. Then I am clicking another button, it clears the targeted shelf and the map is back in its initial state.

What needs to be done is, this baby has to clear the targeted shelf by itself using some async calls, after xx seconds. And in the same fashion, when I begin to show my position on the map with an "X", it has to refresh that "X" while I am walking.

The AsyncTask doesn't seem to be the perfect solution for this. Do you have an idea on how the map should update itself?

Thanks in advance.

The CustomView:

public class CustomView extends View {
    ShapeDrawable roomFrame, targetShelfFrame, me;
    int halfMe;
    ArrayList<ShapeDrawable> shelfFrames;
    //(...)

    @Override
    protected void onDraw(Canvas canvas){
        super.onDraw(canvas);
        if(roomFrame != null)
            roomFrame.draw(canvas);
        for (ShapeDrawable shelfFrame : shelfFrames)
            shelfFrame.draw(canvas);
        if(targetShelfFrame != null)
            targetShelfFrame.draw(canvas);
        if(me != null)
            me.draw(canvas);
    }

    public void setRoom(Room room){
        roomFrame = new ShapeDrawable(new RectShape());
        roomFrame.getPaint().setColor(0xff74AC23);
        roomFrame.getPaint().setStyle(Style.STROKE);
        roomFrame.setBounds(10, 10, room.getWidth(), room.getHeight());
        invalidate();
    }

    public void setShelves(ArrayList<Shelf> shelves){
        shelfFrames = new ArrayList<ShapeDrawable>();
        for(int i = 0; i<shelves.size(); i++){
            ShapeDrawable shelfFrame = new ShapeDrawable(new RectShape());
            shelfFrame.getPaint().setColor(0xff74AC23);
            shelfFrame.setBounds(shelves.get(i).getXPosition(), shelves.get(i).getYPosition(), shelves.get(i).getWidth(), shelves.get(i).getHeight());
            shelfFrames.add(shelfFrame);
        }
        invalidate();
    }

    public void setTargetShelf(Shelf shelf){
        targetShelfFrame = new ShapeDrawable(new RectShape());
        targetShelfFrame.getPaint().setColor(Color.RED);
        targetShelfFrame.setBounds((int)(shelf.getXPosition()), (int)(shelf.getYPosition()),
                (int)((shelf.getXPosition() + shelf.getWidth())), 
                (int)((shelf.getYPosition() + shelf.getHeight())));
        invalidate();
    }

    public void clearTargetShelf(){
        targetShelfFrame = null;
        invalidate();
    }

    public void updateMyPosition(Position position){
        me = new ShapeDrawable(new OvalShape());
        me.getPaint().setColor(Color.GREEN);
        me.setBounds(position.getX() - halfMe, position.getY() - halfMe, 
            position.getX() + halfMe, position.getY() + halfMe);
    }
}

How I call it:

public void loadRoomPlan(Room room, ArrayList<Shelf> shelves){
    CustomView exampleView = (CustomView)findViewById(R.id.roomplan);
    exampleView.setRoom(room);
    exampleView.setShelves(shelves);
}
Était-ce utile?

La solution

Actually, the easiest way (as far as I understand your goals) to solve your problem is to use Handler to perform a delayed execution on a UI thread. So what you need to do is:

  • Create Handler (globally for your custom view)
  • use postDelayed(Runnable, long) interface to run your shelf clean-up with certain delay

Your code would look like:

The CustomView:

public class CustomView extends View {
    ShapeDrawable roomFrame, targetShelfFrame;
    ArrayList<ShapeDrawable> shelfFrames;
    Handler uiThread = new Handler();
    //(...)

    public void setTargetShelf(final Shelf shelf){
        targetShelfFrame = new ShapeDrawable(new RectShape());
        targetShelfFrame.getPaint().setColor(Color.RED);
        targetShelfFrame.setBounds((int)(shelf.getXPosition()), (int)(shelf.getYPosition()),
            (int)((shelf.getXPosition() + shelf.getWidth())), 
            (int)((shelf.getYPosition() + shelf.getHeight())));
        invalidate();
        uiThread.postDelayed(new Runnable()
        {
            @Override
            public void run()
            {
                clearTargetShelf(shelf);            
            }
        }, 10000); //10 secs delay
}

Regarding the second part of your question (with walking 'X' on a map) I didn't quite understand - what type of map are you using? Is it google map? Is it your own map? What does 'walking' mean? Is it real movement, or just some sort of game where you can move your character on the map? Please clarify

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top