[Android/Kotlin] Expandable Layout - 레이아웃 확장하기

Notepad96

·

2022. 9. 2. 11:19

300x250

 

 

1. 요약

 

결과

이번 글에서는 확장(Expandable)하여 레이아웃을 나타낼 수 있는 방법에 관하여 작성한다. 

 

처음에는 확장되어 보이는 레이아웃은 Visibility하지 않는 상태에서 Layout을 클릭하였을 시 보이지 않던 레이아웃을 보이게 하는 방식으로 구현하였다.

 

 

 

 

2. 레이아웃

2-1. activity_main.xml

메인 레이아웃 파일로서 아래 이미지처럼 Layout 01과 Layout 02이 나타난다.

 

이후 각 Layout 01, 02를 클릭하였을 때 아래 숨겨져 있던 Layout이 보이도록 만듦으로써 마치 "접은 글"처럼 레이아웃이 확장되어 나타나지는 기능을 구현한다.

 

※ 최상단의 LinearLayout을 보면 "android:animateLayoutChanges" 속성을 주고 있다. 이는 레이아웃이 변경될 때마다 미리 로드된 애니메이션이 자동으로 실행되도록 만들어준다.

 

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
    android:orientation="vertical"
    android:animateLayoutChanges="true"
    tools:context=".MainActivity">

    <com.google.android.material.card.MaterialCardView
        android:id="@+id/layout01"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginHorizontal="10dp"
        android:layout_marginTop="5dp"
        android:backgroundTint="#FF9341"
        app:strokeWidth="1dp"
        app:cardCornerRadius="3dp"
        app:strokeColor="@color/black">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="10dp"
            android:layout_gravity="center_vertical"
            android:text="Layout 01"
            android:textColor="@color/white"
            android:textSize="22sp" />
        <ImageButton
            android:id="@+id/layoutBtn01"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="10dp"
            android:src="@drawable/arrow_up"
            android:clickable="false"
            android:background="@android:color/transparent"
            android:layout_gravity="right"
            android:textSize="22sp" />
    </com.google.android.material.card.MaterialCardView>

    <com.google.android.material.card.MaterialCardView
        android:id="@+id/layoutDetail01"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginHorizontal="10dp"
        android:backgroundTint="#ccc"
        android:visibility="gone"
        app:strokeWidth="1dp"
        app:strokeColor="#aaa">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="10dp"
            android:layout_gravity="center_vertical"
            android:text="t is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English."
            android:textSize="18sp" />
    </com.google.android.material.card.MaterialCardView>


    <com.google.android.material.card.MaterialCardView
        android:id="@+id/layout02"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginHorizontal="10dp"
        android:layout_marginTop="25dp"
        android:backgroundTint="#6B54CF"
        app:strokeWidth="1dp"
        app:cardCornerRadius="3dp"
        app:strokeColor="@color/black">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="10dp"
            android:layout_gravity="center_vertical"
            android:text="Layout 02"
            android:textColor="@color/white"
            android:textSize="22sp" />
        <ImageButton
            android:id="@+id/layoutBtn02"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="10dp"
            android:src="@drawable/arrow_up"
            android:clickable="false"
            android:background="@android:color/transparent"
            android:layout_gravity="right"
            android:textSize="22sp" />
    </com.google.android.material.card.MaterialCardView>

    <com.google.android.material.card.MaterialCardView
        android:id="@+id/layoutDetail02"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginHorizontal="10dp"
        android:backgroundTint="#ccc"
        android:visibility="gone"
        app:strokeWidth="1dp"
        app:strokeColor="#aaa">

        <ImageView
            android:layout_width="match_parent"
            android:layout_height="250dp"
            android:scaleType="fitXY"
            android:src="@drawable/bread" />
    </com.google.android.material.card.MaterialCardView>
</LinearLayout>

 

 

 

 

3. 코드 및 설명

3-1. MainActivity.kt

Layout의 Click Event를 정의하여 Click 하였을 때 숨겨져 있던 Layout이 보이도록 만든다.

 

이때 숨겨진 Layout이 보이도록 만들 뿐만 아니라 접힌 상태인지 직관적으로 볼 수 있도록 삽입한 화살표 또한 180도 회전하는 animation을 넣음으로써 로직에 따라서 자연스럽게 변화되도록 구현하였다.

 

 

package com.notepad96.layoutexpandable

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import androidx.core.view.isVisible
import com.notepad96.layoutexpandable.databinding.ActivityMainBinding

class MainActivity : AppCompatActivity() {
    private val binding: ActivityMainBinding by lazy { ActivityMainBinding.inflate(layoutInflater) }
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(binding.root)

        binding.layout01.setOnClickListener {
            if(binding.layoutDetail01.visibility == View.VISIBLE) {
                binding.layoutDetail01.visibility = View.GONE
                binding.layoutBtn01.animate().apply {
                    duration = 300
                    rotation(0f)
                }
            } else {
                binding.layoutDetail01.visibility = View.VISIBLE
                binding.layoutBtn01.animate().apply {
                    duration = 300
                    rotation(180f)
                }
            }
        }

        binding.layout02.setOnClickListener {
            if(binding.layoutDetail02.visibility == View.VISIBLE) {
                binding.layoutDetail02.visibility = View.GONE
                binding.layoutBtn02.animate().apply {
                    duration = 300
                    rotation(0f)
                }
            } else {
                binding.layoutDetail02.visibility = View.VISIBLE
                binding.layoutBtn02.animate().apply {
                    duration = 300
                    rotation(180f)
                }
            }
        }

    }

}

 

 

 

 

4. 전체 파일

 

 

GitHub - Notepad96/BlogExample02

Contribute to Notepad96/BlogExample02 development by creating an account on GitHub.

github.com

 

 

 

300x250