Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scrolling over large canvas

I need some help understanding the fundamentals of scrolling over items that are drawn to a canvas in Android. Suppose I want to create a timeline where time at 0 is the top of a visualization and as time increased the timeline continues to be rendered below the previous point. If I wish to render this on Android I know I could simply create a bunch of items on a canvas by overriding onDraw(). However, let's suppose the visualization is bigger than the screen allows.

For example in the first picture below the large black box contains the entire canvas as I render it. I create a blue line that runs vertically up and down as well as several yellow, green and blue rectangles. The red box represents the screen of the Android that is rendering the visualization. As it initially opens all items are drawn but only the items contained within the red box show up on the screen.

Before_Scroll

Now if the user is to scroll down, items that initially appeared below the red box are in view while items that have gone out of the confines of the red box are no longer visable, as represented in the second picture.

After_Scroll

I believe I need to use scrollables but I'm quite lost how to do so. I've read over this page http://developer.android.com/training/custom-views/custom-drawing.html explaining how to create your own customer images and this page http://developer.android.com/training/custom-views/making-interactive.html explaining how to make the UI interactive, but I think I'm missing something.

A sample code that illustrates this problem (this is basic, assume there is logic dictating WHERE the boxes/lines go, etc.) is as follows:

package com.example.scrolltest;

import com.example.scrolltest.Draw;

import android.os.Bundle;
import android.app.Activity;
import android.graphics.Color;

public class MainActivity extends Activity {
    Draw draw;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

    draw = new Draw(this);
    draw.setBackgroundColor(Color.WHITE);
    setContentView(draw);
    }
}

and

package com.example.scrolltest;


import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.view.View;


public class Draw extends View {
    Paint paint = new Paint();

    public Draw(Context context) {
        super(context);            
    }

    @Override
    public void onDraw(Canvas canvas) {

        paint.setColor(Color.GREEN);
        canvas.drawRect(30, 30, 90, 200, paint);
        paint.setColor(Color.BLUE);

        canvas.drawLine(100, 20, 100, 1900, paint);

        paint.setColor(Color.GREEN);
        canvas.drawRect(200, 2000, 400, 3000, paint);
        }
}

What I cannot figure out though, is how I use a scrollable to scroll down to the rectangles that are off of the screen. I'm also unsure if I started this correctly or should use drawables instead...

like image 571
WildBill Avatar asked Apr 09 '13 03:04

WildBill


1 Answers

Simple Method (If the height required is not very large).

Use a ScrollView and add your Draw view in it. Compute the required height for that view in onMeasure.

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

draw = new Draw(this);
draw.setBackgroundColor(Color.WHITE);
ScrollView scrollView = new ScrollView(this);
scrollView.addView(draw);
setContentView(scrollView);
}

public class Draw extends View {
        Paint paint = new Paint();

        public Draw(Context context) {
            super(context);            
        }

        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            // Compute the height required to render the view
            // Assume Width will always be MATCH_PARENT.
            int width = MeasureSpec.getSize(widthMeasureSpec);
            int height = 3000 + 50; // Since 3000 is bottom of last Rect to be drawn added and 50 for padding.
            setMeasuredDimension(width, height);
        }

        @Override
        public void onDraw(Canvas canvas) {

            paint.setColor(Color.GREEN);
            canvas.drawRect(30, 30, 90, 200, paint);
            paint.setColor(Color.BLUE);

            canvas.drawLine(100, 20, 100, 1900, paint);

            paint.setColor(Color.GREEN);
            canvas.drawRect(200, 2000, 400, 3000, paint);
            }
    }
like image 79
Vivek Khandelwal Avatar answered Oct 26 '22 23:10

Vivek Khandelwal