I've been trying to enable my application to scroll my custom view (both horizontally and vertically) to enable the user to draw on more than just the initial screen size. The application is to be used for basic house plan generation e.g. a user draws connected rectangles representing their home.
I am using a custom View which I have set up (as an inner class) inside the activity. After extensive searching and seeing the issues people are having with scroll views, this is as far as I've managed to get. Here's my XML:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<com.example.HomerProject1stDraft.DrawNewPlans.HomerView
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</com.example.HomerProject1stDraft.DrawNewPlans.HomerView>
</LinearLayout>
As you can see I'm trying to add my HomerView
class which is inside the DrawNewPlans
class (the activity).
Here is the onCreate()
method:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.drawnew);
}
Here's the code for my custom view (bearing in mind this is contained in another class):
class HomerView extends View { // the custom View for drawing on
// set up Bitmap, canvas, path and paint
private Bitmap myBitmap; // the initial image we turn into our canvas
private Canvas myCanvas; // the canvas we are drawing on
private Rect myRect; // the mathematical path of the lines we draw
private Paint myBitmapPaint; // the paint we use to draw the bitmap
// get the width of the entire tablet screen
private int screenWidth = getContext().getResources()
.getDisplayMetrics().widthPixels;
// get the height of the entire tablet screen
private int screenHeight = (getContext().getResources()
.getDisplayMetrics().heightPixels);
private int mX, mY, iX, iY; // current x,y and in
public HomerView(Context context) { // constructor of HomerView
super(context);
System.out.println("Screen Width = "+screenWidth+" and screen height = "+screenHeight);
myBitmap = Bitmap.createBitmap(screenWidth, screenHeight,
Bitmap.Config.ARGB_8888); // set our drawable space - the bitmap which becomes the canvas we draw on
myCanvas = new Canvas(myBitmap); // set our canvas to our bitmap which we just set up
myRect = new Rect(); // make a new rect
myBitmapPaint = new Paint(Paint.DITHER_FLAG); // set dither to ON in our saved drawing - gives better color interaction
}
protected void onDraw(Canvas canvas) { // method used when we want to draw something to our canvas
super.onDraw(canvas);
if (addObjectMode == true || addApplianceMode == true) {
canvas.drawColor(Color.TRANSPARENT); // sets canvas colour
canvas.drawBitmap(myBitmap, 0, 0, myBitmapPaint); // save the canvas to bitmap - the numbers are the x, y coords we are drawing from
for (int i = 0; i < rectList.size(); i++) {
canvas.drawRect(rectList.get(i), myPaint);
}
if (addApplianceMode == true) {
canvas.drawBitmap(bmp, iX-50, iY-50, myBitmapPaint);
}
canvas.drawRect(myRect, myPaint); // draw the rectangle that the user has drawn using the paint we set up
}
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) { // if screen size changes, alter the bitmap size
super.onSizeChanged(w, h, oldw, oldh);
}
private void touch_Start(float x, float y) { // on finger touchdown
// check touch mode
iX = (int) (Math.round(x));
iY = (int) (Math.round(y));
mX = (int) (Math.round(x));
mY = (int) (Math.round(y));
if (addObjectMode == true) {
myRect.set(iX, iY, mX, mY);
} else if (addApplianceMode == true) {
// code to draw an appliance icon at mX, mY (with offset so icon is centered)
if (isLamp == true) {
Resources res = getResources();
bmp = BitmapFactory.decodeResource(res, R.drawable.lamp);
myCanvas.drawBitmap(bmp, iX - 50, iY - 50, myBitmapPaint);
} else if (isPC == true) {
Resources res = getResources();
bmp = BitmapFactory.decodeResource(res, R.drawable.pc);
myCanvas.drawBitmap(bmp, iX - 50, iY - 50, myBitmapPaint);
} else if (isKettle == true) {
Resources res = getResources();
bmp = BitmapFactory.decodeResource(res, R.drawable.kettle);
myCanvas.drawBitmap(bmp, iX - 50, iY - 50, myBitmapPaint);
} else if (isOven == true) {
Resources res = getResources();
bmp = BitmapFactory.decodeResource(res, R.drawable.oven);
myCanvas.drawBitmap(bmp, iX - 50, iY - 50, myBitmapPaint);
} else if (isTV == true) {
Resources res = getResources();
bmp = BitmapFactory.decodeResource(res, R.drawable.tv);
myCanvas.drawBitmap(bmp, iX - 50, iY - 50, myBitmapPaint);
}
}
}
private void touch_Move(float x, float y) { // on finger movement
float dX = Math.abs(x - mX); // get difference between x and my X
float dY = Math.abs(y - mY);
if (dX >= TOUCH_TOLERANCE || dY >= TOUCH_TOLERANCE) { // if coordinates are outside screen? if touching hard enough?
mX = (int) (Math.round(x));
mY = (int) (Math.round(y));
if (addObjectMode == true) {
myRect.set(iX, iY, mX, mY);
}
}
}
@SuppressWarnings("deprecation")
private void touch_Up() { // on finger release
if (addObjectMode == true) {
myRect.set(iX, iY, mX, mY);
System.out.println("MyRect coords = "+iX+","+iY+","+mX+","+mY);
rectList.add(myRect);
myCanvas.drawRect(iX, iY, mX, mY, myPaint); // if this isnt present - no lasting copy is drawn to screen. It is erased every draw.
if (eraseMode == false) {
dialogStarter();
}
} else if (addApplianceMode == true) {
showDialog(DIALOG_DEVICE_ENTRY);
}
}
public boolean onTouchEvent(MotionEvent event) { // on any touch event
if (addObjectMode == true || addApplianceMode == true) {
float x = event.getX(); // get current X
float y = event.getY(); // get current Y
switch (event.getAction()) { // what action is the user performing?
case MotionEvent.ACTION_DOWN: // if user is touching down
touch_Start(x, y);
invalidate();
break;
case MotionEvent.ACTION_MOVE: // if user is moving finger while touched down
touch_Move(x, y);
invalidate();
break;
case MotionEvent.ACTION_UP: // if user has released finger
touch_Up();
invalidate();
break;
}
return true;
} else {
return false;
}
}
}
I realise there are many things I need to add - but what are they? awakenScrollBars()
?
Also: at the moment I get this error Error inflating class com.example.HomerProject1stDraft.DrawNewPlans.HomerView
in the XML file. Is there a mistake in the way I'm creating the custom view? Can you even create a view from an inner class?
Many Thanks.