Android Jetpack을 사용하여 보안 매개 변수를 통해 데이터 전달
29972 단어 androidandroidjetpackkotlin
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 {
이 플러그인은 NavArgs
과 NavDirections
을 생성합니다.... // 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
, name
과 age
이다.우리는 또한 Parcelable
을 제작하여 단편 간에 그것을 전달할 수 있도록 했다.사용자를 표시하는 세션을 계속 추가합니다(
Right click project folder > New > Fragment > Fragment (List)
)프로젝트에 의미 있는 이름으로 구성 요소를 설정할 것입니다. 이 경우 이름/대상은
User
대상을 둘러싸고 회전합니다.이 과정을 완성하면 우리를 위해 많은 샘플 코드를 생성할 것이다.현재 우리의 프로젝트에는 다음과 같은 파일이 있어야 한다.
UsersFragment
, UsersRecyclerViewAdapter
, fragment_users.xml
과 fragment_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.xml
을 NavHostFragment
으로 업데이트해야 합니다.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 useFragmentContainerView
instead, but the Android documentation only specifiesfragment
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.
현재, 만약에 우리가 우리의 프로젝트를 구축한다면, 우리는 반드시 우리를 위해
UsersFragmentDirections
과 UserDetailsFragmentArgs
을 생성해야 한다.이러한 생성된 객체는 세션 간에 매개변수를 전달할 때 유형 보안을 사용하고 전송 매개변수 값에 액세스하는 데 필요한 템플릿 파일을 삭제하는 데 도움을 줍니다.
선택한
UsersRecyclerViewAdapter
의 전달과 수신을 처리하기 위해 UsersRecyclerViewAdapter.ViewHolder
과 User
을 업데이트해야 합니다.... // 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
방법에서 holder
의 onBindViewHolder
속성을 업데이트했습니다.또한
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
에서 우리는 user
을 UsersFragmentDirections.actionUsersFragmentToUserDetailsFragment
의 매개 변수로 전달할 것이다. 이 매개 변수는 User
의 대상으로 예상된다.이것이 바로 우리가 추구하는 섹시형 안전이다🙌🏽directions
은 nav_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
args
은 NavArgsLazy<UserDetailsFragmentArgs>
유형이기 때문에 우리는 파라미터에서 user
속성에 직접 접근하여 this.user
에 저장할 수 있다.... // onCreateView closing }
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
textView.text = user.description
}
... // UserDetailsFragment closing }
this.user
이 onCreateView
에서 업데이트됨에 따라 NonNull
user
에 방문하여 onViewCreated
의 사용자 인터페이스를 업데이트할 수 있습니다.응용 프로그램을 실행해서 예상대로 작동하는지 봅시다🤞🏽
지금, 이것은 매우 깨끗한 데이터 전달 방법입니다!✨
Reference
이 문제에 관하여(Android Jetpack을 사용하여 보안 매개 변수를 통해 데이터 전달), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/kilo_loco/passing-data-with-safe-args-using-android-jetpack-hh1텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)