安全なARGSとデータを渡す
29731 ワード
AndroidのJetpackは、ベストプラクティスを奨励しながら開発をスピードアップするいくつかのツールとのデメリットを提供することにより、生活を容易にすることを目指しています.我々が今日焦点を合わせるつもりであるツールはナビゲーションコンポーネントで、安全なargsでデータを渡します.
セーフARGSは、宛先間のデータをナビゲートして渡すときにタイプセーフティを与えるGradleプラグインです.
我々は、含まれているフラグメントのユーザーの一覧が表示されますシンプルなアプリを作成することによって、これらの概念を探索されます
我々は、空の活動で新しいAndroidXプロジェクトで、ゼロから始めます.
依存関係を設定することから始めましょう.
プロジェクトで
我々はプロジェクトを構築することができなければなりません、我々の依存関係の全てをプロジェクトに入れて、現在、ジューシーなものに🥩
我々のアプリは、選択したユーザーの詳細画面を開くことができるユーザーのリストを表示する必要があります.それらのスクリーンの両方を表す2つの断片を作りましょう.
を作成して起動します
前に進んで、我々のユーザーを示すために責任がある断片を加えましょう
私のプロジェクトを意味する名前でコンポーネントを設定します
このプロセスを通過する私たちのためのボイラープレートコードの多くを生成します.プロジェクトには次のファイルがあります.
我々は多くの不要なコードを取り除くことができます
今我々
新しいリソースを作成する
エディタは次のようになります.
をクリックしてグラフにフラグメントを追加しましょう.
私は
私も、ナビゲーションアクション矢を
これは我々のアプリの流れの素晴らしい視覚的な表現ですが、我々は今、アプリを実行しようとすると、我々は実際には見ていないだろう
プリジェネレーションを置換しましょう
我々は、我々のもとに戻ることができます
今我々
のコードで
我々がプロジェクトを構築するならば、我々はそうしなければなりません
これらの生成されたオブジェクトは、渡された引数の値にアクセスするために必要なBoilerplateの一部を削除するのと同様に、フラグメント間の引数を渡すときに、型安全性を使用するのに役立ちます.
我々は更新する必要があります
更新しましょう
The
我々は、現在のところに向かうことができます
私たちのアプリの実行を与えるし、それが期待通りに動作するかどうかを確認してみましょう🤞🏽
今それはいくつかのデータを渡すためにきれいなきれいな方法です!✨
セーフ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
and NavDirections
我々のために.... // android {
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = "1.8"
}
... // android closing }
Java 8は、安全なARGSで動作する最小限の要件です.... // 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 }
我々は、3つの依存関係のすべての1つの変数を使用して、同期でAndroidのJetpackナビゲーションバージョンを同期させます.我々はプロジェクトを構築することができなければなりません、我々の依存関係の全てをプロジェクトに入れて、現在、ジューシーなものに🥩
我々のアプリは、選択したユーザーの詳細画面を開くことができるユーザーのリストを表示する必要があります.それらのスクリーンの両方を表す2つの断片を作りましょう.
を作成して起動します
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
, and age
. 我々もそれを作っているParcelable
それで、我々は断片の間でそれを通過することができます.前に進んで、我々のユーザーを示すために責任がある断片を加えましょう
Right click project folder > New > Fragment > Fragment (List)
)私のプロジェクトを意味する名前でコンポーネントを設定します
User
オブジェクト.このプロセスを通過する私たちのためのボイラープレートコードの多くを生成します.プロジェクトには次のファイルがあります.
UsersFragment
, UsersRecyclerViewAdapter
, fragment_users.xml
, and 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
and the type to 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
to 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
to userDetailsFragment
.のコードで
nav_graph.xml
, 今すぐ追加することができますargument
内部userDetailsFragment
属性... // other userDetailsFragment attributes
<argument
android:name="user"
app:argType="com.kiloloco.passing_data.User" />
... // </fragment> of userDetailsFragment
ここでは、私たちが安全なargsに引数と呼ばれるものが欲しいと指定しています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
and UserDetailsFragmentArgs
生成されます.これらの生成されたオブジェクトは、渡された引数の値にアクセスするために必要なBoilerplateの一部を削除するのと同様に、フラグメント間の引数を渡すときに、型安全性を使用するのに役立ちます.
我々は更新する必要があります
UsersRecyclerViewAdapter
and 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
私たちの財産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
オブジェクトそれは私たちが後にしたセクシーなタイプの安全です🙌🏽The
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 }
With this.user
更新onCreateView
, 我々はアクセスできますNonNull
user
UIを更新するにはonViewCreated
.私たちのアプリの実行を与えるし、それが期待通りに動作するかどうかを確認してみましょう🤞🏽
今それはいくつかのデータを渡すためにきれいなきれいな方法です!✨
Reference
この問題について(安全なARGSとデータを渡す), 我々は、より多くの情報をここで見つけました https://dev.to/kilo_loco/passing-data-with-safe-args-using-android-jetpack-hh1テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol