-1

I am trying to implement a custom view inside of a HorizontalScrollView parent. The custom view repeatedly draws a line to its Canvas based on timing from a Handler. Right now the custom view fills the width of the screen (limited by 548dp height) and I want the line to be able to extend beyond what is visible. Furthermore, I want to allow the user to then be able to horizontally scroll to see more of the line. I tried to set the width of the HorizontalScrollView to 1500dp (which is much larger than the width of the screen) and then I tried to scroll horizontal, but it didn't move. It would also be ideal if the view would scroll with the line as it grew past the visible part of the screen.

I am developing on an ASUS Transformer with Honeycomb.

Here's the relevant part of the layout I'm using:

<HorizontalScrollView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="1500dp"
    android:layout_height="548dp"
    android:fillViewport="true" >

    <maavapp.layout.CustomDraw
        android:id="@+id/custom_draw"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" >
    </maavapp.layout.CustomDraw>
</HorizontalScrollView>

And here is the code for the CustomDraw class:

public class CustomDraw extends View {
private static int mSelected;
private ArrayList<Coordinate> measure1;
private ArrayList<Coordinate> measure2;
private ArrayList<Coordinate> measure3;
private boolean north = false, east = true, south = true, west = false;
private DrawHandler dh = new DrawHandler();
private boolean draw = true;
private int width;
private int height;
private int m2;

public CustomDraw(Context context) {
    super(context);
    init();

}

public CustomDraw(Context context, AttributeSet attrs) {
    super(context, attrs);
    init();
}

public CustomDraw(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    init();
}

public void init() {        
    measure1 = new ArrayList<Coordinate>();
    measure2 = new ArrayList<Coordinate>();
    measure3 = new ArrayList<Coordinate>();

    mSelected = Constants.MEASURE_1;
    width = 0;
    height = 0;
    m2 = 0;
}

public void setMeasure(int measure) {
    mSelected = measure;
}

public void toggleDraw() {
    draw = !draw;
    if(draw) {
        updateLine();
    }
}

public boolean isDrawing() {
    return draw;
}

public void updateLine() {
    // grab new coordinates for each measure
    /*new_coord(measure1);
    new_coord(measure2);
    new_coord(measure3);*/

    if(measure1.isEmpty() && measure2.isEmpty() && measure3.isEmpty()) {
        measure1.add(new Coordinate(0, 0));
        measure2.add(new Coordinate(0, 0));
        measure3.add(new Coordinate(0, 0));
    } else {
        Coordinate last_coord = measure1.get(measure1.size() - 1);

        measure2.add(new Coordinate(++m2, 25));

        /*if(last_coord.x >= width) {
            east = false;
            west = true;
        } else if(last_coord.x <= 0) {
            east = true;
            west = false;
        }*/

        if(last_coord.y >= height) {
            south = false;
            north = true;
        } else if(last_coord.y <= 0) {
            south = true;
            north = false;
        }

        Log.d("MAAV", "last_coord.x + 3: " + (last_coord.x + 3));
        Log.d("MAAV", "last_coord.y + 3: " + (last_coord.y + 3));

        if(south && east) {
            measure1.add(new Coordinate(last_coord.x + 3, last_coord.y + 3));
        } else if(south && west) {
            measure1.add(new Coordinate(last_coord.x - 3, last_coord.y + 3));
        } else if(north && east) {
            measure1.add(new Coordinate(last_coord.x + 3, last_coord.y - 3));
        } else if(north && west) {
            measure1.add(new Coordinate(last_coord.x - 3, last_coord.y - 3));
        }
    }

    if(draw) {
        dh.sleep(10);
    }
}

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    this.width = w;
    this.height = h;
    super.onSizeChanged(w, h, oldw, oldh);
}

@Override
public void onDraw(Canvas c) {
    super.onDraw(c);
    Paint p = new Paint();
    p.setStyle(Paint.Style.FILL);

    p.setColor(Color.WHITE);
    c.drawPaint(p);
    p.setColor(Color.BLACK);

    switch(mSelected) {
    case Constants.MEASURE_1:
        for(int i = 0; i < measure1.size(); i++) {
            Coordinate coord = measure1.get(i);
            Log.d("MAAV", "drawing coord.x, coord.y: " + (coord.x) + ", " + (coord.y));
            c.drawRect(coord.x, coord.y, coord.x + 3, coord.y + 3, p);  
        }
        break;
    case Constants.MEASURE_2:
        for(int i = 0; i < measure2.size(); i++) {
            Coordinate coord = measure2.get(i);
            c.drawRect(coord.x, coord.y, coord.x + 3, coord.y + 3, p);
        }
        break;
    case Constants.MEASURE_3:
        for(int i = 0; i < measure2.size(); i++) {
            Coordinate coord = measure2.get(i);
            c.drawRect(coord.x, coord.y, coord.x + 3, coord.y + 3, p);
        }
        break;
    }

}

