From 9e31066e8080d84360758b099975f758720ed411 Mon Sep 17 00:00:00 2001 From: minseonglove Date: Thu, 29 Dec 2022 15:07:20 +0900 Subject: [PATCH 1/6] =?UTF-8?q?FEAT=20:=20BaseActivity,=20BaseFragment=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bidderbidder/ui/base/BaseActivity.kt | 19 +++++++ .../bidderbidder/ui/base/BaseFragment.kt | 52 +++++++++++++++++++ 2 files changed, 71 insertions(+) create mode 100644 app/src/main/kotlin/com/fakedevelopers/bidderbidder/ui/base/BaseActivity.kt create mode 100644 app/src/main/kotlin/com/fakedevelopers/bidderbidder/ui/base/BaseFragment.kt diff --git a/app/src/main/kotlin/com/fakedevelopers/bidderbidder/ui/base/BaseActivity.kt b/app/src/main/kotlin/com/fakedevelopers/bidderbidder/ui/base/BaseActivity.kt new file mode 100644 index 00000000..ec36c814 --- /dev/null +++ b/app/src/main/kotlin/com/fakedevelopers/bidderbidder/ui/base/BaseActivity.kt @@ -0,0 +1,19 @@ +package com.fakedevelopers.bidderbidder.ui.base + +import android.os.Bundle +import android.view.LayoutInflater +import androidx.appcompat.app.AppCompatActivity +import androidx.viewbinding.ViewBinding + +abstract class BaseActivity( + private val bindingFactory: (LayoutInflater) -> VB +) : AppCompatActivity() { + + protected lateinit var binding: VB + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + binding = bindingFactory(layoutInflater) + setContentView(binding.root) + } +} diff --git a/app/src/main/kotlin/com/fakedevelopers/bidderbidder/ui/base/BaseFragment.kt b/app/src/main/kotlin/com/fakedevelopers/bidderbidder/ui/base/BaseFragment.kt new file mode 100644 index 00000000..3b1ae658 --- /dev/null +++ b/app/src/main/kotlin/com/fakedevelopers/bidderbidder/ui/base/BaseFragment.kt @@ -0,0 +1,52 @@ +package com.fakedevelopers.bidderbidder.ui.base + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.annotation.LayoutRes +import androidx.databinding.DataBindingUtil +import androidx.databinding.ViewDataBinding +import androidx.fragment.app.Fragment +import com.google.android.material.snackbar.Snackbar + +abstract class BaseFragment( + @LayoutRes private val layoutRes: Int +) : Fragment() { + + private var _binding: VB? = null + protected val binding get() = _binding!! + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + _binding = DataBindingUtil.inflate(inflater, layoutRes, container, false) + return binding.run { + lifecycleOwner = viewLifecycleOwner + root + } + } + + fun sendSnackBar( + message: String, + @androidx.annotation.IntRange(from = -2) length: Int = Snackbar.LENGTH_SHORT, + anchorView: View? = null + ) { + Snackbar.make( + binding.root, + message, + length + ).apply { + if (anchorView != null) { + this.anchorView = anchorView + } + }.show() + } + + override fun onDestroyView() { + super.onDestroyView() + _binding = null + } +} From dd8cbad3ccaf821147ad82918c76cd1f136d0d2a Mon Sep 17 00:00:00 2001 From: minseonglove Date: Thu, 29 Dec 2022 15:43:45 +0900 Subject: [PATCH 2/6] =?UTF-8?q?REFACTOR=20:=20BaseActivity,=20BaseFragment?= =?UTF-8?q?=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bidderbidder/ui/LoginActivity.kt | 13 ++---- .../bidderbidder/ui/MainActivity.kt | 25 ++++++----- .../ui/chat/channel/ChannelListFragment.kt | 31 +++----------- .../ui/chat/chatting/ChattingFragment.kt | 22 ++-------- .../bidderbidder/ui/login/LoginFragment.kt | 41 +++---------------- .../ui/loginType/LoginTypeFragment.kt | 37 ++++------------- .../ui/productDetail/ProductDetailFragment.kt | 28 +++---------- .../ui/productList/ProductListFragment.kt | 34 ++++----------- .../ProductRegistrationFragment.kt | 29 +++---------- .../ui/productSearch/ProductSearchFragment.kt | 35 +++------------- 10 files changed, 62 insertions(+), 233 deletions(-) diff --git a/app/src/main/kotlin/com/fakedevelopers/bidderbidder/ui/LoginActivity.kt b/app/src/main/kotlin/com/fakedevelopers/bidderbidder/ui/LoginActivity.kt index 406da93b..f279bd13 100644 --- a/app/src/main/kotlin/com/fakedevelopers/bidderbidder/ui/LoginActivity.kt +++ b/app/src/main/kotlin/com/fakedevelopers/bidderbidder/ui/LoginActivity.kt @@ -1,15 +1,8 @@ package com.fakedevelopers.bidderbidder.ui -import android.os.Bundle -import androidx.appcompat.app.AppCompatActivity -import com.fakedevelopers.bidderbidder.R +import com.fakedevelopers.bidderbidder.databinding.ActivityLoginBinding +import com.fakedevelopers.bidderbidder.ui.base.BaseActivity import dagger.hilt.android.AndroidEntryPoint @AndroidEntryPoint -class LoginActivity : AppCompatActivity() { - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - setContentView(R.layout.activity_login) - } -} +class LoginActivity : BaseActivity(ActivityLoginBinding::inflate) diff --git a/app/src/main/kotlin/com/fakedevelopers/bidderbidder/ui/MainActivity.kt b/app/src/main/kotlin/com/fakedevelopers/bidderbidder/ui/MainActivity.kt index fc0b6ddc..c0c5107c 100644 --- a/app/src/main/kotlin/com/fakedevelopers/bidderbidder/ui/MainActivity.kt +++ b/app/src/main/kotlin/com/fakedevelopers/bidderbidder/ui/MainActivity.kt @@ -4,30 +4,22 @@ import android.os.Bundle import android.view.MotionEvent import android.view.View import androidx.annotation.IdRes -import androidx.appcompat.app.AppCompatActivity import androidx.navigation.NavController import androidx.navigation.NavDirections import androidx.navigation.fragment.NavHostFragment import com.fakedevelopers.bidderbidder.R import com.fakedevelopers.bidderbidder.databinding.ActivityMainBinding +import com.fakedevelopers.bidderbidder.ui.base.BaseActivity import com.jakewharton.threetenabp.AndroidThreeTen import dagger.hilt.android.AndroidEntryPoint @AndroidEntryPoint -class MainActivity : AppCompatActivity() { +class MainActivity : BaseActivity(ActivityMainBinding::inflate) { private lateinit var navController: NavController - private var _binding: ActivityMainBinding? = null - private val binding get() = _binding!! - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - _binding = ActivityMainBinding.inflate(layoutInflater) - setContentView(binding.root) - AndroidThreeTen.init(this) - navController = (supportFragmentManager.findFragmentById(R.id.navigation_main) as NavHostFragment).navController - - navController.addOnDestinationChangedListener { _, destination, _ -> + private val destinationChangeListener by lazy { + NavController.OnDestinationChangedListener { _, destination, _ -> when (destination.id) { R.id.productListFragment -> { binding.bottomNavigationMain.run { @@ -39,6 +31,13 @@ class MainActivity : AppCompatActivity() { else -> binding.bottomNavigationMain.visibility = View.GONE } } + } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + AndroidThreeTen.init(this) + navController = (supportFragmentManager.findFragmentById(R.id.navigation_main) as NavHostFragment).navController + navController.addOnDestinationChangedListener(destinationChangeListener) binding.bottomNavigationMain.setOnItemSelectedListener { item -> when (item.itemId) { R.id.menu_product_registration -> navController.safeNavigate(R.id.productRegistrationFragment) @@ -60,7 +59,7 @@ class MainActivity : AppCompatActivity() { override fun onDestroy() { super.onDestroy() - _binding = null + navController.removeOnDestinationChangedListener(destinationChangeListener) } private fun NavController.safeNavigate(direction: NavDirections) { diff --git a/app/src/main/kotlin/com/fakedevelopers/bidderbidder/ui/chat/channel/ChannelListFragment.kt b/app/src/main/kotlin/com/fakedevelopers/bidderbidder/ui/chat/channel/ChannelListFragment.kt index 79683318..6759cd0e 100644 --- a/app/src/main/kotlin/com/fakedevelopers/bidderbidder/ui/chat/channel/ChannelListFragment.kt +++ b/app/src/main/kotlin/com/fakedevelopers/bidderbidder/ui/chat/channel/ChannelListFragment.kt @@ -1,11 +1,7 @@ package com.fakedevelopers.bidderbidder.ui.chat.channel import android.os.Bundle -import android.view.LayoutInflater import android.view.View -import android.view.ViewGroup -import androidx.databinding.DataBindingUtil -import androidx.fragment.app.Fragment import androidx.fragment.app.viewModels import androidx.lifecycle.Lifecycle import androidx.lifecycle.lifecycleScope @@ -15,6 +11,7 @@ import androidx.navigation.navGraphViewModels import com.fakedevelopers.bidderbidder.R import com.fakedevelopers.bidderbidder.api.data.Constants.Companion.STREAM_KEY import com.fakedevelopers.bidderbidder.databinding.FragmentChannelListBinding +import com.fakedevelopers.bidderbidder.ui.base.BaseFragment import com.fakedevelopers.bidderbidder.ui.util.ApiErrorHandler import dagger.hilt.android.AndroidEntryPoint import io.getstream.chat.android.client.ChatClient @@ -29,30 +26,17 @@ import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.launch @AndroidEntryPoint -class ChannelListFragment : Fragment() { +class ChannelListFragment : BaseFragment( + R.layout.fragment_channel_list +) { - private var _binding: FragmentChannelListBinding? = null - private val binding get() = _binding!! private val viewModel: CLViewModel by navGraphViewModels(R.id.nav_graph) { defaultViewModelProviderFactory } - override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { - _binding = DataBindingUtil.inflate( - inflater, - R.layout.fragment_channel_list, - container, - false - ) - return binding.run { - vm = viewModel - lifecycleOwner = viewLifecycleOwner - root - } - } - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) + binding.vm = viewModel initCollector() initListener() } @@ -144,9 +128,4 @@ class ChannelListFragment : Fragment() { } } } - - override fun onDestroyView() { - super.onDestroyView() - _binding = null - } } diff --git a/app/src/main/kotlin/com/fakedevelopers/bidderbidder/ui/chat/chatting/ChattingFragment.kt b/app/src/main/kotlin/com/fakedevelopers/bidderbidder/ui/chat/chatting/ChattingFragment.kt index c7e47f3f..35aed2b5 100644 --- a/app/src/main/kotlin/com/fakedevelopers/bidderbidder/ui/chat/chatting/ChattingFragment.kt +++ b/app/src/main/kotlin/com/fakedevelopers/bidderbidder/ui/chat/chatting/ChattingFragment.kt @@ -1,17 +1,14 @@ package com.fakedevelopers.bidderbidder.ui.chat.chatting import android.os.Bundle -import android.view.LayoutInflater import android.view.View -import android.view.ViewGroup import androidx.activity.OnBackPressedCallback -import androidx.databinding.DataBindingUtil -import androidx.fragment.app.Fragment import androidx.fragment.app.viewModels import androidx.navigation.fragment.findNavController import androidx.navigation.fragment.navArgs import com.fakedevelopers.bidderbidder.R import com.fakedevelopers.bidderbidder.databinding.FragmentChattingBinding +import com.fakedevelopers.bidderbidder.ui.base.BaseFragment import com.getstream.sdk.chat.viewmodel.MessageInputViewModel import com.getstream.sdk.chat.viewmodel.messages.MessageListViewModel import io.getstream.chat.android.ui.message.input.viewmodel.bindView @@ -20,10 +17,10 @@ import io.getstream.chat.android.ui.message.list.header.viewmodel.bindView import io.getstream.chat.android.ui.message.list.viewmodel.bindView import io.getstream.chat.android.ui.message.list.viewmodel.factory.MessageListViewModelFactory -class ChattingFragment : Fragment() { +class ChattingFragment : BaseFragment( + R.layout.fragment_chatting +) { - private var _binding: FragmentChattingBinding? = null - private val binding get() = _binding!! private val args: ChattingFragmentArgs by navArgs() private val backPressedCallback by lazy { object : OnBackPressedCallback(true) { @@ -33,16 +30,6 @@ class ChattingFragment : Fragment() { } } - override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { - _binding = DataBindingUtil.inflate( - inflater, - R.layout.fragment_chatting, - container, - false - ) - return binding.root - } - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) runCatching { @@ -94,6 +81,5 @@ class ChattingFragment : Fragment() { override fun onDestroyView() { super.onDestroyView() backPressedCallback.remove() - _binding = null } } diff --git a/app/src/main/kotlin/com/fakedevelopers/bidderbidder/ui/login/LoginFragment.kt b/app/src/main/kotlin/com/fakedevelopers/bidderbidder/ui/login/LoginFragment.kt index 58e4daf6..8588d0ca 100644 --- a/app/src/main/kotlin/com/fakedevelopers/bidderbidder/ui/login/LoginFragment.kt +++ b/app/src/main/kotlin/com/fakedevelopers/bidderbidder/ui/login/LoginFragment.kt @@ -2,11 +2,7 @@ package com.fakedevelopers.bidderbidder.ui.login import android.content.Intent import android.os.Bundle -import android.view.LayoutInflater import android.view.View -import android.view.ViewGroup -import androidx.databinding.DataBindingUtil -import androidx.fragment.app.Fragment import androidx.fragment.app.viewModels import androidx.lifecycle.Lifecycle import androidx.lifecycle.lifecycleScope @@ -16,40 +12,20 @@ import com.fakedevelopers.bidderbidder.R import com.fakedevelopers.bidderbidder.api.data.Constants.Companion.LOGIN_SUCCESS import com.fakedevelopers.bidderbidder.databinding.FragmentLoginBinding import com.fakedevelopers.bidderbidder.ui.MainActivity -import com.orhanobut.logger.Logger +import com.fakedevelopers.bidderbidder.ui.base.BaseFragment import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.launch @AndroidEntryPoint -class LoginFragment : Fragment() { +class LoginFragment : BaseFragment( + R.layout.fragment_login +) { - private var _binding: FragmentLoginBinding? = null - - private val binding get() = _binding!! private val viewModel: LoginViewModel by viewModels() - override fun onCreateView( - inflater: LayoutInflater, - container: ViewGroup?, - savedInstanceState: Bundle? - ): View { - _binding = DataBindingUtil.inflate( - inflater, - R.layout.fragment_login, - container, - false - ) - return binding.run { - vm = viewModel - lifecycleOwner = viewLifecycleOwner - root - } - } - - // 버튼 클릭 시 로그인 확인 API 호출 override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - + binding.vm = viewModel initListener() initCollector() } @@ -74,15 +50,10 @@ class LoginFragment : Fragment() { startActivity(Intent(requireContext(), MainActivity::class.java)) requireActivity().finish() } else { - Logger.e(it.errorBody().toString()) + sendSnackBar(it.errorBody().toString()) } } } } } - - override fun onDestroyView() { - super.onDestroyView() - _binding = null - } } diff --git a/app/src/main/kotlin/com/fakedevelopers/bidderbidder/ui/loginType/LoginTypeFragment.kt b/app/src/main/kotlin/com/fakedevelopers/bidderbidder/ui/loginType/LoginTypeFragment.kt index 16d1ceb6..7cc6d778 100644 --- a/app/src/main/kotlin/com/fakedevelopers/bidderbidder/ui/loginType/LoginTypeFragment.kt +++ b/app/src/main/kotlin/com/fakedevelopers/bidderbidder/ui/loginType/LoginTypeFragment.kt @@ -3,13 +3,8 @@ package com.fakedevelopers.bidderbidder.ui.loginType import android.app.Activity.RESULT_OK import android.content.Intent import android.os.Bundle -import android.view.LayoutInflater import android.view.View -import android.view.ViewGroup -import android.widget.Toast import androidx.activity.result.contract.ActivityResultContracts -import androidx.databinding.DataBindingUtil -import androidx.fragment.app.Fragment import androidx.fragment.app.viewModels import androidx.lifecycle.Lifecycle import androidx.lifecycle.lifecycleScope @@ -20,19 +15,22 @@ import com.fakedevelopers.bidderbidder.R import com.fakedevelopers.bidderbidder.api.data.Constants.Companion.WEB_CLIENT_ID import com.fakedevelopers.bidderbidder.databinding.FragmentLoginTypeBinding import com.fakedevelopers.bidderbidder.ui.MainActivity +import com.fakedevelopers.bidderbidder.ui.base.BaseFragment import com.google.android.gms.auth.api.Auth import com.google.android.gms.auth.api.signin.GoogleSignIn import com.google.android.gms.auth.api.signin.GoogleSignInClient import com.google.android.gms.auth.api.signin.GoogleSignInOptions import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.launch + @AndroidEntryPoint -class LoginTypeFragment : Fragment() { +class LoginTypeFragment : BaseFragment( + R.layout.fragment_login_type +) { private lateinit var googleSignInClient: GoogleSignInClient - private var _binding: FragmentLoginTypeBinding? = null private val viewModel: LoginTypeViewModel by viewModels() - private val binding get() = _binding!! + private val requestActivity = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { if (it.resultCode == RESULT_OK) { val result = it.data?.let { data -> Auth.GoogleSignInApi.getSignInResultFromIntent(data) } @@ -45,20 +43,6 @@ class LoginTypeFragment : Fragment() { } } - override fun onCreateView( - inflater: LayoutInflater, - container: ViewGroup?, - savedInstanceState: Bundle? - ): View { - _binding = DataBindingUtil.inflate( - inflater, - R.layout.fragment_login_type, - container, - false - ) - return binding.root - } - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) (requireContext().applicationContext as HiltApplication).let { @@ -96,22 +80,17 @@ class LoginTypeFragment : Fragment() { viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) { viewModel.signinGoogleResponse.collect { if (it.isSuccessful) { - Toast.makeText(requireActivity(), "success", Toast.LENGTH_LONG).show() + sendSnackBar("success") startActivity(Intent(requireContext(), MainActivity::class.java)) requireActivity().finish() } else { - Toast.makeText(requireActivity(), "failure", Toast.LENGTH_LONG).show() + sendSnackBar(it.errorBody().toString()) } } } } } - override fun onDestroyView() { - super.onDestroyView() - _binding = null - } - private fun googleLogin() { val googleSignInOptions = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN) .requestIdToken(WEB_CLIENT_ID) diff --git a/app/src/main/kotlin/com/fakedevelopers/bidderbidder/ui/productDetail/ProductDetailFragment.kt b/app/src/main/kotlin/com/fakedevelopers/bidderbidder/ui/productDetail/ProductDetailFragment.kt index 9b59f5fa..f688ba8f 100644 --- a/app/src/main/kotlin/com/fakedevelopers/bidderbidder/ui/productDetail/ProductDetailFragment.kt +++ b/app/src/main/kotlin/com/fakedevelopers/bidderbidder/ui/productDetail/ProductDetailFragment.kt @@ -6,19 +6,16 @@ import android.text.Spannable import android.text.SpannableStringBuilder import android.text.style.RelativeSizeSpan import android.text.style.StyleSpan -import android.view.LayoutInflater import android.view.View -import android.view.ViewGroup import android.widget.TextView import androidx.core.view.isVisible -import androidx.databinding.DataBindingUtil -import androidx.fragment.app.Fragment import androidx.fragment.app.viewModels import androidx.navigation.fragment.navArgs import androidx.viewpager2.widget.ViewPager2 import com.fakedevelopers.bidderbidder.R import com.fakedevelopers.bidderbidder.databinding.FragmentProductDetailBinding import com.fakedevelopers.bidderbidder.model.RemainTime +import com.fakedevelopers.bidderbidder.ui.base.BaseFragment import com.fakedevelopers.bidderbidder.ui.util.repeatOnStarted import com.orhanobut.logger.Logger import dagger.hilt.android.AndroidEntryPoint @@ -28,10 +25,9 @@ import org.threeten.bp.ZoneOffset import org.threeten.bp.format.DateTimeFormatter @AndroidEntryPoint -class ProductDetailFragment : Fragment() { - - private var _binding: FragmentProductDetailBinding? = null - private val binding get() = _binding!! +class ProductDetailFragment : BaseFragment( + R.layout.fragment_product_detail +) { private val viewModel: ProductDetailViewModel by viewModels() @@ -46,22 +42,9 @@ class ProductDetailFragment : Fragment() { private val formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm") - override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { - _binding = DataBindingUtil.inflate( - inflater, - R.layout.fragment_product_detail, - container, - false - ) - return binding.run { - vm = viewModel - lifecycleOwner = viewLifecycleOwner - root - } - } - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) + binding.vm = viewModel val args: ProductDetailFragmentArgs by navArgs() if (args.productId != -1L) { viewModel.productDetailRequest(args.productId) @@ -183,7 +166,6 @@ class ProductDetailFragment : Fragment() { override fun onDestroyView() { super.onDestroyView() binding.viewpagerProductDetailPictures.unregisterOnPageChangeCallback(onPageChanged) - _binding = null } companion object { diff --git a/app/src/main/kotlin/com/fakedevelopers/bidderbidder/ui/productList/ProductListFragment.kt b/app/src/main/kotlin/com/fakedevelopers/bidderbidder/ui/productList/ProductListFragment.kt index 397d5d3b..98dd7e87 100644 --- a/app/src/main/kotlin/com/fakedevelopers/bidderbidder/ui/productList/ProductListFragment.kt +++ b/app/src/main/kotlin/com/fakedevelopers/bidderbidder/ui/productList/ProductListFragment.kt @@ -1,11 +1,7 @@ package com.fakedevelopers.bidderbidder.ui.productList import android.os.Bundle -import android.view.LayoutInflater import android.view.View -import android.view.ViewGroup -import androidx.databinding.DataBindingUtil -import androidx.fragment.app.Fragment import androidx.lifecycle.Lifecycle import androidx.lifecycle.lifecycleScope import androidx.lifecycle.repeatOnLifecycle @@ -16,19 +12,20 @@ import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import com.fakedevelopers.bidderbidder.R import com.fakedevelopers.bidderbidder.databinding.FragmentProductListBinding +import com.fakedevelopers.bidderbidder.ui.base.BaseFragment import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.launch @AndroidEntryPoint -class ProductListFragment : Fragment() { - - private var _binding: FragmentProductListBinding? = null - private val binding get() = _binding!! +class ProductListFragment : BaseFragment( + R.layout.fragment_product_list +) { private val viewModel: ProductListViewModel by navGraphViewModels(R.id.nav_graph) { defaultViewModelProviderFactory } + private val infinityScroll by lazy { object : RecyclerView.OnScrollListener() { override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) { @@ -42,6 +39,7 @@ class ProductListFragment : Fragment() { } } } + private val linearLayoutManager by lazy { object : LinearLayoutManager(requireContext()) { override fun onLayoutCompleted(state: RecyclerView.State?) { @@ -56,26 +54,9 @@ class ProductListFragment : Fragment() { } } - override fun onCreateView( - inflater: LayoutInflater, - container: ViewGroup?, - savedInstanceState: Bundle? - ): View { - _binding = DataBindingUtil.inflate( - inflater, - R.layout.fragment_product_list, - container, - false - ) - return binding.run { - vm = viewModel - lifecycleOwner = viewLifecycleOwner - root - } - } - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) + binding.vm = viewModel val args: ProductListFragmentArgs by navArgs() if (viewModel.isInitialize) { viewModel.setSearchWord(args.searchWord) @@ -129,7 +110,6 @@ class ProductListFragment : Fragment() { layoutManager = null removeOnScrollListener(infinityScroll) } - _binding = null } companion object { diff --git a/app/src/main/kotlin/com/fakedevelopers/bidderbidder/ui/productRegistration/ProductRegistrationFragment.kt b/app/src/main/kotlin/com/fakedevelopers/bidderbidder/ui/productRegistration/ProductRegistrationFragment.kt index ddfa8a5d..0cd84120 100644 --- a/app/src/main/kotlin/com/fakedevelopers/bidderbidder/ui/productRegistration/ProductRegistrationFragment.kt +++ b/app/src/main/kotlin/com/fakedevelopers/bidderbidder/ui/productRegistration/ProductRegistrationFragment.kt @@ -9,9 +9,7 @@ import android.provider.OpenableColumns import android.text.Editable import android.text.InputFilter import android.text.TextWatcher -import android.view.LayoutInflater import android.view.View -import android.view.ViewGroup import android.widget.AdapterView import android.widget.ArrayAdapter import android.widget.EditText @@ -21,8 +19,6 @@ import androidx.activity.result.ActivityResultLauncher import androidx.activity.result.contract.ActivityResultContracts import androidx.core.content.PermissionChecker import androidx.core.content.PermissionChecker.checkCallingOrSelfPermission -import androidx.databinding.DataBindingUtil -import androidx.fragment.app.Fragment import androidx.fragment.app.viewModels import androidx.lifecycle.Lifecycle import androidx.lifecycle.lifecycleScope @@ -32,6 +28,7 @@ import androidx.navigation.fragment.navArgs import androidx.recyclerview.widget.ItemTouchHelper import com.fakedevelopers.bidderbidder.R import com.fakedevelopers.bidderbidder.databinding.FragmentProductRegistrationBinding +import com.fakedevelopers.bidderbidder.ui.base.BaseFragment import com.fakedevelopers.bidderbidder.ui.productRegistration.PriceTextWatcher.Companion.IS_NOT_NUMBER import com.fakedevelopers.bidderbidder.ui.productRegistration.PriceTextWatcher.Companion.MAX_CONTENT_LENGTH import com.fakedevelopers.bidderbidder.ui.productRegistration.PriceTextWatcher.Companion.MAX_EXPIRATION_LENGTH @@ -54,7 +51,9 @@ import okio.BufferedSink import javax.inject.Inject @AndroidEntryPoint -class ProductRegistrationFragment : Fragment() { +class ProductRegistrationFragment : BaseFragment( + R.layout.fragment_product_registration +) { @Inject lateinit var contentResolverUtil: ContentResolverUtil @@ -65,9 +64,8 @@ class ProductRegistrationFragment : Fragment() { private lateinit var keyboardVisibilityUtils: KeyboardVisibilityUtils private lateinit var permissionLauncher: ActivityResultLauncher - private var _binding: FragmentProductRegistrationBinding? = null - private val binding get() = _binding!! private val viewModel: ProductRegistrationViewModel by viewModels() + private val backPressedCallback by lazy { object : OnBackPressedCallback(true) { override fun handleOnBackPressed() { @@ -76,23 +74,9 @@ class ProductRegistrationFragment : Fragment() { } } - override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { - initResultLauncher() - _binding = DataBindingUtil.inflate( - inflater, - R.layout.fragment_product_registration, - container, - false - ) - return binding.run { - vm = viewModel - lifecycleOwner = viewLifecycleOwner - root - } - } - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) + binding.vm = viewModel val args: ProductRegistrationFragmentArgs by navArgs() args.productRegistrationDto?.let { viewModel.initState(it) @@ -363,7 +347,6 @@ class ProductRegistrationFragment : Fragment() { override fun onDestroyView() { super.onDestroyView() - _binding = null backPressedCallback.remove() keyboardVisibilityUtils.deleteKeyboardListeners() } diff --git a/app/src/main/kotlin/com/fakedevelopers/bidderbidder/ui/productSearch/ProductSearchFragment.kt b/app/src/main/kotlin/com/fakedevelopers/bidderbidder/ui/productSearch/ProductSearchFragment.kt index 73504723..de63dd62 100644 --- a/app/src/main/kotlin/com/fakedevelopers/bidderbidder/ui/productSearch/ProductSearchFragment.kt +++ b/app/src/main/kotlin/com/fakedevelopers/bidderbidder/ui/productSearch/ProductSearchFragment.kt @@ -2,15 +2,11 @@ package com.fakedevelopers.bidderbidder.ui.productSearch import android.content.Context import android.os.Bundle -import android.view.LayoutInflater import android.view.View -import android.view.ViewGroup import android.view.inputmethod.EditorInfo import android.view.inputmethod.InputMethodManager -import androidx.databinding.DataBindingUtil import androidx.datastore.preferences.core.edit import androidx.datastore.preferences.core.emptyPreferences -import androidx.fragment.app.Fragment import androidx.fragment.app.viewModels import androidx.lifecycle.Lifecycle import androidx.lifecycle.lifecycleScope @@ -21,6 +17,7 @@ import com.fakedevelopers.bidderbidder.R import com.fakedevelopers.bidderbidder.api.datastore.DatastoreSetting.Companion.SEARCH_HISTORY import com.fakedevelopers.bidderbidder.api.datastore.DatastoreSetting.Companion.datastore import com.fakedevelopers.bidderbidder.databinding.FragmentProductSearchBinding +import com.fakedevelopers.bidderbidder.ui.base.BaseFragment import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.delay import kotlinx.coroutines.flow.catch @@ -30,18 +27,16 @@ import kotlinx.coroutines.launch import java.io.IOException @AndroidEntryPoint -class ProductSearchFragment : Fragment() { - - private var _binding: FragmentProductSearchBinding? = null - +class ProductSearchFragment : BaseFragment( + R.layout.fragment_product_list +) { private val viewModel: ProductSearchViewModel by viewModels() - private val binding get() = _binding!! private val args: ProductSearchFragmentArgs by navArgs() + private val imm by lazy { requireActivity().getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager } - // datastore private val searchHistory by lazy { requireContext().datastore.data .catch { exception -> @@ -56,22 +51,9 @@ class ProductSearchFragment : Fragment() { } } - override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { - _binding = DataBindingUtil.inflate( - inflater, - R.layout.fragment_product_search, - container, - false - ) - return binding.run { - vm = viewModel - lifecycleOwner = viewLifecycleOwner - root - } - } - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) + binding.vm = viewModel initCollector() initListener() } @@ -144,11 +126,6 @@ class ProductSearchFragment : Fragment() { } } - override fun onDestroy() { - super.onDestroy() - _binding = null - } - companion object { const val WAIT_BEFORE_REQUEST = 700L } From 338da3e97021c3bee07a931b1721e3011cbf5fd9 Mon Sep 17 00:00:00 2001 From: minseonglove Date: Thu, 29 Dec 2022 15:49:40 +0900 Subject: [PATCH 3/6] =?UTF-8?q?FEAT=20:=20navigateActivity=20=EB=A9=94?= =?UTF-8?q?=EC=86=8C=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/fakedevelopers/bidderbidder/ui/base/BaseFragment.kt | 6 ++++++ .../fakedevelopers/bidderbidder/ui/login/LoginFragment.kt | 4 +--- .../bidderbidder/ui/loginType/LoginTypeFragment.kt | 4 +--- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/app/src/main/kotlin/com/fakedevelopers/bidderbidder/ui/base/BaseFragment.kt b/app/src/main/kotlin/com/fakedevelopers/bidderbidder/ui/base/BaseFragment.kt index 3b1ae658..7475aaa6 100644 --- a/app/src/main/kotlin/com/fakedevelopers/bidderbidder/ui/base/BaseFragment.kt +++ b/app/src/main/kotlin/com/fakedevelopers/bidderbidder/ui/base/BaseFragment.kt @@ -1,5 +1,6 @@ package com.fakedevelopers.bidderbidder.ui.base +import android.content.Intent import android.os.Bundle import android.view.LayoutInflater import android.view.View @@ -45,6 +46,11 @@ abstract class BaseFragment( }.show() } + fun navigateActivity(activity: Class<*>) { + startActivity(Intent(requireContext(), activity)) + requireActivity().finish() + } + override fun onDestroyView() { super.onDestroyView() _binding = null diff --git a/app/src/main/kotlin/com/fakedevelopers/bidderbidder/ui/login/LoginFragment.kt b/app/src/main/kotlin/com/fakedevelopers/bidderbidder/ui/login/LoginFragment.kt index 8588d0ca..3584a0a2 100644 --- a/app/src/main/kotlin/com/fakedevelopers/bidderbidder/ui/login/LoginFragment.kt +++ b/app/src/main/kotlin/com/fakedevelopers/bidderbidder/ui/login/LoginFragment.kt @@ -1,6 +1,5 @@ package com.fakedevelopers.bidderbidder.ui.login -import android.content.Intent import android.os.Bundle import android.view.View import androidx.fragment.app.viewModels @@ -47,8 +46,7 @@ class LoginFragment : BaseFragment( viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) { viewModel.loginResponse.collect { if (it.isSuccessful && it.body().toString() == LOGIN_SUCCESS) { - startActivity(Intent(requireContext(), MainActivity::class.java)) - requireActivity().finish() + navigateActivity(MainActivity::class.java) } else { sendSnackBar(it.errorBody().toString()) } diff --git a/app/src/main/kotlin/com/fakedevelopers/bidderbidder/ui/loginType/LoginTypeFragment.kt b/app/src/main/kotlin/com/fakedevelopers/bidderbidder/ui/loginType/LoginTypeFragment.kt index 7cc6d778..4fd6adcc 100644 --- a/app/src/main/kotlin/com/fakedevelopers/bidderbidder/ui/loginType/LoginTypeFragment.kt +++ b/app/src/main/kotlin/com/fakedevelopers/bidderbidder/ui/loginType/LoginTypeFragment.kt @@ -1,7 +1,6 @@ package com.fakedevelopers.bidderbidder.ui.loginType import android.app.Activity.RESULT_OK -import android.content.Intent import android.os.Bundle import android.view.View import androidx.activity.result.contract.ActivityResultContracts @@ -81,8 +80,7 @@ class LoginTypeFragment : BaseFragment( viewModel.signinGoogleResponse.collect { if (it.isSuccessful) { sendSnackBar("success") - startActivity(Intent(requireContext(), MainActivity::class.java)) - requireActivity().finish() + navigateActivity(MainActivity::class.java) } else { sendSnackBar(it.errorBody().toString()) } From 77bcd588f4ce16353cd87b17292a52487af40172 Mon Sep 17 00:00:00 2001 From: minseonglove Date: Thu, 29 Dec 2022 16:04:11 +0900 Subject: [PATCH 4/6] =?UTF-8?q?FIX=20:=20onDestroyView=EC=97=90=EC=84=9C?= =?UTF-8?q?=20=EB=B0=94=EC=9D=B8=EB=94=A9=EC=9D=84=20=ED=95=B4=EC=A0=9C?= =?UTF-8?q?=ED=95=9C=20=EB=92=A4=20=EB=B0=94=EC=9D=B8=EB=94=A9=EC=97=90=20?= =?UTF-8?q?=EC=A0=91=EA=B7=BC=ED=95=98=EB=A0=A4=EB=8A=94=20=EB=82=98?= =?UTF-8?q?=EC=81=9C=20=EB=8F=99=EC=9E=91=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bidderbidder/ui/productDetail/ProductDetailFragment.kt | 2 +- .../bidderbidder/ui/productList/ProductListFragment.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/kotlin/com/fakedevelopers/bidderbidder/ui/productDetail/ProductDetailFragment.kt b/app/src/main/kotlin/com/fakedevelopers/bidderbidder/ui/productDetail/ProductDetailFragment.kt index f688ba8f..29f60661 100644 --- a/app/src/main/kotlin/com/fakedevelopers/bidderbidder/ui/productDetail/ProductDetailFragment.kt +++ b/app/src/main/kotlin/com/fakedevelopers/bidderbidder/ui/productDetail/ProductDetailFragment.kt @@ -164,8 +164,8 @@ class ProductDetailFragment : BaseFragment( } override fun onDestroyView() { - super.onDestroyView() binding.viewpagerProductDetailPictures.unregisterOnPageChangeCallback(onPageChanged) + super.onDestroyView() } companion object { diff --git a/app/src/main/kotlin/com/fakedevelopers/bidderbidder/ui/productList/ProductListFragment.kt b/app/src/main/kotlin/com/fakedevelopers/bidderbidder/ui/productList/ProductListFragment.kt index 98dd7e87..790098a8 100644 --- a/app/src/main/kotlin/com/fakedevelopers/bidderbidder/ui/productList/ProductListFragment.kt +++ b/app/src/main/kotlin/com/fakedevelopers/bidderbidder/ui/productList/ProductListFragment.kt @@ -105,11 +105,11 @@ class ProductListFragment : BaseFragment( } override fun onDestroyView() { - super.onDestroyView() binding.recyclerProductList.run { layoutManager = null removeOnScrollListener(infinityScroll) } + super.onDestroyView() } companion object { From 1d8e938eb5bb1ab7a52bc88342f80362f4bb4e4b Mon Sep 17 00:00:00 2001 From: minseonglove Date: Thu, 29 Dec 2022 19:19:19 +0900 Subject: [PATCH 5/6] =?UTF-8?q?CHORE=20:=20=EC=BD=94=EB=93=9C=20=EC=8A=A4?= =?UTF-8?q?=EB=A9=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ui/productRegistration/ProductRegistrationFragment.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/main/kotlin/com/fakedevelopers/bidderbidder/ui/productRegistration/ProductRegistrationFragment.kt b/app/src/main/kotlin/com/fakedevelopers/bidderbidder/ui/productRegistration/ProductRegistrationFragment.kt index 0cd84120..6f6dec64 100644 --- a/app/src/main/kotlin/com/fakedevelopers/bidderbidder/ui/productRegistration/ProductRegistrationFragment.kt +++ b/app/src/main/kotlin/com/fakedevelopers/bidderbidder/ui/productRegistration/ProductRegistrationFragment.kt @@ -85,6 +85,7 @@ class ProductRegistrationFragment : BaseFragment Date: Thu, 29 Dec 2022 19:34:42 +0900 Subject: [PATCH 6/6] =?UTF-8?q?DEPLOY=20:=20=EB=A6=B4=EB=A6=AC=EC=A6=88=20?= =?UTF-8?q?=ED=83=9C=EA=B7=B8=20=EC=96=91=EC=8B=9D=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/bidderbidderCI.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/bidderbidderCI.yml b/.github/workflows/bidderbidderCI.yml index 8c7467dc..3e75d56a 100644 --- a/.github/workflows/bidderbidderCI.yml +++ b/.github/workflows/bidderbidderCI.yml @@ -47,7 +47,7 @@ jobs: name: artifact - name: Get current date id: date - run: echo "::set-output name=date::$(date +'%Y-%m-%d-%H-%M')" + run: echo "::set-output name=date::$(date +'%Y-%m-%d-%H-%M-%S')" - name: Create Release id: create_release uses: actions/create-release@v1