Android Jetpack을 사용하여 보안 매개 변수를 통해 데이터 전달

Android Jetpack은 개발자에게 다양한 도구를 제공하여 개발 속도를 높이는 동시에 최선의 실천을 장려하여 생활을 더욱 쉽게 하는 데 목적을 두고 있다.우리가 오늘 주목해야 할 도구는 네비게이션 구성 요소와 안전 파라미터를 사용하여 데이터를 전달하는 것이다.
Safe Args는 Gradle 플러그인으로 목적지 간에 데이터를 탐색하고 전달할 때 유형 보안을 제공합니다.
우리는 간단한 응용 프로그램을 만들어서 이러한 개념을 탐색할 것이다. 이 응용 프로그램은 RecyclerView을 포함하는 부분에 사용자 목록을 표시하고 선택한 User을 우리의 UserDetailsFragment에 전달할 것이다.

우리는 새로운 AndroidX 프로젝트부터 시작할 것이다. 이 프로젝트는 빈 활동이 있다.

의존항을 설정하는 것부터 시작합시다.
프로젝트 build.gradle 파일에 다음을 추가합니다.
... // dependencies {

def nav_version = "2.3.0"
classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$nav_version"

... // dependencies closing }
모듈 build.gradle 파일에는 다음과 같은 모든 내용이 필요합니다.
... // other plugins

apply plugin: "androidx.navigation.safeargs"

... // android {
이 플러그인은 NavArgsNavDirections을 생성합니다.
... // android {

compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_8
    targetCompatibility JavaVersion.VERSION_1_8
}

kotlinOptions {
    jvmTarget = "1.8"
}

... // android closing }
Java 8은 보안 매개변수를 사용하기 위한 최소 요구 사항입니다.
... // depedencies {

def nav_version = "2.3.0"
implementation "androidx.navigation:navigation-fragment-ktx:$nav_version"
implementation "androidx.navigation:navigation-ui-ktx:$nav_version"
implementation "androidx.navigation:navigation-dynamic-features-fragment:$nav_version"

... // dependencies closing }
우리는 모든 세 개의 의존항에 대해 하나의 변수를 사용하여 우리의 안드로이드 Jetpack 내비게이션 의존항 버전을 동기화할 것이다.
우리는 우리의 프로젝트를 구축하고 우리의 모든 의존항을 프로젝트에 융합시킬 수 있어야 한다. 지금부터 재미있는 일을 시작해야 한다🥩
응용 프로그램은 사용자 목록을 표시하고 선택한 사용자의 세부 정보 화면을 열어야 합니다.이 두 개의 스크린을 대표하기 위해 두 개의 세션을 제작합시다.
우리는 우선 우리가 사용할 User 대상을 만들 것이다.( Right click project folder > New > Kotlin File/Class > Class )
import android.os.Parcelable
import kotlinx.android.parcel.Parcelize

@Parcelize
data class User(val id: Int, val name: String, val age: Int): Parcelable {
    val description: String
        get() = "$name is $age years old."
}
여기서 우리는 몇 가지 속성만 제시함으로써 우리의 대상을 매우 간단하게 유지한다. 예를 들어 id, nameage이다.우리는 또한 Parcelable을 제작하여 단편 간에 그것을 전달할 수 있도록 했다.
사용자를 표시하는 세션을 계속 추가합니다(Right click project folder > New > Fragment > Fragment (List))

프로젝트에 의미 있는 이름으로 구성 요소를 설정할 것입니다. 이 경우 이름/대상은 User 대상을 둘러싸고 회전합니다.
이 과정을 완성하면 우리를 위해 많은 샘플 코드를 생성할 것이다.현재 우리의 프로젝트에는 다음과 같은 파일이 있어야 한다. UsersFragment, UsersRecyclerViewAdapter, fragment_users.xmlfragment_users_list.xml이다.
우리는 UsersFragment의 불필요한 코드를 제거하고 다음과 같은 방법으로 우리의 가상 데이터를 사용할 수 있다.
class UsersFragment : Fragment() {

