2023. 1. 26. 02:34ㆍAndroid Jetpack
저번에 했던 Jetpack Navigation 이 적용된 프로젝트에서 Safe Args를 사용하여 Fragment 간의 데이터를 주고받는 방법과 WebView를 이용해서 책에 정보를 Parcelable로 이용해 보여주는 방법까지 알아보겟습니다.
1. Safe Args을 추가
- build.gradle(프로젝트)
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
google()
}
dependencies {
classpath("androidx.navigation:navigation-safe-args-gradle-plugin:2.5.3")
}
}
- build.gradle(앱 모듈)
plugins {
//Safe Args
id "androidx.navigation.safeargs.kotlin"
Navigation | Android 개발자 | Android Developers
Navigation | Android 개발자 | Android Developers
컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요. Navigation Navigation은 Android 애플리케이션 내에서 '대상' 사이를 탐색하는 프레임워크로, 대상이 Fragment, Activity
developer.android.com
2. Parcelable을 추가
- build.grdle(앱 모듈)
plugins {
id "kotlin-parcelize"
}
Parcelable 구현 생성기 | Android 개발자 | Android Developers
Parcelable 구현 생성기 | Android 개발자 | Android Developers
Parcelable 구현 생성기 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요. kotlin-parcelize 플러그인은 Parcelable 구현 생성기를 제공합니다. Parcelable 지원을 포함하려
developer.android.com
- Book
package com.example.kakaobook.ui.view.data.model
import android.os.Parcelable
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import kotlinx.parcelize.Parcelize
@Parcelize
@JsonClass(generateAdapter = true)
data class Book(
@Json(name = "authors")
val authors: List<String>,
@Json(name = "contents")
val contents: String,
@Json(name = "datetime")
val datetime: String,
@Json(name = "isbn")
val isbn: String,
@Json(name = "price")
val price: Int,
@Json(name = "publisher")
val publisher: String,
@Json(name = "sale_price")
val salePrice: Int,
@Json(name = "status")
val status: String,
@Json(name = "thumbnail")
val thumbnail: String,
@Json(name = "title")
val title: String,
@Json(name = "translators")
val translators: List<String>,
@Json(name = "url")
val url: String
) : Parcelable
-> @Parcelize로 클래스에 주석을 달면 다음 같이 Parcelable 구현이 자동으로 생성됩니다.
- 데이터를 전달받을 Fragment를 생성해준다.
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".ui.view.ui.view.BookFragment">
<WebView
android:id="@+id/webview"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
-> Webview를 통해 전달받을 ui를 구현햇습니다.
- booksearch_nav_graph.xml 로 가서 새로만들엇던 Frgment를 New Destination해주자
- 데이터를 전달받을 Fragment_book 에 Argument를 추가한다.
전달할 데이터의 타입이 기초 타입인 경우는 전달할 데이터 타입에 맞춰서 선택해 주면 되고,
그 외의 경우에는 Custom Parcelable을 선택한다. 선택하면 [Select Class]란 창이 뜨는데 내가 정의한 데이터 클래스 중 Parcelable의 구현인 클래스만 뜨게 된다. 전달하고 싶은 데이터의 타입을 선택해 주면 된다.
-> 위의 이미지에서 fragment_search, fragment_favoirte가 fragment_book으로 데이터 전달이 이루어진다고 가정했고,
fragment_book에 Argument(전달받을 데이터)를 추가해주엇다.
- SearchFragment 에서 검색결과를 수행햇을때 fragment_book에 데이터를 전달해주도록합니다.
1.BookSearchAdpater에서 뷰홀더 클래스안에 setonItemclicklister를 만들어준다.
package com.example.kakaobook.ui.view.ui.view.adapter
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import com.example.kakaobook.databinding.ItemBookViewBinding
import com.example.kakaobook.ui.view.data.model.Book
class BookSearchAdapter : ListAdapter<Book, BookSearchViewHolder>(diffUtilCallback) {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BookSearchViewHolder {
return BookSearchViewHolder(
ItemBookViewBinding.inflate(LayoutInflater.from(parent.context), parent, false)
)
}
override fun onBindViewHolder(holder: BookSearchViewHolder, position: Int) {
holder.bind(currentList[position])
holder.itemView.setOnClickListener {
onItemClickListener?.let { it(currentList[position])}
}
}
private var onItemClickListener: ((Book) -> Unit)? = null
fun setOnItemClickListener(listener: (Book) -> Unit) {
onItemClickListener = listener
}
companion object {
private val diffUtilCallback = object : DiffUtil.ItemCallback<Book>() {
override fun areItemsTheSame(oldItem: Book, newItem: Book): Boolean {
return oldItem == newItem
}
override fun areContentsTheSame(oldItem: Book, newItem: Book): Boolean {
return oldItem.isbn == newItem.isbn
}
}
}
}
-> 클릭 이벤트를 받은 뷰홀더를 특정하는 역할을 어댑터가 수행해야 하기 때문에 setOnItemClickListener함수가 실행되었을때 책에 정보를 보여주도록한다.
2. SearchFragment
private fun setupRecyclerView() {
bookSearchAdapter = BookSearchAdapter()
binding.SearchResult.layoutManager = LinearLayoutManager(context)
binding.SearchResult.adapter = bookSearchAdapter
bookSearchAdapter.setOnItemClickListener {
findNavController().navigate(SearchFragmentDirections.actionFragmentSearchToFrgmentBook(it))
}
}
-> 어댑터에 클릭이벤트를받앗을때 navigate에 바꿔줄 프래그먼트를 SearchFragment에서 BookFragment로 교체되는걸알수있다.
3. BookFragment
package com.example.kakaobook.ui.view.ui.view
import android.annotation.SuppressLint
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.webkit.WebViewClient
import androidx.fragment.app.Fragment
import androidx.navigation.fragment.navArgs
import com.example.kakaobook.databinding.FragmentBookBinding
class BookFragment : Fragment() {
private var mbinding : FragmentBookBinding? = null
private val binding get() = mbinding!!
private val args by navArgs<BookFragmentArgs>()
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
mbinding = FragmentBookBinding.inflate(inflater, container, false)
return binding.root
}
@SuppressLint("SetJavaScriptEnabled")
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.webview.apply {
webViewClient = WebViewClient()
settings.javaScriptEnabled = true
loadUrl(args.book.url)
}
}
override fun onPause() {
binding.webview.onPause()
super.onPause()
}
override fun onResume() {
binding.webview.onResume()
super.onResume()
}
override fun onDestroyView() {
mbinding = null
super.onDestroyView()
}
}
-> 먼저 by navArgs 를 사용해 args 를 나중에 초기화시키겟다.
웹 애플리케이션 또는 웹페이지만 클라이언트 애플리케이션의 일부로 제공하려는 경우 WebView를 사용한다.
webview에서 webviewClient를연결해준다. webview에 연결된 Setting을 통해 javascript 가 사용가능 하도록 true로 설정해준다.
webview에서 웹페이지를 로드하려면 loadurl()을 사용해 전달받은 url 값을 webview에 표시해준다.
출처 :WebView에서 웹 앱 빌드 | Android 개발자 | Android Developers
WebView에서 웹 앱 빌드 | Android 개발자 | Android Developers
WebView에서 웹 앱 빌드 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요. 웹 애플리케이션 또는 웹페이지만 클라이언트 애플리케이션의 일부로 제공하려는 경
developer.android.com
'Android Jetpack' 카테고리의 다른 글
Room DB를 UI와 연동하기 (0) | 2023.01.30 |
---|---|
책 검색결과 저장을 위한 Room DB 구현해보기 (0) | 2023.01.27 |
Navigation으로 UI의 화면전환 구현하기 (0) | 2023.01.25 |
책 검색 앱 만들기(4) - 검색결과를 UI에 표시하기 (0) | 2023.01.20 |
책 검색 앱 만들기(3)- Android App Architecture 적용하기 (0) | 2023.01.19 |