안드로이드

안드로이드 프로그래밍 - 다용도 앱 만들기 6

IT의 큰손 2023. 1. 18. 17:37
728x90
  • 앱의 기능 설명
    • 1. 로그인 기능
    • 2. 메모장
    • 3. 달력
    • 4. 연락처
    • 5. 그림판
    • 6. 미니게임
    • 7. 계산기
    • 8. 스톱워치
    • 9. 가계부

 

  • 그림판
  •  

그림판

  • 그림판 xml 코드
더보기
LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#FFCCCCCC"
    android:orientation="vertical" >

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="40dp"
        android:layout_gravity="center"
        android:orientation="horizontal" >

        <ImageButton
            android:id="@+id/imageButton"
            android:layout_width="30dp"
            android:layout_height="30dp"
            android:layout_margin="8dp"
            android:contentDescription="expand"
            android:src="@drawable/plus" />
        <ImageButton
            android:id="@+id/imageButton2"
            android:layout_width="30dp"
            android:layout_height="30dp"
            android:layout_margin="8dp"
            android:contentDescription="shrink"
            android:src="@drawable/minus" />
        <ImageButton
            android:id="@+id/imageButton3"
            android:layout_width="30dp"
            android:layout_height="30dp"
            android:layout_margin="8dp"
            android:contentDescription="rotateLeft"
            android:src="@drawable/left" />
        <ImageButton
            android:id="@+id/imageButton4"
            android:layout_width="30dp"
            android:layout_height="30dp"
            android:layout_margin="8dp"
            android:contentDescription="rotateRight"
            android:src="@drawable/right" />
        <ImageButton
            android:id="@+id/new_btn"
            android:layout_width="30dp"
            android:layout_height="30dp"
            android:layout_margin="8dp"
            android:contentDescription="new drawing"
            android:src="@drawable/new_pic" />

        <ImageButton
            android:id="@+id/draw_btn"
            android:layout_width="30dp"
            android:layout_height="30dp"
            android:layout_margin="8dp"
            android:contentDescription="brush mode"
            android:src="@drawable/brush" />

        <ImageButton
            android:id="@+id/erase_btn"
            android:layout_width="30dp"
            android:layout_height="30dp"
            android:layout_margin="8dp"
            android:contentDescription="erase"
            android:src="@drawable/eraser" />

        <ImageButton
            android:id="@+id/save_btn"
            android:layout_width="30dp"
            android:layout_height="30dp"
            android:layout_margin="8dp"
            android:contentDescription="save"
            android:src="@drawable/save" />

    </LinearLayout>

    <kr.co.company.explicitintent.SingleTouchView
        android:id="@+id/drawing"
        android:layout_width="fill_parent"
        android:layout_height="0dp"
        android:layout_marginBottom="3dp"
        android:layout_marginLeft="5dp"
        android:layout_marginRight="5dp"
        android:layout_marginTop="3dp"
        android:layout_weight="1"
        android:background="#FFFFFFFF"
        tools:ignore="MissingClass" />

    <LinearLayout
        android:id="@+id/imagebt"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:orientation="vertical" >

        <LinearLayout
            android:id="@+id/paint_colors"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal" >

            <ImageButton
                android:layout_width="30dp"
                android:layout_height="30dp"
                android:layout_margin="2dp"
                android:background="#FF000000"
                android:onClick="clicked"
                android:tag="#FF000000" />

            <ImageButton
                android:layout_width="30dp"
                android:layout_height="30dp"
                android:layout_margin="2dp"
                android:background="#FFFF0000"
                android:onClick="clicked"
                android:tag="#FFFF0000" />

            <ImageButton
                android:layout_width="30dp"
                android:layout_height="30dp"
                android:layout_margin="2dp"
                android:background="#FFFF6600"
                android:onClick="clicked"
                android:tag="#FFFF6600" />

            <ImageButton
                android:layout_width="30dp"
                android:layout_height="30dp"
                android:layout_margin="2dp"
                android:background="#FFFFCC00"
                android:onClick="clicked"
                android:tag="#FFFFCC00" />

            <ImageButton
                android:layout_width="30dp"
                android:layout_height="30dp"
                android:layout_margin="2dp"
                android:background="#FF009900"
                android:onClick="clicked"
                android:tag="#FF009900" />

            <ImageButton
                android:layout_width="30dp"
                android:layout_height="30dp"
                android:layout_margin="2dp"
                android:background="#FFFFFFFF"
                android:onClick="clicked"
                android:tag="#FFFFFFFF" />
        </LinearLayout>
    </LinearLayout>