    private val users = listOf<User>(
        User(1, "Kyle", 29),
        User(2, "Adri", 36),
        User(3, "Andy", 14),
        User(4, "Xayxay", 3),
        User(5, "Mya", 1)
    )

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val view = inflater.inflate(R.layout.fragment_users_list, container, false)

        if (view is RecyclerView) {
            with(view) {
                layoutManager = LinearLayoutManager(context)
                adapter = UsersRecyclerViewAdapter(users)
            }
        }
        return view
    }
}
UsersRecyclerViewAdapter은 자동으로 생성된 가상 대상을 필요로 하기 때문에 User 대상 목록을 전달하는 중 오류가 발생했습니다.우리가 이 문제를 해결합시다.
class UsersRecyclerViewAdapter(
    private val users: List<User>
) : RecyclerView.Adapter<UsersRecyclerViewAdapter.ViewHolder>() {

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        val view = LayoutInflater.from(parent.context)
            .inflate(R.layout.fragment_users, parent, false)
        return ViewHolder(view)
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        val user = users[position]
        holder.idView.text = user.id.toString()
        holder.contentView.text = user.name
    }

    override fun getItemCount(): Int = users.size

    inner class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
        val idView: TextView = view.findViewById(R.id.item_number)
        val contentView: TextView = view.findViewById(R.id.content)

        override fun toString(): String {
            return super.toString() + " '" + contentView.text + "'"
        }
    }
}
여기서 유일한 변경 사항은 values 속성을 users으로 변경하고 유형을 User으로 변경하는 것입니다.우리는 또한 관련 데이터를 ViewHolder 방법의 onBindViewHolder에 귀속시킬 것을 확보한다.
현재 UsersFragment이 올바르게 구성되었습니다. 새로운 UserDetailsFragment(Right click project folder > New > Fragment > Fragment (Blank))을 설정하겠습니다.
class UserDetailsFragment : Fragment() {

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val view = inflater.inflate(R.layout.fragment_user_details, container, false)

        return view
    }
}
또한 fragment_user_details.xml을 업데이트하여 미리 생성된 TextView이 화면 중앙에 위치하도록 합니다.
<?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=".UserDetailsFragment">

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hello_blank_fragment"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>
현재 우리는 이미 이 두 부분을 열거하였으며, 우리는 내비게이션 그림에서 그것들을 사용하려고 한다.
새로운 자원(Right click res folder > New > Android Resource File)을 만들고 nav_graph이라는 새로운 네비게이션 자원을 만듭니다

우리의 편집기는 지금 이렇게 해야 한다.

그림에 세션을 추가하려면 (+) 아이콘을 누르십시오.

내가 먼저 usersFragment을 추가했기 때문에 그 이름 옆에 집 아이콘이 하나 있는데 이것은 우리의 nav_graph의 입구점이 될 것이라고 표시한다.다른 순서로 추가하면 usersFragment을 선택하고 맨 위에 있는 하우스 아이콘을 누르면 시작 목적지로 사용할 수 있습니다.
나는 또한 네비게이션 조작 화살표를 userDetailsFragment으로 끌어당겨서 우리가 usersFragment에서 userDetailsFragment으로 네비게이션을 할 수 있어야 한다는 것을 지시했다.
이것은 좋은 응용 프로그램 흐름의 시각적 표시이지만, 만약 우리가 지금 응용 프로그램을 실행하려고 시도한다면, 우리는 실제적으로 우리의 usersFragment을 보지 못할 것이다.activity_main.xmlNavHostFragment으로 업데이트해야 합니다.TextView으로 activity_main.xml에서 미리 생성된 NavHostFragment을 대체하겠습니다.
<?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">

    <fragment
        android:id="@+id/fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:defaultNavHost="true"
        app:navGraph="@navigation/nav_graph" />

</androidx.constraintlayout.widget.ConstraintLayout>

Note
You might receive a warning here to use FragmentContainerView instead, but the Android documentation only specifies fragment at this stage, so we will continue to use it here.


우리는 nav_graph.xml으로 돌아갈 수 있다. 우리는 목적지 패널의 호스트 부분에서 activity_main을 보아야 한다.

