アプリケーションがカスタム ビューを (水平方向と垂直方向の両方で) スクロールできるようにして、ユーザーが初期画面サイズ以上のものを描画できるようにしようとしています。このアプリケーションは、基本的な家屋図の生成に使用されます。たとえば、ユーザーは自分の家を表す接続された長方形を描画します。
アクティビティ内で (内部クラスとして) 設定したカスタム ビューを使用しています。人々がスクロールビューで抱えている問題を広範囲に検索して見た後、これは私がなんとか得た限りです。ここに私の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>
ご覧のとおり、クラス (アクティビティ)HomerView
内にあるクラスを追加しようとしています。DrawNewPlans
onCreate()
メソッドは次のとおりです。
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.drawnew);
}
これが私のカスタムビューのコードです(これは別のクラスに含まれていることに注意してください):
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;
}
}
}
追加しなければならないことがたくさんありますが、それらは何ですか? awakenScrollBars()
?
また、現時点Error inflating class com.example.HomerProject1stDraft.DrawNewPlans.HomerView
では、XML ファイルでこのエラーが発生します。カスタム ビューの作成方法に誤りはありますか? 内部クラスからビューを作成することさえできますか?
どうもありがとう。