0

アプリケーションがカスタム ビューを (水平方向と垂直方向の両方で) スクロールできるようにして、ユーザーが初期画面サイズ以上のものを描画できるようにしようとしています。このアプリケーションは、基本的な家屋図の生成に使用されます。たとえば、ユーザーは自分の家を表す接続された長方形を描画します。

アクティビティ内で (内部クラスとして) 設定したカスタム ビューを使用しています。人々がスクロールビューで抱えている問題を広範囲に検索して見た後、これは私がなんとか得た限りです。ここに私の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 ファイルでこのエラーが発生します。カスタム ビューの作成方法に誤りはありますか? 内部クラスからビューを作成することさえできますか?

どうもありがとう。

4

2 に答える 2

0

Firstly , i would suggest not to wrap your custom scrollview in another scrollview.If it is avoidable, avoid it.Also, you can check below link where i have implemented a custom scrollview.

https://stackoverflow.com/questions/15188842/customization-of-imageview-and-layouts

于 2013-03-06T16:20:15.230 に答える
0

ScrollView は垂直スクロールのみをサポートします。水平方向と垂直方向の両方でスクロールする必要があるため、TwoDScrollView と呼ばれる特別なクラスが必要になります。

このクラスとソース コードの詳細については、http: //blog.gorges.us/2010/06/android-two-dimensional-scrollview/を参照してください。

xml で ScrollView の代わりにこのクラスを使用すると、水平方向と垂直方向の両方にスクロールできるはずです。

他のエラーについては、ソースコードと問題が発生した場所を共有してください。

于 2013-03-06T16:57:54.990 に答える