Skip to content

Commit

Permalink
Merge pull request #96 from pknu-wap/#91/enhancement/jsp/app_enhancement
Browse files Browse the repository at this point in the history
#91/enhancement/jsp/app enhancement
  • Loading branch information
pknujsp authored Jun 2, 2023
2 parents 48c2b3b + dad2251 commit 7e18ba4
Show file tree
Hide file tree
Showing 115 changed files with 2,091 additions and 967 deletions.
1 change: 1 addition & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ dependencies {
implementation(project(":core:data"))
implementation(project(":core:ui"))
implementation(project(":core:model"))
implementation(project(":core:database"))


implementation(project(":feature:interestedmedicine"))
Expand Down
42 changes: 29 additions & 13 deletions app/src/main/java/com/android/mediproject/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,16 @@ import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
import androidx.navigation.NavController
import androidx.navigation.fragment.NavHostFragment
import androidx.navigation.ui.setupWithNavController
import com.android.mediproject.core.ui.WindowViewModel
import com.android.mediproject.core.ui.base.BaseActivity
import com.android.mediproject.databinding.ActivityMainBinding
import dagger.hilt.android.AndroidEntryPoint
import repeatOnStarted

@AndroidEntryPoint
class MainActivity :
BaseActivity<ActivityMainBinding, MainViewModel>(ActivityMainBinding::inflate) {
class MainActivity : BaseActivity<ActivityMainBinding, MainViewModel>(ActivityMainBinding::inflate) {

private val windowViewModel: WindowViewModel by viewModels()

companion object {
const val VISIBLE = 0
Expand All @@ -44,8 +46,7 @@ class MainActivity :
}

binding.apply {
val navHostFragment =
supportFragmentManager.findFragmentById(R.id.fragmentContainerView) as NavHostFragment
val navHostFragment = supportFragmentManager.findFragmentById(R.id.fragmentContainerView) as NavHostFragment
navController = navHostFragment.navController

bottomNav.apply {
Expand All @@ -60,10 +61,26 @@ class MainActivity :
viewModel = activityViewModel.apply {
repeatOnStarted { eventFlow.collect { handleEvent(it) } }
}

root.viewTreeObserver.addOnPreDrawListener(object : ViewTreeObserver.OnPreDrawListener {
override fun onPreDraw(): Boolean {
if (bottomAppBar.height > 0) {
root.viewTreeObserver.removeOnPreDrawListener(this)
/**
val containerHeight = root.height - bottomAppBar.height
windowViewModel.setBottomNavHeight(containerHeight)
fragmentContainerView.layoutParams = CoordinatorLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT, containerHeight
)
*/
}
return true
}
})
}
}

override fun setSplash(){
override fun setSplash() {
installSplashScreen()
}

Expand Down Expand Up @@ -91,15 +108,14 @@ class MainActivity :
*
* argument 를 통해 bottomNav 를 숨길지 말지 결정한다.
*/
private fun setDestinationListener() =
navController.addOnDestinationChangedListener { _, destination, arg ->
log(arg.toString())
if (destination.id in hideBottomNavDestinationIds) {
bottomVisible(INVISIBLE)
} else {
bottomVisible(VISIBLE)
}
private fun setDestinationListener() = navController.addOnDestinationChangedListener { _, destination, arg ->
log(arg.toString())
if (destination.id in hideBottomNavDestinationIds) {
bottomVisible(INVISIBLE)
} else {
bottomVisible(VISIBLE)
}
}

private fun bottomVisible(isVisible: Int) {
log(isVisible.toString())
Expand Down
1 change: 1 addition & 0 deletions app/src/main/res/layout/activity_main.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
</data>

<androidx.coordinatorlayout.widget.CoordinatorLayout
android:id="@+id/mainLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent">
Expand Down
1 change: 1 addition & 0 deletions app/src/main/res/navigation/main_nav.xml
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,6 @@
<include app:graph="@navigation/interestedmedicine_nav" />
<include app:graph="@navigation/camera_nav" />
<include app:graph="@navigation/medicine_details_nav" />
<include app:graph="@navigation/search_medicines_nav" />

</navigation>
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ plugins {
alias(libs.plugins.kotlin.android) apply false
alias(libs.plugins.nav.safeargs.kotlin) apply false
alias(libs.plugins.kapt) apply false
//alias(libs.plugins.ksp) apply false
// alias(libs.plugins.ksp) apply false
alias(libs.plugins.kotlin.parcelize) apply false
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package com.android.mediproject.core.common.adapter

import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.annotation.IdRes
import androidx.databinding.DataBindingUtil
import androidx.databinding.ViewDataBinding
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.RecyclerView.ViewHolder

/**
* 귀찮음 줄여주는 ListAdapter
*
* @param T : ListAdapter에 들어갈 아이템 타입
* @param V : ViewDataBinding
* @param differ : DiffUtil.ItemCallback<T>
* - ListAdapter의 DiffUtil.ItemCallback
* - 아이템이 같은지 비교하는 메소드를 구현해야함
* @param initViewHolder : (((CViewHolder<T, V>) -> Unit)
* - ViewHolder 초기화
* - ex) { holder -> ViewHolder class init 시 필요한 작업 처리 }
* @param onBind : (CViewHolder<T, V>, T, Int) -> Unit
* - ViewHolder 바인딩
* - ex) { holder, item, position -> 필요한 작업 처리 }
* @param itemViewId : Int
* - ViewHolder의 itemView id
* - ex) R.layout.item_view
*
*/
abstract class GodBindListAdapter<T, V : ViewDataBinding>(
differ: DiffUtil.ItemCallback<T>,
private val initViewHolder: ((GodBindViewHolder<T, V>) -> Unit)?,
private val onBind: (GodBindViewHolder<T, V>, T, Int) -> Unit,
@IdRes private val itemViewId: Int
) : ListAdapter<T, GodBindViewHolder<T, V>>(differ) {

private var _inflater: LayoutInflater? = null
private val inflater get() = _inflater!!

override fun onAttachedToRecyclerView(recyclerView: RecyclerView) {
super.onAttachedToRecyclerView(recyclerView)
_inflater = null
_inflater = LayoutInflater.from(recyclerView.context)
}

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): GodBindViewHolder<T, V> =
GodBindViewHolder(DataBindingUtil.inflate<V>(inflater, itemViewId, parent, false), initViewHolder, onBind)


override fun onBindViewHolder(holder: GodBindViewHolder<T, V>, position: Int) {
holder.bind(getItem(position))
}

override fun onDetachedFromRecyclerView(recyclerView: RecyclerView) {
super.onDetachedFromRecyclerView(recyclerView)
_inflater = null
}
}

class GodBindViewHolder<T, V : ViewDataBinding>(
private val binding: V,
private val initViewHolder: ((GodBindViewHolder<T, V>) -> Unit)?,
private val onBind: (GodBindViewHolder<T, V>, T, Int) -> Unit,
) : ViewHolder(binding.root) {

init {
initViewHolder?.invoke(this)
}

fun bind(item: T) {
onBind.invoke(this, item, absoluteAdapterPosition)
binding.executePendingBindings()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package com.android.mediproject.core.common.bindingadapter

import android.graphics.Bitmap
import android.text.Spanned
import android.view.View
import android.widget.EditText
import android.widget.ImageView
import android.widget.TextView
import androidx.core.text.PrecomputedTextCompat
Expand All @@ -26,22 +28,45 @@ object BindingAdapter {
@BindingAdapter("img")
@JvmStatic
fun loadImage(imageView: ImageView, img: String) {
GlideApp.with(imageView.context).load(img).centerInside().skipMemoryCache(false).into(imageView)
GlideApp.with(imageView.context).load(img).centerInside().skipMemoryCache(false)
.into(imageView)
}

@BindingAdapter("img")
@JvmStatic
fun loadImage(imageView: ImageView, img: Bitmap) {
GlideApp.with(imageView.context).load(img).centerInside().skipMemoryCache(false).into(imageView)
GlideApp.with(imageView.context).load(img).centerInside().skipMemoryCache(false)
.into(imageView)
}


/**
* TextView에 비동기적으로 텍스트를 설정합니다.
*/
@BindingAdapter("asyncText")
@JvmStatic
fun setAsyncText(textView: TextView, text: Spanned?) {
if (text != null) {
val precomputedText = PrecomputedTextCompat.create(text, TextViewCompat.getTextMetricsParams(textView))
val precomputedText =
PrecomputedTextCompat.create(text, TextViewCompat.getTextMetricsParams(textView))
TextViewCompat.setPrecomputedText(textView, precomputedText)
}
}

/**
* EditText의 텍스트를 전달받은 ViewModel의 onClickedSendButton 함수에 전달하고, EditText의 텍스트를 지웁니다.
*
* @param view 클릭 이벤트를 받을 View
* @param editText 텍스트를 전달받을 EditText
* @param iSendText 텍스트를 전달받을 ViewModel
*/
@BindingAdapter("onClickSend", "inputText")
@JvmStatic
fun setOnClick(view: View, iSendText: ISendText, editText: EditText) {
view.setOnClickListener {
iSendText.onClickedSendButton(editText.text)
editText.text.clear()
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.android.mediproject.core.common.bindingadapter

interface ISendText {
fun onClickedSendButton(text: CharSequence)
}
Original file line number Diff line number Diff line change
@@ -1,25 +1,23 @@
package com.android.mediproject.core.common.dialog

import android.content.Context
import android.view.ViewGroup
import androidx.appcompat.app.AlertDialog
import com.google.android.material.dialog.MaterialAlertDialogBuilder

object LoadingDialog {

private var dialog: AlertDialog? = null

fun showLoadingDialog(context: Context, textMessage: String?) {
dismiss()
AlertDialog.Builder(context).setView(ProgressIndicator(context, null, textMessage)).setCancelable(false).create().also {
it.window?.setBackgroundDrawableResource(android.R.color.transparent)
it.window?.attributes = it.window?.attributes?.apply {
width = ViewGroup.LayoutParams.WRAP_CONTENT
height = ViewGroup.LayoutParams.WRAP_CONTENT
MaterialAlertDialogBuilder(context).setView(ProgressIndicator(context, textMessage))
.setCancelable(false).create().also {
it.setCanceledOnTouchOutside(false)
it.window?.setBackgroundDrawableResource(android.R.color.transparent)
dismiss()
dialog = it
it.show()
}
it.setCanceledOnTouchOutside(false)
dialog = it
it.show()
}

}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ package com.android.mediproject.core.common.dialog

import android.content.Context
import android.graphics.Color
import android.graphics.Typeface
import android.util.AttributeSet
import android.util.TypedValue
import android.view.Gravity
import android.widget.TextView
Expand All @@ -14,7 +12,7 @@ import com.airbnb.lottie.LottieDrawable.INFINITE
import com.android.mediproject.core.common.R
import com.android.mediproject.core.common.uiutil.dpToPx

class ProgressIndicator(context: Context, attrs: AttributeSet?, textMessage: String?) : ConstraintLayout(context, attrs) {
class ProgressIndicator(context: Context, textMessage: String?) : ConstraintLayout(context) {

private val lottie = LottieAnimationView(context).apply {
setAnimation(R.raw.bluedottedprogress)
Expand All @@ -26,7 +24,6 @@ class ProgressIndicator(context: Context, attrs: AttributeSet?, textMessage: Str
textMessage?.apply {
textView.text = this
textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 15f)
textView.typeface = Typeface.create("sans-serif-condensed", Typeface.NORMAL)
textView.setTextColor(Color.DKGRAY)
} ?: run { textView.visibility = GONE }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,21 @@ import com.google.android.material.progressindicator.CircularProgressIndicator
* @param emptyMsg 로딩 상태가 아닐 때 보여줄 메시지
*/
fun PagingDataAdapter<*, *>.setOnStateChangedListener(
msgTextView: TextView, listView: RecyclerView, progressBar: CircularProgressIndicator, emptyMsg: String
msgTextView: TextView,
listView: RecyclerView,
progressBar: CircularProgressIndicator,
emptyMsg: String
) {
var isFirstLoad = true
addLoadStateListener { loadState ->
isFirstLoad = loadState.refresh is LoadState.Loading
if (isFirstLoad) listView.scrollToPosition(0)

msgTextView.text = emptyMsg

progressBar.isVisible = isFirstLoad
listView.isVisible = (!isFirstLoad && loadState.source.refresh !is LoadState.Loading)
msgTextView.isVisible = !isFirstLoad && loadState.source.refresh !is LoadState.Loading && itemCount == 0
listView.isVisible = (!isFirstLoad && (loadState.source.refresh !is LoadState.Loading))
msgTextView.isVisible =
((!isFirstLoad && loadState.source.refresh !is LoadState.Loading) && itemCount == 0)
}
}
Loading

0 comments on commit 7e18ba4

Please sign in to comment.