More Activity : Coming soon card
blogs api adapter and recyclerview AboutWoka Activity saving instance of player in home one and two fragment to optimize the theme switching
This commit is contained in:
@@ -1,21 +1,53 @@
|
||||
package com.woka.home
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.AsyncDifferConfig
|
||||
import androidx.recyclerview.widget.DiffUtil
|
||||
import androidx.recyclerview.widget.ListAdapter
|
||||
import androidx.recyclerview.widget.RecyclerView.ViewHolder
|
||||
import com.bumptech.glide.Glide
|
||||
import com.woka.R
|
||||
import com.woka.databinding.BlogViewHolderBinding
|
||||
import com.woka.modules.blogs.Blog
|
||||
import java.util.concurrent.Executors
|
||||
|
||||
class BlogsAdapter(config: AsyncDifferConfig<Blog>) :
|
||||
ListAdapter<Blog, BlogsAdapter.BlogViewHolder>(config) {
|
||||
|
||||
inner class BlogViewHolder(binding: BlogViewHolderBinding): ViewHolder(binding.root)
|
||||
inner class BlogViewHolder(val binding: BlogViewHolderBinding): ViewHolder(binding.root)
|
||||
|
||||
companion object{
|
||||
private val DIFF_UTILS = object : DiffUtil.ItemCallback<Blog>(){
|
||||
override fun areItemsTheSame(oldItem: Blog, newItem: Blog): Boolean =
|
||||
oldItem.id == newItem.id
|
||||
|
||||
override fun areContentsTheSame(oldItem: Blog, newItem: Blog): Boolean =
|
||||
oldItem == newItem
|
||||
}
|
||||
|
||||
private val ASYNC_DIFF_CONFIG = AsyncDifferConfig.Builder(DIFF_UTILS)
|
||||
.setBackgroundThreadExecutor(Executors.newSingleThreadExecutor())
|
||||
.build()
|
||||
}
|
||||
|
||||
constructor(): this(ASYNC_DIFF_CONFIG)
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BlogViewHolder {
|
||||
|
||||
return BlogViewHolder(BlogViewHolderBinding.inflate(LayoutInflater.from(parent.context), parent, false))
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: BlogViewHolder, position: Int) {
|
||||
with(getItem(position)){
|
||||
thumbnail_path?.let {
|
||||
Glide.with(holder.binding.image)
|
||||
.load(it)
|
||||
.placeholder(android.R.color.darker_gray)
|
||||
.error(R.drawable.woka_logo_half)
|
||||
.into(holder.binding.image)
|
||||
}
|
||||
|
||||
holder.binding.title.text = title
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,6 +12,7 @@ import android.graphics.Shader
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import android.view.HapticFeedbackConstants
|
||||
import android.view.View.GONE
|
||||
import android.view.View.VISIBLE
|
||||
import android.view.WindowManager
|
||||
@@ -26,6 +27,7 @@ import androidx.core.view.WindowInsetsCompat
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import com.bumptech.glide.Glide
|
||||
import com.google.android.exoplayer2.ExoPlayer
|
||||
import com.jwplayer.pub.api.license.LicenseUtil
|
||||
import com.woka.BuildConfig
|
||||
import com.woka.R
|
||||
@@ -37,6 +39,7 @@ import com.woka.home.BottomNavigation.Companion.MY_LIST
|
||||
import com.woka.home.fragments.Home1Fragment
|
||||
import com.woka.home.fragments.Home2Fragment
|
||||
import com.woka.home.fragments.MyListFragment
|
||||
import com.woka.home.sidebar.AboutActivity
|
||||
import com.woka.mvvm.userDataModels.UserDataResponse
|
||||
import com.woka.networking.ApiResult
|
||||
import com.woka.onboard.OnboardActivity
|
||||
@@ -131,6 +134,8 @@ class HomeActivity : WokaBaseActivity(),
|
||||
}
|
||||
|
||||
LicenseUtil().setLicenseKey(this, "LkYoNusv+gSIVJIrXa5Bf59iBNlUMxeg82PM/l8JWk+cD4BE")
|
||||
|
||||
viewModel.initPlayer(applicationContext)
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
@@ -256,6 +261,11 @@ class HomeActivity : WokaBaseActivity(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sbAboutWokaCard.setOnClickListener {
|
||||
startActivity(Intent(this@HomeActivity, AboutActivity::class.java),
|
||||
ActivityOptions.makeSceneTransitionAnimation(this@HomeActivity).toBundle())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -267,10 +277,16 @@ class HomeActivity : WokaBaseActivity(),
|
||||
Theme.THEME_ONE -> {
|
||||
sbTheme1Selected.visibility = VISIBLE
|
||||
sbTheme2Selected.visibility = GONE
|
||||
|
||||
sbTheme1.isPressable = false
|
||||
sbTheme2.isPressable = true
|
||||
}
|
||||
Theme.THEME_TWO -> {
|
||||
sbTheme2Selected.visibility = VISIBLE
|
||||
sbTheme1Selected.visibility = GONE
|
||||
|
||||
sbTheme1.isPressable = true
|
||||
sbTheme2.isPressable = false
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -310,6 +326,8 @@ class HomeActivity : WokaBaseActivity(),
|
||||
if (!init){
|
||||
binding.homeDrawer.closeDrawer(GravityCompat.END)
|
||||
viewModel.sendLocaleChangeEvent(locale)
|
||||
|
||||
binding.root.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
package com.woka.home
|
||||
|
||||
import android.content.Context
|
||||
import android.net.Uri
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.google.android.exoplayer2.ExoPlayer
|
||||
import com.google.android.exoplayer2.MediaItem
|
||||
import com.woka.home.BottomNavigation.Companion.HOME
|
||||
import com.woka.mvvm.UserApiService
|
||||
import com.woka.mvvm.UserRepository
|
||||
@@ -26,6 +30,20 @@ class HomeViewModel: ViewModel(){
|
||||
val logoutLiveData: LiveData<ApiResult<Any>?>
|
||||
get() = _logoutLiveData
|
||||
|
||||
var player: ExoPlayer? = null
|
||||
|
||||
fun initPlayer(context: Context) {
|
||||
player = ExoPlayer.Builder(context).build()
|
||||
|
||||
player?.volume = 0f
|
||||
|
||||
val videoUri = Uri.parse("https://d3volyx7jx7oal.cloudfront.net/master.m3u8")
|
||||
val mediaItem = MediaItem.fromUri(videoUri)
|
||||
player?.setMediaItem(mediaItem)
|
||||
player?.playWhenReady = true
|
||||
player?.prepare()
|
||||
}
|
||||
|
||||
fun sendLocaleChangeEvent(locale: String){
|
||||
_localeChangeLiveData.postValue(locale)
|
||||
}
|
||||
@@ -36,4 +54,10 @@ class HomeViewModel: ViewModel(){
|
||||
_logoutLiveData.postValue(userRepository.logout())
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCleared() {
|
||||
super.onCleared()
|
||||
player?.release()
|
||||
player = null
|
||||
}
|
||||
}
|
||||
@@ -2,44 +2,93 @@ package com.woka.home
|
||||
|
||||
import android.graphics.Color
|
||||
import android.os.Bundle
|
||||
import android.transition.Fade
|
||||
import android.view.WindowManager
|
||||
import androidx.activity.enableEdgeToEdge
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.view.ViewCompat
|
||||
import androidx.core.view.WindowInsetsCompat
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import com.woka.R
|
||||
import com.woka.modules.BlogsViewModel
|
||||
import com.woka.databinding.ActivityMoreHomeBinding
|
||||
import com.woka.modules.BlogsRepository
|
||||
import com.woka.networking.ApiResult
|
||||
import com.woka.utils.WokaBaseActivity
|
||||
import com.woka.utils.hide
|
||||
import com.woka.utils.lightStatusBar
|
||||
import com.woka.utils.show
|
||||
import com.woka.utils.toast
|
||||
|
||||
class MoreHomeActivity : WokaBaseActivity() {
|
||||
|
||||
private lateinit var blogsViewModel: BlogsViewModel
|
||||
private lateinit var binding: ActivityMoreHomeBinding
|
||||
|
||||
private lateinit var blogsAdapter: BlogsAdapter
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
with(window){
|
||||
enterTransition = Fade()
|
||||
}
|
||||
enableEdgeToEdge()
|
||||
setContentView(R.layout.activity_more_home)
|
||||
binding = ActivityMoreHomeBinding.inflate(layoutInflater)
|
||||
setContentView(binding.root)
|
||||
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
|
||||
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
|
||||
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
|
||||
insets
|
||||
}
|
||||
|
||||
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
|
||||
window.statusBarColor = Color.TRANSPARENT
|
||||
window.navigationBarColor = getColor(R.color.more_bg)
|
||||
window.lightStatusBar()
|
||||
with(window){
|
||||
addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
|
||||
statusBarColor = Color.TRANSPARENT
|
||||
navigationBarColor = getColor(R.color.more_bg)
|
||||
lightStatusBar()
|
||||
}
|
||||
|
||||
blogsViewModel = ViewModelProvider(this)[BlogsViewModel::class.java]
|
||||
blogsAdapter = BlogsAdapter()
|
||||
|
||||
initViews()
|
||||
|
||||
clickEvents()
|
||||
|
||||
setObservers()
|
||||
}
|
||||
|
||||
private fun setObservers() {
|
||||
blogsViewModel.blogsLiveData.observe(this){
|
||||
private fun clickEvents() {
|
||||
binding.apply {
|
||||
more.setOnClickListener {
|
||||
onBackPressedDispatcher.onBackPressed()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun initViews(){
|
||||
binding.apply {
|
||||
rvBlogs.adapter = blogsAdapter
|
||||
}
|
||||
}
|
||||
|
||||
private fun setObservers() {
|
||||
BlogsRepository.blogsLiveData.observe(this){
|
||||
when(it){
|
||||
is ApiResult.Error -> {
|
||||
toast(it.errorMessage)
|
||||
binding.blogsTxt.hide()
|
||||
binding.rvBlogs.hide()
|
||||
}
|
||||
is ApiResult.Loading -> {
|
||||
binding.blogsTxt.hide()
|
||||
binding.rvBlogs.hide()
|
||||
}
|
||||
is ApiResult.Success -> {
|
||||
it.data?.blogs?.let {blogList ->
|
||||
binding.blogsTxt.show()
|
||||
binding.rvBlogs.show()
|
||||
|
||||
blogsAdapter.submitList(blogList)
|
||||
}
|
||||
}
|
||||
null -> {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package com.woka.home.fragments
|
||||
|
||||
import android.animation.ObjectAnimator
|
||||
import android.animation.ValueAnimator
|
||||
import android.app.ActivityOptions
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
@@ -47,8 +48,6 @@ class Home1Fragment : Fragment() {
|
||||
private var star1Animator: ValueAnimator? = null
|
||||
private var star2Animator: ValueAnimator? = null
|
||||
|
||||
private lateinit var player: ExoPlayer
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
@@ -56,7 +55,6 @@ class Home1Fragment : Fragment() {
|
||||
binding = FragmentHome1Binding.inflate(inflater, container, false)
|
||||
activity?.let {
|
||||
viewModel = ViewModelProvider(it)[HomeViewModel::class.java]
|
||||
player = ExoPlayer.Builder(it).build()
|
||||
}
|
||||
|
||||
initViews()
|
||||
@@ -85,8 +83,8 @@ class Home1Fragment : Fragment() {
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
handleAnimations()
|
||||
if (!player.isPlaying){
|
||||
player.play()
|
||||
if (viewModel.player?.isPlaying == false){
|
||||
viewModel.player?.play()
|
||||
}
|
||||
|
||||
binding.playerView.show()
|
||||
@@ -100,29 +98,16 @@ class Home1Fragment : Fragment() {
|
||||
if (star1Animator?.isRunning == true) star1Animator?.pause()
|
||||
if (star2Animator?.isRunning == true) star2Animator?.pause()
|
||||
|
||||
if (player.isPlaying) player.pause()
|
||||
if (viewModel.player?.isPlaying == true) viewModel.player?.pause()
|
||||
|
||||
if (viewModel.isHomeBackgroundBlurred){
|
||||
binding.playerView.hide()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
player.release()
|
||||
}
|
||||
|
||||
private fun initPlayerView() {
|
||||
binding.playerView.player = player
|
||||
|
||||
binding.playerView.player = viewModel.player
|
||||
binding.playerView.useController = false
|
||||
player.volume = 0f
|
||||
|
||||
val videoUri = Uri.parse("https://d3volyx7jx7oal.cloudfront.net/master.m3u8")
|
||||
val mediaItem = MediaItem.fromUri(videoUri)
|
||||
player.setMediaItem(mediaItem)
|
||||
player.playWhenReady = true
|
||||
player.prepare()
|
||||
}
|
||||
|
||||
private fun setObservers() {
|
||||
@@ -169,7 +154,8 @@ class Home1Fragment : Fragment() {
|
||||
|
||||
more.setOnClickListener {
|
||||
activity?.let {
|
||||
startActivity(Intent(it, MoreHomeActivity::class.java))
|
||||
startActivity(Intent(it, MoreHomeActivity::class.java),
|
||||
ActivityOptions.makeSceneTransitionAnimation(it).toBundle())
|
||||
} }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,8 +31,6 @@ class Home2Fragment : Fragment() {
|
||||
|
||||
private lateinit var viewModel: HomeViewModel
|
||||
|
||||
private lateinit var player: ExoPlayer
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
@@ -41,7 +39,6 @@ class Home2Fragment : Fragment() {
|
||||
|
||||
activity?.let {
|
||||
viewModel = ViewModelProvider(it)[HomeViewModel::class.java]
|
||||
player = ExoPlayer.Builder(it).build()
|
||||
}
|
||||
|
||||
iniViews()
|
||||
@@ -65,8 +62,8 @@ class Home2Fragment : Fragment() {
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
if (!player.isPlaying){
|
||||
player.play()
|
||||
if (viewModel.player?.isPlaying == false){
|
||||
viewModel.player?.play()
|
||||
}
|
||||
|
||||
binding.playerView.show()
|
||||
@@ -74,32 +71,16 @@ class Home2Fragment : Fragment() {
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
if (player.isPlaying) {
|
||||
player.pause()
|
||||
}
|
||||
if (viewModel.player?.isPlaying == true) viewModel.player?.pause()
|
||||
|
||||
if (viewModel.isHomeBackgroundBlurred){
|
||||
binding.playerView.hide()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
player.release()
|
||||
}
|
||||
|
||||
private fun initPlayerView() {
|
||||
binding.playerView.player = player
|
||||
|
||||
binding.playerView.player = viewModel.player
|
||||
binding.playerView.useController = false
|
||||
player.volume = 0f
|
||||
|
||||
val videoUri = Uri.parse("https://d3volyx7jx7oal.cloudfront.net/master.m3u8")
|
||||
val mediaItem = MediaItem.fromUri(videoUri)
|
||||
player.setMediaItem(mediaItem)
|
||||
player.playWhenReady = true
|
||||
|
||||
player.prepare()
|
||||
}
|
||||
|
||||
private fun clickEvents(){
|
||||
|
||||
49
app/src/main/java/com/woka/home/sidebar/AboutActivity.kt
Normal file
49
app/src/main/java/com/woka/home/sidebar/AboutActivity.kt
Normal file
@@ -0,0 +1,49 @@
|
||||
package com.woka.home.sidebar
|
||||
|
||||
import android.graphics.Color
|
||||
import android.os.Bundle
|
||||
import android.transition.Fade
|
||||
import android.transition.Slide
|
||||
import android.view.Gravity.END
|
||||
import androidx.activity.enableEdgeToEdge
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.view.ViewCompat
|
||||
import androidx.core.view.WindowInsetsCompat
|
||||
import com.woka.R
|
||||
import com.woka.databinding.ActivityAboutBinding
|
||||
import com.woka.utils.WokaBaseActivity
|
||||
import com.woka.utils.lightStatusBar
|
||||
|
||||
class AboutActivity : WokaBaseActivity() {
|
||||
|
||||
private lateinit var binding: ActivityAboutBinding
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
window.enterTransition = Slide().apply {
|
||||
slideEdge = END
|
||||
}
|
||||
enableEdgeToEdge()
|
||||
binding = ActivityAboutBinding.inflate(layoutInflater)
|
||||
setContentView(binding.root)
|
||||
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
|
||||
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
|
||||
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
|
||||
insets
|
||||
}
|
||||
|
||||
with(window){
|
||||
lightStatusBar(true)
|
||||
}
|
||||
|
||||
clickEvents()
|
||||
}
|
||||
|
||||
private fun clickEvents() {
|
||||
binding.apply {
|
||||
backBtn.setOnClickListener {
|
||||
onBackPressedDispatcher.onBackPressed()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,17 +1,39 @@
|
||||
package com.woka.modules
|
||||
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.woka.modules.blogs.BlogsResponse
|
||||
import com.woka.networking.ApiResult
|
||||
import com.woka.networking.RetrofitHelper
|
||||
import com.woka.networking.RetrofitHelper.handleApiCall
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
object BlogsRepository{
|
||||
|
||||
class BlogsRepository {
|
||||
private val apiService = RetrofitHelper.getRetrofit().create(ModuleApiService::class.java)
|
||||
|
||||
suspend fun getBlogs(): ApiResult<BlogsResponse>{
|
||||
private val _blogsLiveData = MutableLiveData<ApiResult<BlogsResponse>>()
|
||||
val blogsLiveData: LiveData<ApiResult<BlogsResponse>?>
|
||||
get() = _blogsLiveData
|
||||
|
||||
init {
|
||||
loadBlogs()
|
||||
}
|
||||
|
||||
private suspend fun getBlogs(): ApiResult<BlogsResponse>{
|
||||
return handleApiCall{
|
||||
apiService.getBlogs()
|
||||
}
|
||||
}
|
||||
|
||||
private fun loadBlogs(){
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
_blogsLiveData.postValue(ApiResult.Loading())
|
||||
_blogsLiveData.postValue(getBlogs())
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
package com.woka.modules
|
||||
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.woka.modules.blogs.BlogsResponse
|
||||
import com.woka.networking.ApiResult
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
class BlogsViewModel: ViewModel() {
|
||||
|
||||
private val blogsRepository = BlogsRepository()
|
||||
|
||||
private val _blogsLiveData = MutableLiveData<ApiResult<BlogsResponse>>()
|
||||
val blogsLiveData: LiveData<ApiResult<BlogsResponse>?>
|
||||
get() = _blogsLiveData
|
||||
|
||||
init {
|
||||
loadBlogs()
|
||||
}
|
||||
|
||||
private fun loadBlogs(){
|
||||
viewModelScope.launch {
|
||||
_blogsLiveData.postValue(ApiResult.Loading())
|
||||
_blogsLiveData.postValue(blogsRepository.getBlogs())
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -16,8 +16,8 @@ import androidx.fragment.app.Fragment
|
||||
import com.woka.WokaApp.Companion.userPrefs
|
||||
import java.util.Locale
|
||||
|
||||
fun Window.lightStatusBar(){
|
||||
WindowCompat.getInsetsController(this, decorView).isAppearanceLightStatusBars = false
|
||||
fun Window.lightStatusBar(lightStatus: Boolean = false){
|
||||
WindowCompat.getInsetsController(this, decorView).isAppearanceLightStatusBars = lightStatus
|
||||
}
|
||||
|
||||
fun View.scaleAnimate(from: Float = 0.5f, to: Float = 1f, duration: Long = 500){
|
||||
|
||||
@@ -1,34 +1,20 @@
|
||||
package com.woka.utils
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Build
|
||||
import android.util.AttributeSet
|
||||
import android.util.Log
|
||||
import android.view.HapticFeedbackConstants
|
||||
import android.view.MotionEvent
|
||||
import android.view.MotionEvent.ACTION_CANCEL
|
||||
import android.view.MotionEvent.ACTION_DOWN
|
||||
import android.view.MotionEvent.ACTION_OUTSIDE
|
||||
import android.view.MotionEvent.ACTION_SCROLL
|
||||
import android.view.MotionEvent.ACTION_UP
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.FrameLayout
|
||||
import android.widget.ScrollView
|
||||
import androidx.core.view.ScrollingView
|
||||
import com.woka.R
|
||||
import kotlin.math.abs
|
||||
|
||||
class PressableCard : FrameLayout {
|
||||
|
||||
companion object {
|
||||
private const val DEFAULT_SCALE_WHEN_PRESS = 0.9f
|
||||
private const val DEFAULT_SCALE = 1f
|
||||
|
||||
private const val DEFAULT_ALPHA_WHEN_PRESS = 0.5f
|
||||
private const val DEFAULT_ALPHA = 1f
|
||||
|
||||
private const val MIN_MOMENT_AFTER_TOUCH = 25f
|
||||
}
|
||||
|
||||
enum class PressableType(value: Int){
|
||||
SCALE(0), FADE(1);
|
||||
}
|
||||
@@ -48,39 +34,65 @@ class PressableCard : FrameLayout {
|
||||
|
||||
// attributes
|
||||
private var pressType: PressableType? = PressableType.SCALE
|
||||
private var scaleFrom = 0.9f
|
||||
private var scaleTo = 1f
|
||||
|
||||
private var alphaFrom = 0.5f
|
||||
private var alphaTo = 1f
|
||||
|
||||
private var isHapticEnabled = false
|
||||
var isPressable = true
|
||||
|
||||
private fun setPressType(attrs: AttributeSet?){
|
||||
val attributes = context.obtainStyledAttributes(attrs, R.styleable.PressableCard)
|
||||
|
||||
val value = attributes.getInt(R.styleable.PressableCard_pressType, 0)
|
||||
pressType = when(value){
|
||||
1 -> PressableType.FADE
|
||||
else -> PressableType.SCALE
|
||||
}
|
||||
|
||||
scaleFrom = attributes.getFloat(R.styleable.PressableCard_scaleFrom, 0.9f)
|
||||
scaleTo = attributes.getFloat(R.styleable.PressableCard_scaleTo, 1f)
|
||||
|
||||
alphaFrom = attributes.getFloat(R.styleable.PressableCard_alphaFrom, 0.5f)
|
||||
alphaTo = attributes.getFloat(R.styleable.PressableCard_alphaTo, 1f)
|
||||
|
||||
isHapticEnabled = attributes.getBoolean(R.styleable.PressableCard_isHapticEnabled, false)
|
||||
|
||||
attributes.recycle()
|
||||
}
|
||||
|
||||
private fun refresh() {
|
||||
if (isPressed) {
|
||||
if (isHapticEnabled){
|
||||
performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY)
|
||||
}
|
||||
if (pressType == PressableType.SCALE){
|
||||
scaleX = (DEFAULT_SCALE_WHEN_PRESS)
|
||||
scaleY = (DEFAULT_SCALE_WHEN_PRESS)
|
||||
scaleX = (scaleFrom)
|
||||
scaleY = (scaleFrom)
|
||||
}else if (pressType == PressableType.FADE){
|
||||
alpha = DEFAULT_ALPHA_WHEN_PRESS
|
||||
alpha = alphaFrom
|
||||
}
|
||||
invalidate()
|
||||
return
|
||||
}
|
||||
|
||||
if (isHapticEnabled && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
|
||||
performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY_RELEASE)
|
||||
}
|
||||
if (pressType == PressableType.SCALE){
|
||||
scaleX = (DEFAULT_SCALE)
|
||||
scaleY = (DEFAULT_SCALE)
|
||||
scaleX = (scaleTo)
|
||||
scaleY = (scaleTo)
|
||||
}else if (pressType == PressableType.FADE){
|
||||
alpha = DEFAULT_ALPHA
|
||||
alpha = alphaTo
|
||||
}
|
||||
invalidate()
|
||||
}
|
||||
|
||||
override fun setPressed(pressed: Boolean) {
|
||||
super.setPressed(pressed)
|
||||
if (!isPressable) return
|
||||
refresh()
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user