class DrawHandler extends Handler {

    @Override
    public void handleMessage(Message msg) {
        CustomDraw.this.updateLine();
        CustomDraw.this.invalidate();
    }

    public void sleep(long delayMillis) {
        this.removeMessages(0);
        sendMessageDelayed(obtainMessage(0), delayMillis);
    }
}
}

Thanks for any help!

Jon Rubins
  • 4,323
  • 9
  • 32
  • 51
  • -1 for asking same question twice that too with in half an hour...http://stackoverflow.com/questions/10214244/horizontal-scroll-view-with-custom-view-child – Shankar Agarwal Apr 18 '12 at 17:30
  • Again, I explained to you that it's a different question. Also, because I accepted the other question, I didn't want to lose interest in the new question by simply editing the old one. – Jon Rubins Apr 18 '12 at 17:41
  • Thanks for being unproductive though and only focusing on the fact that I asked a similar question instead of actually realizing that I'm asking for help and would rather have an answer than useless comments. I feel that -1 should be for questions that display no lack of outside research or effort put in, which I think I have done. I would ask you to think about the real point of why you -1 something and how it actually contributes. – Jon Rubins Apr 18 '12 at 17:45

1 Answers1

0

For anyone that's curious, I figured out the answer for my situation. Hopefully what I outline below could be helpful to you too.

In order to get the custom View to scroll, I had to add a LinearLayout wrapper around my custom View. Not 100% sure why.

Also, though I declare a fixed size for my custom View (in the xml file below), I'm able to update it dynamically in my code using:

CustomDraw.this.setLayoutParams(new LinearLayout.LayoutParams(width + {adjust size}, height));

where "width" and "height" are the width and height of the custom View. Again, not sure why I have to say "new LinearLayout.LayoutParams(...);" but that's what seems to work.

Here's the xml I'm using:

<HorizontalScrollView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/scroller"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:fillViewport="true" >

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="548dp"
        android:orientation="vertical" >

        <maavapp.layout.CustomDraw
            android:id="@+id/custom_draw"
            android:layout_width="4800dp"
            android:layout_height="fill_parent" >
        </maavapp.layout.CustomDraw>
    </LinearLayout>
</HorizontalScrollView>

And here's the relevant parts of the custom class code I'm using:

public class CustomDraw extends View {
// member variables

public void setHSV(HorizontalScrollView hsv) {
    this.hsv = hsv;
}

public void updateLine() {
    if(measure1.isEmpty()) {
        measure1.add(new Coordinate(0, 0));
    } else {
        Coordinate last_coord = measure1.get(measure1.size() - 1);

                    // calculate south, north, east, and west

        if(((last_coord.x + 3) % 1200 == 0) 
                || ((last_coord.x + 3) % 1200 == 1) 
                || ((last_coord.x + 3) % 1200 == 2)
                || ((last_coord.x + 3) % 1200 == 3) && (last_coord.x + 3 >= 1200)) {
            hsv.smoothScrollTo(last_coord.x - 50, 0);
        }
        if(last_coord.x >= (width - 100)) {
            this.setLayoutParams(new LinearLayout.LayoutParams(width + 4800, height));
            width += 4800;
        }

        if(south && east) {
            measure1.add(new Coordinate(last_coord.x + 3, last_coord.y + 3));
        } else if(south && west) {
            measure1.add(new Coordinate(last_coord.x - 3, last_coord.y + 3));
        } else if(north && east) {
            measure1.add(new Coordinate(last_coord.x + 3, last_coord.y - 3));
        } else if(north && west) {
            measure1.add(new Coordinate(last_coord.x - 3, last_coord.y - 3));
        }
    }

    if(draw) {
        dh.sleep(10);
    }
}

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    this.width = w;
    this.height = h;
    super.onSizeChanged(w, h, oldw, oldh);
}

@Override
public void onDraw(Canvas c) {
    super.onDraw(c);
    Paint p = new Paint();
    p.setStyle(Paint.Style.FILL);

    p.setColor(Color.WHITE);
    c.drawPaint(p);
    p.setColor(Color.BLACK);

        Coordinate coord;
    for(int i = 0; i < measure1.size(); i++) {
        coord = measure1.get(i);
        c.drawRect(coord.x, coord.y, coord.x + 3, coord.y + 3, p);  
    }
}

class DrawHandler extends Handler {
    @Override
    public void handleMessage(Message msg) {
        CustomDraw.this.updateLine();
        CustomDraw.this.invalidate();
    }

    public void sleep(long delayMillis) {
        this.removeMessages(0);
        sendMessageDelayed(obtainMessage(0), delayMillis);
    }
}
}
Jon Rubins
  • 4,323
  • 9
  • 32
  • 51