본문 바로가기

안드로이드

새로운 뷰 만들기

반응형

뷰가 스스로의 크기를 정할 때 자동으로 호출되는 메소드는 onMeasure이고, 스스로를 레이아웃에 맞게 그릴 때는 onDraw 메소드가 자동으로 호출된다

 

public void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
public void onDraw(Canvas canvas)

 

widthMeasureSPec과 heightMeasureSpec은 이 뷰를 담고 있는 레이아웃에서 이 뷰에게 허용하는 여유 공간의 폭과 높이에 대한 정보이다

부모 컨테이너에서 여유 공간에 대한 정보를 전달하는데 이 값을 참조하여 뷰가 보일 적절한 크기를 반환하면 이 크기 값으로 뷰가 그려지게 된다

 

void setMeasuredDimension(int measuredWidth, int measuredHeight)

onMeasure 메소드 안에서 이 뷰를 담고 있는 레이아웃에게 이 뷰의 크기 값을 반환하고 싶다면 setMeasuredDimension 메소드를 사용한다

 

/app/res/value/dimens.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <dimen name="text_size">16sp</dimen>
</resources>

 

dimens.xml 파일은 크기 값 등을 정의할 수 있는 파일

 

MyButton.java

package com.example.a42_view;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;

import androidx.appcompat.widget.AppCompatButton;

// API에서 제공하는 뷰를 사용하려면 API의 뷰를 상속해야 한다
// AppCompatButton에는 버튼을 위한 기능이 미리 정의되어 있다
public class MyButton extends AppCompatButton {

    //    안드로이는 UI 객체를 만들 때, Context 객체를 전달받도록 되어 있으므로 생성자에는 항상 Context 객체가 전달되어야 한다
    public MyButton(Context context) {
        super(context);
    }

    //    AttributeSet 객체는 xml 레이아웃에서 태그에 추가하는 속성을 전달받기 위한 것
    public MyButton(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    private void init(Context context) {
//        배경색 설정
        setBackgroundColor(Color.CYAN);
//        글자색 설정
        setTextColor(Color.BLACK);

//        글자 크기 설정
//        픽셀 단위만 설정 가능하므로, xml 파일을 사용하여서 sp 단위를 사용
        float textSize = getResources().getDimension(R.dimen.text_size);
        setTextSize(textSize);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        Log.d("MyButton", "onDraw 호출됨");
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        Log.d("MyButton", "onTouchEvent 호출됨");

        int action = event.getAction();
        switch (action) {
            case MotionEvent.ACTION_DOWN:
                setBackgroundColor(Color.BLUE);
                setTextColor(Color.RED);
                break;

            case MotionEvent.ACTION_OUTSIDE:
            case MotionEvent.ACTION_CANCEL:
            case MotionEvent.ACTION_UP:
                setBackgroundColor(Color.CYAN);
                setTextColor(Color.BLACK);
                break;
        }

//        전체 뷰를 새로 고침
        invalidate();

        return true;
    }
}

 

activity_main

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <!-- 새로 만든 MyButton 클래스를 태그로 추가하기 -->
    <!-- RelativeLayout 안에 추가했을때 layout_centerInParent 속성을 true로 하면 화면 가운데에 보이도록 함 -->
    <com.example.a42_view.MyButton
        android:id="@+id/button"
        android:layout_width="200dp"
        android:layout_height="80dp"
        android:layout_centerInParent="true"
        android:text="시작하기" />

</RelativeLayout>

 

 

 

 

 

 

 

반응형

'안드로이드' 카테고리의 다른 글

리사이클러뷰  (0) 2021.10.26
새로운 레이아웃 만들기, 카드뷰 넣기  (0) 2021.10.26
나인 패치  (0) 2021.10.26
외부 라이브러리를 이용한 위험 권한 자동 부여  (0) 2021.10.26
위험 권한 부여  (0) 2021.10.22