안드로이드/개발관련(Kotlin)

안드로이드 Circle Progress (로딩 애니메이션) 만들기

닉네임못짓는사람 2023. 3. 30. 20:18
반응형

안드로이드에서 네트워크 통신을 하거나 데이터를 처리하는 동안

사용자에게 아무 화면도 보여주지 않으면 혼동을 줄 수 있다.

 

때문에 이 글에서는 위와 같은 상황에 사용할 수 있는 간단한 애니메이션을 만들어보도록 하자.

 

Drawable 작성


로딩 애니메이션은 gif, lottie등을 활용할 수도 있지만 이번 글에선 rotate drawable을 사용해서 만들어보도록 하자.

<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromDegrees="0"
    android:pivotX="50%"
    android:pivotY="50%"
    android:toDegrees="360" >
    <shape
        android:innerRadiusRatio="3"
        android:shape="ring"
        android:thicknessRatio="8"
        android:useLevel="false">

        <size
            android:width="60dp"
            android:height="60dp"/>
        <gradient
            android:angle="0"
            android:endColor="@color/teal_200"
            android:startColor="@color/white"
            android:type="sweep"
            android:useLevel="false"
            />
    </shape>
</rotate>

rotate로 이미지를 회전하도록 해주고 gradient값을 주어서 자연스럽게 두 가지 색이 섞이도록 해보자.

 

Dialog Fragment


그 다음으로 앱의 여러 군데에서 사용하기 편하도록 LoadingProgress를 보여주는 DIalogFragment를 하나 만들어보자.

class CircleProgressDialog: DialogFragment() {
    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        val binding = FragmentCircleProgressBinding.inflate(inflater, container, false)
        dialog?.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))

        return binding.root
    }
}
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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">

    <ProgressBar
        android:id="@+id/circle_progress"
        android:layout_width="300dp"
        android:layout_height="300dp"
        android:indeterminateDrawable="@drawable/circle_progress"
        android:indeterminateDuration="1000"
        android:padding="10dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

여기서 ProgressBar의 indeterminateDrawable에 위에서 만든 drawable을 넣어주면 된다.

 

실사용


마지막으로 Activity에서 버튼 클릭 시 위에서 만든 LoadingDialogFragment를 띄워주도록 해보자.

class MainActivity : AppCompatActivity() {
    private lateinit var binding: ActivityMainBinding
    private val loadingDialog = CircleProgressDialog()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        binding.loadingButton.setOnClickListener {
            showLoading()
        }
    }

    private fun showLoading() {
        CoroutineScope(Dispatchers.Main).launch {
            loadingDialog.show(supportFragmentManager, loadingDialog.tag)
            withContext(Dispatchers.Default) { delay(3000) }
            loadingDialog.dismiss()
        }
    }
}
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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">

    <Button
        android:id="@+id/loading_button"
        android:layout_width="200dp"
        android:layout_height="100dp"
        android:text="Loading"
        android:textAllCaps="false"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

위 코드에선 버튼 클릭 시 Loading Dialog를 띄워주고, Coroutine을 사용해 3초가 지나면 Dialog를 dismiss해주도록 했다.

 

 

 

 

반응형