</LinearLayout>
  • LinearLayout을 통해 상위에 버튼들을 이미지 버튼을 통하여 나열 및 정리하였다.
  • 기능들로는,
    • 확대
    • 축소
    • 좌로 회전
    • 우로 회전
    • 새 페이지
    • 그리기
      • 검정,빨강,주황,노랑,초록,하양
    • 지우기
    • 저장

 

  • 그림판 java 코드
더보기
public class Activity6 extends AppCompatActivity {
    float scaleX = 1.0f, scaleY = 1.0f, rotateAngle;
    private SingleTouchView drawView;
    private ImageButton currPaint;
    private View new_btn;
    private View draw_btn;
    private View erase_btn;
    private View save_btn;
    private View imageButton;
    private View imageButton2;
    private View imageButton3;
    private View imageButton4;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.layout6);
        drawView = (SingleTouchView) findViewById(R.id.drawing);
        LinearLayout paintLayout = (LinearLayout) findViewById(R.id.paint_colors);
        currPaint = (ImageButton) paintLayout.getChildAt(0);
        new_btn = findViewById(R.id.new_btn);
        draw_btn = findViewById(R.id.draw_btn);
        erase_btn = findViewById(R.id.erase_btn);
        save_btn = findViewById(R.id.save_btn);
        imageButton = findViewById(R.id.imageButton);
        imageButton2 = findViewById(R.id.imageButton2);
        imageButton3 = findViewById(R.id.imageButton3);
        imageButton4 = findViewById(R.id.imageButton4);


        Button.OnClickListener onClickListener = new Button.OnClickListener() {
            @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
            @Override
            public void onClick(View view) {
                switch (view.getId()) {
                    //새 파일
                    case R.id.new_btn:
                        drawView.setMenu(0);
                        paintLayout.setVisibility(View.INVISIBLE);
                        break;

                    //그리기 모드
                    case R.id.draw_btn:
                        drawView.setMenu(1);

                        //그리기 모드 버튼을 눌러야 색상 버튼들이 보임
                        paintLayout.setVisibility(View.VISIBLE);
                        break;

                    //지우개 모드
                    case R.id.erase_btn:
                        drawView.setMenu(2);
                        paintLayout.setVisibility(View.INVISIBLE);
                        break;

                    //저장 모드
                    case R.id.save_btn:
                        drawView.setMenu(1);
                        paintLayout.setVisibility(View.INVISIBLE);
                        Toast.makeText(getApplicationContext(), "저장되었습니다.", Toast.LENGTH_SHORT).show();
                        break;
                    //확대모드
                    case R.id.imageButton:
                        drawView.setMenu(3);
                        paintLayout.setVisibility(View.INVISIBLE);
                        break;
                    //축소모드
                    case R.id.imageButton2:
                        drawView.setMenu(4);
                        paintLayout.setVisibility(View.INVISIBLE);
                        break;
                    //왼쪽회전
                    case R.id.imageButton3:
                        drawView.setMenu(5);
                        paintLayout.setVisibility(View.INVISIBLE);
                        break;
                    //오른쪽회전
                    case R.id.imageButton4:
                        drawView.setMenu(6);
                        paintLayout.setVisibility(View.INVISIBLE);
                        break;
                    default:
                        break;

                }
            }
        };
        new_btn.setOnClickListener(onClickListener);
        draw_btn.setOnClickListener(onClickListener);
        erase_btn.setOnClickListener(onClickListener);
        save_btn.setOnClickListener(onClickListener);
        imageButton.setOnClickListener(onClickListener);
        imageButton2.setOnClickListener(onClickListener);
        imageButton3.setOnClickListener(onClickListener);
        imageButton4.setOnClickListener(onClickListener);
    }
    public void color_clicked(View view) {
        if (view != currPaint) {
            String color = view.getTag().toString();
            drawView.setColor(color);
            currPaint = (ImageButton) view;
        }

        else {
            drawView.setColor("#00000000");
            currPaint = (ImageButton) view;
        }
    }


    public void clicked(View view) {
        if (view != currPaint) {
            String color = view.getTag().toString();
            drawView.setColor(color);
            currPaint = (ImageButton) view;
        }

    }


}
  • float형으로 scaleX, scaleY, ratateAngle를 선언
  • 각각의 버튼들을 findViewById하여 해당 자바로 불러옴
  • switch case문을 통하여 각각의 버튼이 클릭 되었을 때 실행되도록 함
    • case R.id.new_btn : 새파일을 사용
    • case R.id.draw_btn : 그리기 모드
    • case R.id.erase_btn : 지우개 모드
    • case R.id.save_btn : 저장 모드
    • case R.id.imageButton : 확대 모드
    • case R.id.imageButton2 : 축소 모드
    • case R.id.imageButton3 : 좌로 회전
    • case R.id.imageButton4 : 우로 회전

 

  • 그림판 java 코드 2