현재 우리의 nav_graph은 이미 설치되어 있으며, User의 대상을 usersFragment에서 userDetailsFragment으로 전달할 것을 지정할 수 있습니다.
코드 nav_graph.xml에서 argument 속성에 userDetailsFragment을 추가할 수 있습니다.
... // other userDetailsFragment attributes

<argument
    android:name="user"
    app:argType="com.kiloloco.passing_data.User" />

... // </fragment> of userDetailsFragment
여기에서 우리는 안전 파라미터에 user이라는 파라미터가 있기를 희망하는 파라미터를 지정합니다. 이 파라미터의 유형은 User입니다.

Note
If you would like to see the different types of arguments you can pass to Safe Args, check out the Android Docs.


현재, 만약에 우리가 우리의 프로젝트를 구축한다면, 우리는 반드시 우리를 위해 UsersFragmentDirectionsUserDetailsFragmentArgs을 생성해야 한다.

이러한 생성된 객체는 세션 간에 매개변수를 전달할 때 유형 보안을 사용하고 전송 매개변수 값에 액세스하는 데 필요한 템플릿 파일을 삭제하는 데 도움을 줍니다.
선택한 UsersRecyclerViewAdapter의 전달과 수신을 처리하기 위해 UsersRecyclerViewAdapter.ViewHolderUser을 업데이트해야 합니다.
... // override fun getItemCount(): Int = users.size

inner class ViewHolder(view: View, var user: User? = null) : RecyclerView.ViewHolder(view) {

... // val idView: TextView = view.findViewById(R.id.item_number)
... // holder.contentView.text = user.name

holder.user = user

... // onBindViewHolder closing }
우리는 user에 null일 수 있는 ViewHolder 속성을 추가한 다음에 user 방법에서 holderonBindViewHolder 속성을 업데이트했습니다.
또한 ViewHolder을 업데이트하여 사용자의 선택과 UserDetailsFragment의 내비게이션을 실제적으로 처리할 것입니다.
... // val contentView: TextView = view.findViewById(R.id.content)

init {
    view.setOnClickListener {
        user?.let { user ->
            val directions = UsersFragmentDirections.actionUsersFragmentToUserDetailsFragment(user)
            view.findNavController().navigate(directions)
        }
    }
}

... // override fun toString(): String {
우리의 onClickListenter에서 우리는 userUsersFragmentDirections.actionUsersFragmentToUserDetailsFragment의 매개 변수로 전달할 것이다. 이 매개 변수는 User의 대상으로 예상된다.이것이 바로 우리가 추구하는 섹시형 안전이다🙌🏽directionsnav_graph에서 생성된 조작을 포함하고 있으며, 이 조작은 UsersFragment에서 UserDetailsFragment으로 생성된 흐름과 관련이 있습니다.User 대상을 UserDetailsFragmentArgs에서 접근할 수 있는 패키지로 전달합니다.
우리는 현재 UserDetailsFragment으로 이동하여 선택한 User의 수신을 처리할 수 있습니다.
... // class UserDetailsFragment : Fragment() {

private val args: UserDetailsFragmentArgs by navArgs()
private lateinit var user: User

... // 
우리는 navArgs()에 권한을 부여함으로써 우리의 논점을 얻을 수 있으며, lateinit var이 필요합니다. User에 걸립니다.
... // val view = inflater.inflate(R.layout.fragment_user_details, container, false)

user = args.user

... // return view
argsNavArgsLazy<UserDetailsFragmentArgs> 유형이기 때문에 우리는 파라미터에서 user 속성에 직접 접근하여 this.user에 저장할 수 있다.
... // onCreateView closing }

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    textView.text = user.description
}

... // UserDetailsFragment closing }
this.useronCreateView에서 업데이트됨에 따라 NonNull user에 방문하여 onViewCreated의 사용자 인터페이스를 업데이트할 수 있습니다.
응용 프로그램을 실행해서 예상대로 작동하는지 봅시다🤞🏽

지금, 이것은 매우 깨끗한 데이터 전달 방법입니다!✨

좋은 웹페이지 즐겨찾기