도서 리뷰 앱 Part 4(Parcelize)
Parcelize 사용하기
id 'kotlin-parcelize'
@Parcelize
data class Book(
@SerializedName("itemId")val id:Long,
@SerializedName("title")val title:String,
@SerializedName("description")val description:String,
@SerializedName("coverSmallUrl")val coverSmallUrl:String
) : Parcelable
디테일 화면 생성, 스크롤뷰 사용
<?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"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ScrollView
android:id="@+id/scrollView"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/titleTextView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:textColor="@color/black"
android:textSize="24sp"
android:gravity="center"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/coverImageView"
android:layout_width="300dp"
android:layout_height="300dp"
app:layout_constraintTop_toBottomOf="@id/titleTextView"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:layout_marginTop="16dp"/>
<TextView
android:id="@+id/descriptionTextView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:textSize="16sp"
app:layout_constraintTop_toBottomOf="@id/coverImageView"
app:layout_constraintStart_toStartOf="parent"
android:layout_margin="16dp"
app:layout_constraintEnd_toEndOf="parent"
android:textColor="@color/black"/>
<EditText
android:id="@+id/reviewEditText"
android:layout_width="0dp"
android:layout_height="300dp"
app:layout_constraintTop_toBottomOf="@id/descriptionTextView"
android:layout_margin="16dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
<Button
android:id="@+id/saveButton"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@id/reviewEditText"
app:layout_constraintStart_toStartOf="parent"
android:text="save"
android:layout_margin="16dp"
app:layout_constraintEnd_toEndOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>
북 어뎁터에 인터페이스 추가
// 추가 된 인터페이스
interface OnItemClickedListener{
fun onItemClicked(bookModel:Book)
}
var onItemClickedListener:OnItemClickedListener? = null
inner class BookItemViewHolder(private val binding: ItemBookBinding) :RecyclerView.ViewHolder(binding.root) {
fun bind(bookModel:Book){
binding.titleTextView.text = bookModel.title
binding.descriptionTextView.text = bookModel.description
Glide
.with(binding.titleTextView.context)
.load(bookModel.coverSmallUrl)
.into(binding.coverImageView)
binding.root.setOnClickListener {
onItemClickedListener?.onItemClicked(bookModel)
}
}
}
클릭리스너 넘겨주기
// 메인 엑티비티에서 어뎁터 구현할 때 리스너 객체 만들기
adapter.onItemClickedListener = object :BookAdapter.OnItemClickedListener{
override fun onItemClicked(bookModel: Book) {
val intent = Intent(applicationContext, DetailActivity::class.java)
// 위에서 직렬화 한 오브젝트를 넘겨주기
intent.putExtra("bookModel", bookModel)
startActivity(intent)
}
}
Review Model(Entity), ReviewDao 인터페이스 생성, 데이터베이스에 DAO 추가
// Review.kotlin
@Entity
data class Review(
@PrimaryKey val id:Int?,
@ColumnInfo(name = "review") val review:String?
)
// ReviewDao.kt
@Dao
interface ReviewDao {
@Query("select * from review where id ==:id")
fun getOneReview(id:Int): Review?
// 대체 삽입
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun saveReview(review:Review)
}
// AppDatabase.kt
@Database(entities = [History::class, Review::class], version =2)
abstract class AppDatabase:RoomDatabase() {
abstract fun historyDao() : HistoryDao
abstract fun reviewDao() : ReviewDao
}
Detail 엑티비티 생성
// DetailActicity.kt
class DetailActivity : AppCompatActivity() {
lateinit var binding:ActivityDetailBinding
lateinit var db:AppDatabase
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityDetailBinding.inflate(layoutInflater)
setContentView(binding.root)
initDB()
initLayout()
}
// 디비 생성
private fun initDB() {
db = Room.databaseBuilder(
applicationContext,
AppDatabase::class.java,
"BookSearchDB"
).build()
}
// 레이아웃 초기화
private fun initLayout() {
val model = intent.getParcelableExtra<Book>("bookModel")
binding.titleTextView.text = model?.title
binding.descriptionTextView.text = model?.description
Glide
.with(this)
.load(model?.coverSmallUrl)
.into(binding.coverImageView)
binding.saveButton.setOnClickListener {
Thread{
db.reviewDao().saveReview(Review(model?.id?.toInt() ?: 0, binding.reviewEditText.text.toString()))
}.start()
}
Thread{
val review = db.reviewDao().getOneReview(model?.id?.toInt() ?: 0)
runOnUiThread{
binding.reviewEditText.setText(review?.review.toString() ?: "")
}
}.start()
}
}