더보기
public class SingleTouchView extends View {
    private Paint paint = new Paint();
    private Path path = new Path();
    private int paintColor = 0xFF000000;
    private Paint canvasPaint;
    private Canvas drawCanvas;
    private Bitmap canvasBitmap;
    float scaleX = 1.0f, scaleY = 1.0f, rotateAngle;
    MyView displayView;

    public class MyView extends View {
        public MyView(MainActivity context) {
            super(context);
        }
    }
    public SingleTouchView(Context context, AttributeSet attrs) {
        super(context, attrs);

        paint.setAntiAlias(true);
        paint.setStrokeWidth(10f);
        paint.setColor(paintColor);
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeJoin(Paint.Join.ROUND);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        canvasBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
        drawCanvas = new Canvas(canvasBitmap);
        canvasPaint = new Paint(Paint.DITHER_FLAG);

    }

    @Override
    protected void onDraw(Canvas canvas) {
        canvas.drawBitmap(canvasBitmap, 0, 0, canvasPaint);
        canvas.drawPath(path, paint);

        int centerX = getWidth() / 2;
        int centerY = getHeight() / 2;
        canvas.scale(scaleX, scaleY, centerX, centerY);
        canvas.rotate(rotateAngle, centerX, centerY);

        Bitmap bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.rp3);
        canvas.drawBitmap(bitmap,0,0,paint);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        float touchX = event.getX();
        float touchY = event.getY();
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                path.moveTo(touchX, touchY);
                break;
            case MotionEvent.ACTION_MOVE:
                path.lineTo(touchX, touchY);
                break;
            case MotionEvent.ACTION_UP:
                drawCanvas.drawPath(path, paint);
                path.reset();
                break;
            default:
                return false;
        }
        invalidate();
        return true;

    }

    public void setColor(String newColor) {
        invalidate();
        paintColor = Color.parseColor(newColor);
        paint.setColor(paintColor);
    }

    public void setMenu(int menu) {
        Log.d("!!singletouchview", String.valueOf(menu));
        if(menu == 0) {
            canvasBitmap.eraseColor(Color.WHITE);
            invalidate();
        }

        else if(menu == 2) {
            paint.setColor(0xFFFFFFFF);
            paint.setStrokeWidth(30f);
            paint.setStrokeCap(Paint.Cap.SQUARE);
        }
        else if(menu == 3) {
            scaleX += 0.3;
            scaleY += 0.3;
            invalidate();
        }
        else if(menu == 4) {
            scaleX -= 0.3;
            scaleY -= 0.3;
            invalidate();
        }
        else if(menu == 5) {
            rotateAngle -= 30;
            invalidate();
        }
        else if(menu == 6) {
            rotateAngle += 30;
            invalidate();
        }
        else {
        }
    }
}
  • paint() 클래스를 상속
  • path() 클래스를 상속
  • setAntiAlias(true) : 상차가 뚜렷한 경계 부근에 중간색을 삽입하여 도형이나 글꼴이 주변 배경과 부드럽게 잘 어울리도록 함.
  • setStrokeWidth(10f) : 선 두께는 10f
  • setColor(paintColor) : 색상은 paintColor
  • setStyle(Paint.style.STROKE) : 채우지 않고 외각선만 채운다
  • setStrokeJoin(Paint.Join.ROUND) : 선의 꼭지점은 둥글게
  • canvasBitmap : 비트맵을 생성한다.
  • onDraw 를 통하여, 해당 비트맵에 그려질 수 있도록 하였다.
  • onTouchEvent 를 통하여, ACTION_DOWN, ACTION_MOVE, ACTION_UP을 사용
  • setMenu를 통하여, 이전의 case문이 사용되도록 함.
728x90