Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HW-4 DataBinding 적용 #543

Merged
merged 13 commits into from
Mar 28, 2020
Merged
5 changes: 3 additions & 2 deletions 2003/mtjin/AndroidArchitectureStudy/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ apply plugin: 'com.android.application'

apply plugin: 'kotlin-android'

apply plugin: 'kotlin-android-extensions'

apply plugin: 'kotlin-kapt'

android {
Expand All @@ -27,6 +25,9 @@ android {
targetCompatibility = "8"
sourceCompatibility = "8"
}
dataBinding {
enabled = true
}
}

dependencies {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,51 +2,44 @@ package com.mtjin.androidarchitecturestudy.ui.login

import android.content.Intent
import android.os.Bundle
import android.widget.Button
import android.widget.EditText
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.databinding.DataBindingUtil
import com.mtjin.androidarchitecturestudy.R
import com.mtjin.androidarchitecturestudy.data.login.source.LoginRepository
import com.mtjin.androidarchitecturestudy.data.login.source.LoginRepositoryImpl
import com.mtjin.androidarchitecturestudy.data.login.source.local.LoginLocalDataSource
import com.mtjin.androidarchitecturestudy.data.login.source.local.LoginLocalDataSourceImpl
import com.mtjin.androidarchitecturestudy.databinding.ActivityLoginBinding
import com.mtjin.androidarchitecturestudy.ui.search.MovieSearchActivity
import com.mtjin.androidarchitecturestudy.utils.PreferenceManager

class LoginActivity : AppCompatActivity(), LoginContract.View {
private lateinit var presenter: LoginContract.Presenter
private lateinit var etId: EditText
private lateinit var etPw: EditText
private lateinit var btnLogin: Button

private lateinit var binding: ActivityLoginBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_login)
initView()
initListener()
initDataBinding()
inject()
}

private fun initDataBinding() {
binding =
DataBindingUtil.setContentView(this, R.layout.activity_login)
binding.login = this
}

private fun inject() {
val preferenceManager = PreferenceManager(this)
val loginLocalDataSource: LoginLocalDataSource = LoginLocalDataSourceImpl(preferenceManager)
val loginRepository: LoginRepository = LoginRepositoryImpl(loginLocalDataSource)
presenter = LoginPresenter(this, loginRepository)
}

private fun initView() {
etId = findViewById(R.id.et_id)
etPw = findViewById(R.id.et_pw)
btnLogin = findViewById(R.id.btn_login)
}

