마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

레이아웃에 커스텀뷰(paint 객체?) 어떻게 추가 해야 할까요??

0 추천

안녕하세요.. 그림판 예제를 조금 바꿔보고 싶어서 고민 하고 있습니다.

제 생각으로는 화면 제일 위쪽에 선 모양(볼펜, 형광펜 등의 모양) 색 선택 등의 버튼을 넣어주고

그 밑에  나머지 화면에다가 그리고 싶어서

MyView로 생성한 뷰를 레이아웃에 추가 하려고 하는데 생각처럼 되질 않고

어플을 실행하면 바로 종료가 되어버립니다.

package com.example.androidtest;

import android.app.Activity;
import android.content.Context;
import android.graphics.*;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.widget.*;

public class MainActivity extends Activity {


    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        View myV = new MyView(this);
        LinearLayout linear = (LinearLayout)findViewById(R.id.linear);
        linear.addView(myV);
        setContentView(linear);

        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setDither(true);
        mPaint.setColor(Color.BLACK);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeJoin(Paint.Join.ROUND);
        mPaint.setStrokeCap(Paint.Cap.ROUND);
        mPaint.setStrokeWidth(12);
        
    }

    private Paint       mPaint;

    public class MyView extends View {

        private Bitmap  mBitmap;
        private Canvas  mCanvas;
        private Path    mPath;
        private Paint   mBitmapPaint;

        public MyView(Context c) {
            super(c);

            mPath = new Path();
            mBitmapPaint = new Paint(Paint.DITHER_FLAG);
        }

        @Override
        protected void onSizeChanged(int w, int h, int oldw, int oldh) {
            super.onSizeChanged(w, h, oldw, oldh);
            mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
            mCanvas = new Canvas(mBitmap);
        }

        @Override
        protected void onDraw(Canvas canvas) {
            canvas.drawColor(0xFFAAAAAA);

            canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);

            canvas.drawPath(mPath, mPaint);
        }

        private float mX, mY;
        private static final float TOUCH_TOLERANCE = 4;

        private void touch_start(float x, float y) {
            mPath.reset();
            mPath.moveTo(x, y);
            mX = x;
            mY = y;
        }
        private void touch_move(float x, float y) {
            float dx = Math.abs(x - mX);
            float dy = Math.abs(y - mY);
            if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
                mPath.quadTo(mX, mY, (x + mX)/2, (y + mY)/2);
                mX = x;
                mY = y;
            }
        }
        private void touch_up() {
            mPath.lineTo(mX, mY);
            // commit the path to our offscreen
            mCanvas.drawPath(mPath, mPaint);
            // kill this so we don't double draw
            mPath.reset();
        }

        @Override
        public boolean onTouchEvent(MotionEvent event) {
            float x = event.getX();
            float y = event.getY();

            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    touch_start(x, y);
                    invalidate();
                    break;
                case MotionEvent.ACTION_MOVE:
                    touch_move(x, y);
                    invalidate();
                    break;
                case MotionEvent.ACTION_UP:
                    touch_up();
                    invalidate();
                    break;
            }
            return true;
        }
    }
}

이렇게 진행되고 있는데

xml은

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/linear"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity" >

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal" >

        <Button
            android:id="@+id/a"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="A" />

        <Button
            android:id="@+id/B"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="B" />

        <Button
            android:id="@+id/C"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="C" />

        <Button
            android:id="@+id/D"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="D" />
    </LinearLayout>

</LinearLayout>

이렇게 되어있습니다.

어디가 잘못됐다거나 이부분이 좀 이상하다거나 블로그를 참고해보라거나 알려주시면 감사하겠습니다.

익명사용자 님이 2013년 12월 20일 질문

1개의 답변

0 추천
setContentView의 사용이 잘못되었네요.

setContentView 보다

LinearLayout linear = (LinearLayout)findViewById(R.id.linear);부분의 findViewById를 먼저사용하여서 에러가 난것으로 예상됩니다.

액티비티에 할당된 레이아웃이 없는데 view를 찾는 메소드를 호출해서 그렇구요.

 

setContentView(R.layout,[xml명]); 을 제일먼저 하신뒤에

LinearLayout linear = (LinearLayout)findViewById(R.id.linear);

하고 나신뒤 MyView를 만들어서 linear에 add해보세요.
얼룩돼지 (15,720 포인트) 님이 2013년 12월 20일 답변
지금 밖이라 조금 있다가 해 봐야겠네요...
그리고 또 궁굼한게...그림판을 만드려고 하는중인데 제일 위에 버튼들을 놔두고 나머지에 paint로 canvas를 그린 뷰는 버튼 밑에서부터 범이가 되는게 맞는건가요??
그렇게 하시려면 조금 수정을 해야합니다.
아 그리고 질문에 올려주신 소스에 myV객체에 영역잡아주는 코드가 없네요.

음.. 원하시는데로 하시려면 weight 개념을 아셔야하는데..
XML에서 최상위 LinearLayout에 orientation="verical"로 주시고
myV.serLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayouParams.MATHCH_PARENT, 0, 1);
이렇게 주가해주시면 버튼 레이아웃외에 나머지영역을 myV가 차지하게 됩니다.
감사합니다 ^^ 이제야 뷰나 엑티비티 순서를 쪼금 이나마 알겠네요.. 책을 참고해서 계속 진행 하겠습니다.. 채택? 이라는게 보이지 않아서 이렇게 댓글을 남기네요 ^^
헐.. 정말정말 감사합니다...
...