[Kotlin] 5장. 화면 구성 - 프래그먼트, 뷰

Hwichan Ji·2020년 12월 22일
0

Kotlin

목록 보기
5/11
post-thumbnail

이것이 안드로이드다 with 코틀린(고돈호 지음) 으로 공부한 내용을 정리한 글입니다.

Fragment

Fragment는 하나의 화면을 분할하여 각각을 독립적인 코드로 구성할 때 사용합니다.

class MyFragment : Fragment() {
    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        return inflater.inflate(R.layout.myfragment_layout, container, false)
    }
}

태블릿과 같은 큰 화면을 가진 디바이스에선 한 화면에 여러 Fragment 가 함께 나타나도록 하지만, 스마트폰과 같이 작은 화면을 가진 디바이스에선 탭 메뉴나 스와이프로 전환되는 화면들을 Fragment 로 만듭니다.

프래그먼트를 액티비티에 추가

프래그먼트는 단독으로 사용되지 않고 액티비티의 일부로 사용됩니다.

// 프래그먼트 생성
val mFragment: MyFragment = MyFragment() 

// 프래그먼트를 액티비티에 넣기 위한 트랜잭션 객체 생성
val transaction = supportFragmentManager.beginTransaction() 

// 액티비티에 넣을 프래그먼트와 넣을 위치를 트랜잭션에 추가
transaction.add(R.id.frameLayout, mFragment)

// 트랜잭션을 수행
transaction.commit()

액티비티에서 프래그먼트를 하나만 사용할 경우엔 <fragment> 컨테이너
를 사용하여 프래그먼트를 배치하고 프래그먼트 간의 전환이 필요한 경우엔 <FrameLayout>에 프래그먼트를 배치합니다.

프래그먼트로 데이터 전달

프래그먼트 생성시 데이터 전달

액태비티끼리는 Intent를 통해 데이터를 주고 받았다면 액티비티에서 프래그먼트로 데이터를 전달할 때는 arguments라는 프로퍼티를 이용합니다.

// activity
val mFragment: MyFragment = MyFragment()

var bundle = Bundle()
bundle.putString("key", "value")

mFragment.arguments = bundle

// fragment
val str = arguments?.getString("key")

생성되어 화면에 보이는 프래그먼트에 데이터 전달

프래그먼트에 메서드를 정의하고 액티비티에서 그 메서드를 호출하여 데이터를 직접적으로 전달할 수 있습니다.

프래그먼트에서 프래그먼트로 데이터 전달

프래그먼트 사이의 데이터 전송은 액티비티를 거쳐야 합니다. 데이터를 전달하는 프래그먼트는 액티비티에 정의된 메서드를 호출하고, 그 메서드는 데이터를 받는 프래그먼트의 메서드를 호출하여 데이터를 전달합니다.

프래그먼트 생명주기

fragment lifecycle
출처: Android Developers

View

View는 화면을 구성하는 최소 단위입니다. 뷰는 뷰그룹으로 묶이며 이 뷰그룹이 모여 프래그먼트 혹은 액티비티를 이룹니다. 일반적으로 위젯은 뷰로, 레이아웃은 뷰그룹으로 여겨지지만 위젯과 레이아웃 모드 최상위 클래스인 View 클래스를 상속받아 구현합니다.

View Class

View 클래스는 화면에 그림을 그리기 위한 메서드를 가지고 있습니다. View 클래스를 상속받은 위젯들이 화면에 그리고자 하는 것의 크기, 색상, 위치 등의 정보를 View 클래스로 전달하면 View 클래스는 onDraw() 메서드를 사용하여 화면에 그립니다.

View에 텍스트 출력하기

View 클래스는 Context 를 생성자에서 입력받아야 하기 때문에 View 클래스를 상속받은 클래스들은 Context 를 입력받는 생성자가 하나 꼭 있어야만 합니다.

class CustomView(context: Context) : View(context) {
    override fun onDraw(canvas: Canvas?) {
        super.onDraw(canvas)
    }
}

Canvas 클래스는 일종의 그리기 도구로 그림판과 함께 그림을 그리기 위한 draw로 시작하는 메서드들을 제공합니다. 텍스트를 출력하기 위해서는 CanvasdrawText() 메서드를 사용해야 합니다. drawText() 메서드에는 글자의 색과 두께 정보를 가지고 있는 Paint 객체와 출력할 문자열 그리고 가로세로 좌표가 필요합니다.

val paint = Paint()
paint.color = Color.BLACK
paint.textSize = 100f
canvas?.drawText("hello", 0f, 100f, paint)

안드로이드 화면 좌표는 왼쪽 상단이 (0,0)이고 문자열의 기준 좌표는 문자열의 왼쪽 하단입니다. 따라서 문자열을 완전하게 출력하기 위해선 문자열의 높이만큼 출력 y좌표를 증가시켜줘야 합니다.

사용자로부터 문자열을 입력받아 출력할 경우엔 생성자를 통해 그 문자열을 넘겨받아야 합니다.

class CustomView(text: String, context: Context) : View(context) {
    var text: String
    init {
        this.text = text
    }
    override fun onDraw(canvas: Canvas?) {
        super.onDraw(canvas)
        // ...
        canvas?.drawText(text, 0f, 100f, paint)
    }
}

View에 그림 그리기

View에 도형 그림을 그릴 때는 색상, 모양, 외곽선 두께 등에 대한 정보가 담긴 Paint 객체를 사용합니다.

  • drawCircle(중심의 x좌표, 중심의 y좌표, 반지름, Paint): 원을 그리는 메소드
  • drawArc(중심의 x좌표, 중심의 y좌표, 반지름, Paint): 원호를 그리는 메소드
  • drawRect(Rect, Paint): 사각형을 그리는 메소드. Rect은 사각형의 left, top, right, bottom 좌표를 담은 클래스
  • drawRoundRect(RectF, x라운드 크기, y라운드 크기, Paint): 둥근 사각형을 그리는 메소드.

커스텀 위젯 만들기

위젯의 커스터 마이징은 크게 세 단계로 진행됩니다.

attrs.xml 파일 생성

attrs.xml은 위젯 이름, 속성의 이름 그리고 입력되는 값의 타입을 정의한 파일입니다.

<declare-styleable name="CustomWidget">
    <attr name="새로운 속성" format="string"/>
</declare-styleable>

커스텀 위젯 클래스 생성

위젯 클래스를 상속받아 커스텀 위젯 클래스를 생성하고 위에서 정의한 속성을 처리하는 코드를 작성합니다.

class CustomWidget : TextView {
    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int)
        : super(context, attrs, defStyleAttr) {
    
    }
}

레이아웃에 태그 적용

레이아웃 파일에서 커스텀 속성은 android 대신 custom을 사용합니다.

<패키지명.CustomWidget
    android:id="@+id/button"
    custom:새로운 속성=""
    android:text="새로 만든 위젯"/>
profile
안드로이드 개발자를 꿈꾸는 사람

0개의 댓글