private fun initListener() {
btnLogin.setOnClickListener {
val id = etId.text.toString().trim()
val pw = etPw.text.toString().trim()
presenter.doLogin(id, pw)
}
fun onLoginClick() {
val id = binding.etId.text.toString().trim()
val pw = binding.etPw.text.toString().trim()
presenter.doLogin(id, pw)
}


Expand All @@ -56,11 +49,11 @@ class LoginActivity : AppCompatActivity(), LoginContract.View {
}

override fun showIdEmptyError() {
etId.error = getString(R.string.id_empty_error_msg)
binding.etId.error = getString(R.string.id_empty_error_msg)
}

override fun showPwEmptyError() {
etPw.error = getString(R.string.pw_empty_error_msg)
binding.etPw.error = getString(R.string.pw_empty_error_msg)
}

override fun goMovieSearch() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,28 +1,28 @@
package com.mtjin.androidarchitecturestudy.ui.search

import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.RatingBar
import android.widget.TextView
import androidx.core.text.HtmlCompat
import androidx.databinding.DataBindingUtil
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.mtjin.androidarchitecturestudy.R
import com.mtjin.androidarchitecturestudy.data.search.Movie
import com.mtjin.androidarchitecturestudy.databinding.ItemMovieBinding

class MovieAdapter :
class MovieAdapter(private val itemClick: (Movie) -> Unit) :
RecyclerView.Adapter<MovieAdapter.ViewHolder>() {
private lateinit var clickCallBack: (Movie) -> Unit
lateinit var binding: ItemMovieBinding
private val items: ArrayList<Movie> = ArrayList()

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view: View = LayoutInflater.from(parent.context)
.inflate(R.layout.item_movie, parent, false)
val viewHolder = ViewHolder(view)
view.setOnClickListener {
clickCallBack(items[viewHolder.adapterPosition])
binding = DataBindingUtil.inflate(
LayoutInflater.from(parent.context),
R.layout.item_movie,
parent,
false
)
val viewHolder = ViewHolder(binding)
binding.root.setOnClickListener {
itemClick(items[viewHolder.adapterPosition])
}

return viewHolder
Expand All @@ -36,38 +36,20 @@ class MovieAdapter :
}
}

class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {

private val ivPoster = itemView.findViewById<ImageView>(R.id.iv_poster)
private val rvRating = itemView.findViewById<RatingBar>(R.id.rb_rating)
private val tvTitle = itemView.findViewById<TextView>(R.id.tv_title)
private val tvReleaseDate = itemView.findViewById<TextView>(R.id.tv_release_date)
private val tvActor = itemView.findViewById<TextView>(R.id.tv_actor)
private val tvDirector = itemView.findViewById<TextView>(R.id.tv_director)
class ViewHolder(private val binding: ItemMovieBinding) :
RecyclerView.ViewHolder(binding.root) {

fun bind(movie: Movie) {
with(movie) {
Glide.with(itemView).load(image)
.placeholder(R.drawable.ic_default)
.into(ivPoster!!)
rvRating.rating = (userRating.toFloatOrNull() ?: 0f) / 2
tvTitle.text = HtmlCompat.fromHtml(title, HtmlCompat.FROM_HTML_MODE_COMPACT)
tvReleaseDate.text = pubDate
tvActor.text = actor
tvDirector.text = director
}
binding.movie = movie
Hwangjunhong marked this conversation as resolved.
Show resolved Hide resolved
binding.executePendingBindings()
}
}

fun setItems(items: List<Movie>) {
fun addItems(items: List<Movie>) {
this.items.addAll(items)
notifyDataSetChanged()
}

fun setItemClickListener(clickCallBack: (Movie) -> Unit) {
this.clickCallBack = clickCallBack
}

fun clear() {
this.items.clear()
notifyDataSetChanged()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,21 @@ import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.view.View
import android.widget.Button
import android.widget.EditText
import android.widget.ProgressBar
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.databinding.DataBindingUtil
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.mtjin.androidarchitecturestudy.R
import com.mtjin.androidarchitecturestudy.data.search.Movie
import com.mtjin.androidarchitecturestudy.databinding.ActivityMovieSearchBinding
import com.mtjin.androidarchitecturestudy.utils.MyApplication


class MovieSearchActivity : AppCompatActivity(), MovieSearchContract.View {

private lateinit var binding: ActivityMovieSearchBinding
private lateinit var presenter: MovieSearchContract.Presenter
private lateinit var etInput: EditText
private lateinit var btnSearch: Button
private lateinit var rvMovies: RecyclerView
private lateinit var pbLoading: ProgressBar
private lateinit var movieAdapter: MovieAdapter
private lateinit var myApplication: MyApplication
private lateinit var query: String
Expand All @@ -31,54 +27,48 @@ class MovieSearchActivity : AppCompatActivity(), MovieSearchContract.View {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_movie_search)

initView()
initDataBinding()
inject()
initAdapter()
initListener()
presenter = MovieSearchPresenter(this, myApplication.movieRepository)
}

private fun initView() {
private fun initDataBinding() {
binding = DataBindingUtil.setContentView(this, R.layout.activity_movie_search)
binding.search = this
}

private fun inject() {
myApplication = application as MyApplication
etInput = findViewById(R.id.et_input)
btnSearch = findViewById(R.id.btn_search)
rvMovies = findViewById(R.id.rv_movies)
pbLoading = findViewById(R.id.pb_loading)
presenter = MovieSearchPresenter(this, myApplication.movieRepository)
}

private fun initAdapter() {
movieAdapter = MovieAdapter()
val linearLayoutManager = LinearLayoutManager(this)
rvMovies.layoutManager = linearLayoutManager
scrollListener = object : EndlessRecyclerViewScrollListener(linearLayoutManager) {
movieAdapter = MovieAdapter { movie ->
Intent(Intent.ACTION_VIEW, Uri.parse(movie.link)).takeIf {
it.resolveActivity(packageManager) != null
}?.run(this::startActivity)
}
scrollListener = object :
EndlessRecyclerViewScrollListener(binding.rvMovies.layoutManager as LinearLayoutManager) {
Comment on lines +51 to +52
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

커밋에 xml에 linearlayoutManager 추가하는 코드가 빠진것같아요 ~~

Copy link
Contributor Author

@mtjin mtjin Mar 24, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

기존에 xml에 linearlayoutManager 추가 되있었습니다~
image

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

앗그렇군요 ... 제가못봤었네요 @sooakim approve하였습니다 ~~

override fun onLoadMore(page: Int, totalItemsCount: Int, view: RecyclerView?) {
presenter.requestPagingMovie(query, totalItemsCount + 1)
}
}
rvMovies.addOnScrollListener(scrollListener)
rvMovies.adapter = movieAdapter
binding.rvMovies.addOnScrollListener(scrollListener)
binding.rvMovies.adapter = movieAdapter
}

private fun initListener() {
//어댑터 아이템 클릭리스너
movieAdapter.setItemClickListener { movie ->
Intent(Intent.ACTION_VIEW, Uri.parse(movie.link)).takeIf {
it.resolveActivity(packageManager) != null
}?.run(this::startActivity)
}
//검색버튼
btnSearch.setOnClickListener {
query = etInput.text.toString().trim()
presenter.requestMovie(query)
}
fun onSearchClick() {
query = binding.etInput.text.toString().trim()
presenter.requestMovie(query)
}

override fun showLoading() {
pbLoading.visibility = View.VISIBLE
binding.pbLoading.visibility = View.VISIBLE
}

override fun hideLoading() {
pbLoading.visibility = View.GONE
binding.pbLoading.visibility = View.GONE
}

override fun showToast(msg: String) {
Expand Down Expand Up @@ -111,12 +101,12 @@ class MovieSearchActivity : AppCompatActivity(), MovieSearchContract.View {

override fun searchMovieSuccess(movieList: List<Movie>) {
movieAdapter.clear()
movieAdapter.setItems(movieList)
movieAdapter.addItems(movieList)
Toast.makeText(this, getString(R.string.load_movie_success_msg), Toast.LENGTH_SHORT).show()
}

override fun pagingMovieSuccess(movieList: List<Movie>) {
movieAdapter.setItems(movieList)
movieAdapter.addItems(movieList)
Toast.makeText(this, getString(R.string.load_movie_success_msg), Toast.LENGTH_SHORT).show()
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package com.mtjin.androidarchitecturestudy.utils

import android.widget.ImageView
import android.widget.RatingBar
import android.widget.TextView
import androidx.core.text.HtmlCompat
import androidx.databinding.BindingAdapter
import com.bumptech.glide.Glide
import com.mtjin.androidarchitecturestudy.R


@BindingAdapter("htmlText")
fun setHtmlText(textView: TextView, html: String) {
HtmlCompat.fromHtml(html, HtmlCompat.FROM_HTML_MODE_COMPACT)
}

@BindingAdapter("urlImage")
fun setUrlImage(imageView: ImageView, url: String) {
Glide.with(imageView).load(url)
.placeholder(R.drawable.ic_default)
.into(imageView)
}

@BindingAdapter("movieRating")
fun setMovieRating(ratingBar: RatingBar, score: String) {
ratingBar.rating = (score.toFloatOrNull() ?: 0f) / 2
}

/*
확장함수 사용 필기용입니다.
@BindingAdapter("app:movieRating")
fun RatingBar.setMovieRating(score: String) {
rating = (score.toFloatOrNull() ?: 0f) / 2
}
*/