refactor: Cleaned up the way that we move between fragments

I have removed the need for ViewPager2 to move between fragments
This commit is contained in:
HeCodes2Much
2024-05-23 19:05:57 +01:00
parent 0d32f77e0f
commit 9e05fe7c38
36 changed files with 929 additions and 839 deletions

View File

@@ -28,7 +28,10 @@ android {
isShrinkResources = false
isDebuggable = true
applicationIdSuffix = ".debug"
proguardFiles (getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
resValue("string", "app_name", "Easy Launcher (Debug)")
resValue("string", "settings_backups_file", "autoBackup.debug.ini")
}
@@ -36,7 +39,10 @@ android {
getByName("release") {
isMinifyEnabled = true
isShrinkResources = true
proguardFiles (getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
resValue("string", "app_name", "Easy Launcher")
resValue("string", "settings_backups_file", "autoBackup.ini")
}
@@ -89,11 +95,11 @@ dependencies {
implementation(libs.lifecycle.viewmodel.ktx)
implementation(libs.work.runtime.ktx)
implementation(libs.recyclerview)
implementation(libs.viewpager2)
implementation(libs.preference)
implementation(libs.biometric.ktx)
implementation(libs.room.ktx)
implementation(libs.room.runtime)
//noinspection KaptUsageInsteadOfKsp
kapt(libs.room.compiler)
implementation(libs.dagger.hilt.android)

View File

@@ -27,7 +27,7 @@
<application
android:name=".Application"
android:allowBackup="false"
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@drawable/app_launcher"

View File

@@ -63,5 +63,7 @@ object Constants {
const val APP_GOOGLE_PLAY_STORE = "market://search?c=apps&q"
const val APP_WIDGET_HOST_ID = 1024
const val TRIPLE_TAP_DELAY_MS = 300
const val LONG_PRESS_DELAY_MS = 500
const val REQUEST_CODE_ENABLE_ADMIN = 123
}

View File

@@ -11,7 +11,6 @@ import android.util.Log
import android.view.View
import android.view.inputmethod.InputMethodManager
import android.widget.EditText
import android.widget.Toast
import androidx.fragment.app.Fragment
import com.github.droidworksstudio.launcher.Constants
import java.io.File
@@ -28,7 +27,6 @@ fun View.showKeyboard(show: Boolean = true) {
if (this.requestFocus())
this.postDelayed({
this.findViewById<EditText>(androidx.appcompat.R.id.search_src_text).apply {
textSize = 28f
isCursorVisible = false
}
val imm = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager

View File

@@ -24,11 +24,14 @@ import android.view.WindowManager
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.widget.LinearLayoutCompat
import androidx.fragment.app.Fragment
import androidx.navigation.fragment.findNavController
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.github.droidworksstudio.launcher.Constants
import com.github.droidworksstudio.launcher.R
import com.github.droidworksstudio.launcher.accessibility.MyAccessibilityService
import com.github.droidworksstudio.launcher.data.entities.AppInfo
import com.github.droidworksstudio.launcher.listener.OnSwipeTouchListener
import com.github.droidworksstudio.launcher.ui.activities.FakeHomeActivity
import java.util.Calendar
import java.util.Date

View File

@@ -5,18 +5,18 @@ import com.github.droidworksstudio.launcher.data.entities.AppInfo
class OnItemClickedListener {
interface OnAppsClickedListener{
fun onAppClicked(appInfo: AppInfo)
fun onAppClicked(appInfo: AppInfo) {}
}
interface OnAppLongClickedListener{
fun onAppLongClicked(appInfo: AppInfo)
fun onAppLongClicked(appInfo: AppInfo) {}
}
interface BottomSheetDismissListener {
fun onBottomSheetDismissed()
fun onBottomSheetDismissed() {}
}
interface OnAppStateClickListener{
fun onAppStateClicked(appInfo: AppInfo)
fun onAppStateClicked(appInfo: AppInfo) {}
}
}

View File

@@ -3,6 +3,6 @@ package com.github.droidworksstudio.launcher.listener
class OnItemMoveListener {
interface OnItemActionListener {
fun onViewMoved(oldPosition: Int, newPosition: Int): Boolean
fun onViewSwiped(position: Int)
fun onViewSwiped(position: Int) {}
}
}

View File

@@ -3,15 +3,23 @@ package com.github.droidworksstudio.launcher.listener
import android.annotation.SuppressLint
import android.content.Context
import android.view.GestureDetector
import android.view.GestureDetector.SimpleOnGestureListener
import android.view.MotionEvent
import android.view.View
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import android.view.View.OnTouchListener
import com.github.droidworksstudio.launcher.Constants
import java.util.*
import kotlin.concurrent.schedule
import kotlin.math.abs
internal open class OnSwipeTouchListener(c: Context?) : View.OnTouchListener {
/*
Swipe, double tap and long press touch listener for a view
Source: https://www.tutorialspoint.com/how-to-handle-swipe-gestures-in-kotlin
*/
internal open class OnSwipeTouchListener(c: Context?) : OnTouchListener {
private var longPressOn = false
private var doubleTapOn = false
private val gestureDetector: GestureDetector
@SuppressLint("ClickableViewAccessibility")
@@ -21,7 +29,7 @@ internal open class OnSwipeTouchListener(c: Context?) : View.OnTouchListener {
return gestureDetector.onTouchEvent(motionEvent)
}
private inner class GestureListener : GestureDetector.SimpleOnGestureListener() {
private inner class GestureListener : SimpleOnGestureListener() {
private val swipeThreshold: Int = 100
private val swipeVelocityThreshold: Int = 100
@@ -29,37 +37,48 @@ internal open class OnSwipeTouchListener(c: Context?) : View.OnTouchListener {
return true
}
override fun onSingleTapUp(e: MotionEvent): Boolean {
if (doubleTapOn) {
doubleTapOn = false
onTripleClick()
}
return super.onSingleTapUp(e)
}
override fun onDoubleTap(e: MotionEvent): Boolean {
onDoubleClick()
doubleTapOn = true
Timer().schedule(Constants.TRIPLE_TAP_DELAY_MS.toLong()) {
if (doubleTapOn) {
doubleTapOn = false
onDoubleClick()
}
}
return super.onDoubleTap(e)
}
override fun onLongPress(e: MotionEvent) {
longPressOn = true
val scope = CoroutineScope(Dispatchers.Main)
scope.launch {
if (longPressOn) {
onLongClick()
}
Timer().schedule(Constants.LONG_PRESS_DELAY_MS.toLong()) {
if (longPressOn) onLongClick()
}
super.onLongPress(e)
}
override fun onFling(
e1: MotionEvent?,
event1: MotionEvent,
event1: MotionEvent?,
event2: MotionEvent,
velocityX: Float,
velocityY: Float
): Boolean {
try {
val diffY = event1.y - event1.y
val diffX = event1.x - event1.x
if (kotlin.math.abs(diffX) > kotlin.math.abs(diffY)) {
if (kotlin.math.abs(diffX) > swipeThreshold && kotlin.math.abs(velocityX) > swipeVelocityThreshold) {
val diffY = event2.y - event1!!.y
val diffX = event2.x - event1.x
if (abs(diffX) > abs(diffY)) {
if (abs(diffX) > swipeThreshold && abs(velocityX) > swipeVelocityThreshold) {
if (diffX > 0) onSwipeRight() else onSwipeLeft()
}
} else {
if (kotlin.math.abs(diffY) > swipeThreshold && kotlin.math.abs(velocityY) > swipeVelocityThreshold) {
if (abs(diffY) > swipeThreshold && abs(velocityY) > swipeVelocityThreshold) {
if (diffY < 0) onSwipeUp() else onSwipeDown()
}
}
@@ -76,7 +95,7 @@ internal open class OnSwipeTouchListener(c: Context?) : View.OnTouchListener {
open fun onSwipeDown() {}
open fun onLongClick() {}
open fun onDoubleClick() {}
open fun onTripleClick() {}
init {
gestureDetector = GestureDetector(c, GestureListener())
}

View File

@@ -1,7 +1,5 @@
package com.github.droidworksstudio.launcher.listener
interface ScrollEventListener {
fun onTopReached()
fun onBottomReached()
fun onScroll(isTopReached: Boolean, isBottomReached: Boolean)
fun onScroll(isTopReached: Boolean, isBottomReached: Boolean) {}
}

View File

@@ -4,7 +4,6 @@ import android.annotation.SuppressLint
import android.content.pm.ActivityInfo
import android.os.Build
import android.os.Bundle
import android.util.Log
import android.view.Menu
import android.view.MenuItem
import android.view.WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
@@ -20,8 +19,6 @@ import com.github.droidworksstudio.launcher.R
import com.github.droidworksstudio.launcher.databinding.ActivityMainBinding
import com.github.droidworksstudio.launcher.helper.AppHelper
import com.github.droidworksstudio.launcher.helper.PreferenceHelper
import com.github.droidworksstudio.launcher.ui.drawer.DrawFragment
import com.github.droidworksstudio.launcher.ui.viewpager.ViewPagerAdapter
import com.github.droidworksstudio.launcher.viewmodel.AppViewModel
import com.github.droidworksstudio.launcher.viewmodel.PreferenceViewModel
import dagger.hilt.android.AndroidEntryPoint
@@ -46,8 +43,6 @@ class MainActivity : AppCompatActivity() {
@Inject
lateinit var appHelper: AppHelper
private val viewPagerAdapter: ViewPagerAdapter by lazy { ViewPagerAdapter(supportFragmentManager, lifecycle) }
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@@ -56,7 +51,6 @@ class MainActivity : AppCompatActivity() {
initializeDependencies()
setupNavController()
setupViewPagerAdapter()
setupOrientation()
}
@@ -73,12 +67,10 @@ class MainActivity : AppCompatActivity() {
lifecycleScope.launch {
viewModel.initializeInstalledAppInfo(this@MainActivity)
}
//GlobalScope.launch { }
preferenceHelper.firstLaunch = false
}
private fun observeUI() {
binding.pager.currentItem = 1
preferenceViewModel.setShowStatusBar(preferenceHelper.showStatusBar)
preferenceViewModel.showStatusBarLiveData.observe(this) {
if (it) appHelper.showStatusBar(this.window)
@@ -94,12 +86,6 @@ class MainActivity : AppCompatActivity() {
appBarConfiguration = AppBarConfiguration(navController.graph)
}
private fun setupViewPagerAdapter() {
binding.pager.apply {
adapter = viewPagerAdapter
offscreenPageLimit = 1
}
}
@SuppressLint("SourceLockedOrientationActivity")
private fun setupOrientation() {
if (appHelper.isTablet(this)) return
@@ -143,18 +129,10 @@ class MainActivity : AppCompatActivity() {
@Deprecated("Deprecated in Java")
override fun onBackPressed() {
val currentItem = binding.pager.currentItem
Log.d("currentItem","$currentItem")
val navHostFragment =
supportFragmentManager.findFragmentById(R.id.nav_host_fragment_content_main) as NavHostFragment
val currentFragment = navHostFragment.childFragmentManager.fragments[0]
if (currentFragment is DrawFragment) {
@Suppress("DEPRECATION")
navController = findNavController(R.id.nav_host_fragment_content_main)
@Suppress("DEPRECATION")
if (navController.currentDestination?.id != R.id.HomeFragment)
super.onBackPressed()
} else {
binding.pager.currentItem = currentItem - 1
}
}
private fun backToHomeScreen() {

View File

@@ -13,6 +13,7 @@ import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import androidx.lifecycle.coroutineScope
import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.findNavController
import androidx.recyclerview.widget.StaggeredGridLayoutManager
import com.github.droidworksstudio.launcher.R
import com.github.droidworksstudio.launcher.data.entities.AppInfo
@@ -26,6 +27,8 @@ import com.github.droidworksstudio.launcher.helper.searchCustomSearchEngine
import com.github.droidworksstudio.launcher.helper.searchOnPlayStore
import com.github.droidworksstudio.launcher.helper.showKeyboard
import com.github.droidworksstudio.launcher.listener.OnItemClickedListener
import com.github.droidworksstudio.launcher.listener.OnSwipeTouchListener
import com.github.droidworksstudio.launcher.listener.ScrollEventListener
import com.github.droidworksstudio.launcher.ui.bottomsheetdialog.AppInfoBottomSheetFragment
import com.github.droidworksstudio.launcher.viewmodel.AppViewModel
import dagger.hilt.android.AndroidEntryPoint
@@ -40,7 +43,7 @@ class DrawFragment : Fragment(), OnItemClickedListener.OnAppsClickedListener,
OnItemClickedListener.OnAppLongClickedListener,
OnItemClickedListener.BottomSheetDismissListener,
OnItemClickedListener.OnAppStateClickListener,
FingerprintHelper.Callback {
FingerprintHelper.Callback, ScrollEventListener {
private var _binding: FragmentDrawBinding? = null
private val binding get() = _binding!!
@@ -78,6 +81,7 @@ class DrawFragment : Fragment(), OnItemClickedListener.OnAppsClickedListener,
setupRecyclerView()
setupSearch()
observeClickListener()
observeSwipeTouchListener()
}
private fun setupRecyclerView() {
@@ -94,7 +98,7 @@ class DrawFragment : Fragment(), OnItemClickedListener.OnAppsClickedListener,
@Suppress("DEPRECATION")
viewLifecycleOwner.lifecycleScope.launchWhenCreated {
viewModel.drawApps.collect{
viewModel.drawApps.collect {
drawAdapter.submitList(it)
drawAdapter.updateDataWithStateFlow(it)
}
@@ -121,6 +125,7 @@ class DrawFragment : Fragment(), OnItemClickedListener.OnAppsClickedListener,
}
return true
}
override fun onQueryTextChange(newText: String?): Boolean {
searchApp(newText.toString())
return true
@@ -129,12 +134,33 @@ class DrawFragment : Fragment(), OnItemClickedListener.OnAppsClickedListener,
}
private fun observeClickListener(){
@SuppressLint("ClickableViewAccessibility")
private fun observeClickListener() {
binding.drawSearchButton.setOnClickListener {
binding.searchViewText.showKeyboard()
}
}
@SuppressLint("ClickableViewAccessibility")
private fun observeSwipeTouchListener() {
binding.touchArea.setOnTouchListener(getSwipeGestureListener(context))
}
private fun getSwipeGestureListener(context: Context): View.OnTouchListener {
return object : OnSwipeTouchListener(context) {
override fun onSwipeLeft() {
super.onSwipeLeft()
findNavController().popBackStack()
}
override fun onSwipeRight() {
super.onSwipeRight()
findNavController().popBackStack()
}
}
}
private fun searchApp(query: String) {
val searchQuery = "%$query%"
@Suppress("DEPRECATION")
@@ -202,9 +228,6 @@ class DrawFragment : Fragment(), OnItemClickedListener.OnAppsClickedListener,
showSelectedApp(appInfo)
}
override fun onBottomSheetDismissed() {
}
override fun onAppStateClicked(appInfo: AppInfo) {
viewModel.update(appInfo)
Log.d("Tag", "${appInfo.appName} : Draw Favorite: ${appInfo.favorite}")
@@ -214,7 +237,7 @@ class DrawFragment : Fragment(), OnItemClickedListener.OnAppsClickedListener,
if (!appInfo.lock) {
appHelper.launchApp(context, appInfo)
} else {
fingerHelper.startFingerprintAuth(appInfo,this)
fingerHelper.startFingerprintAuth(appInfo, this)
}
}

View File

@@ -13,6 +13,7 @@ import androidx.annotation.RequiresApi
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.findNavController
import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.StaggeredGridLayoutManager
@@ -24,6 +25,7 @@ import com.github.droidworksstudio.launcher.helper.FingerprintHelper
import com.github.droidworksstudio.launcher.helper.PreferenceHelper
import com.github.droidworksstudio.launcher.listener.OnItemClickedListener
import com.github.droidworksstudio.launcher.listener.OnItemMoveListener
import com.github.droidworksstudio.launcher.listener.OnSwipeTouchListener
import com.github.droidworksstudio.launcher.viewmodel.AppViewModel
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.launch
@@ -75,6 +77,7 @@ class FavoriteFragment : Fragment(), OnItemClickedListener.OnAppsClickedListener
context = requireContext()
setupRecyclerView()
observeSwipeTouchListener()
observeFavorite()
observeHomeAppOrder()
}
@@ -88,6 +91,20 @@ class FavoriteFragment : Fragment(), OnItemClickedListener.OnAppsClickedListener
}
}
@SuppressLint("ClickableViewAccessibility")
private fun observeSwipeTouchListener() {
binding.touchArea.setOnTouchListener(getSwipeGestureListener(context))
}
private fun getSwipeGestureListener(context: Context): View.OnTouchListener {
return object : OnSwipeTouchListener(context) {
override fun onSwipeLeft() {
super.onSwipeLeft()
findNavController().popBackStack()
}
}
}
private fun handleDragAndDrop(oldPosition: Int, newPosition: Int) {
val items = favoriteAdapter.currentList.toMutableList()
Collections.swap(items, oldPosition, newPosition)
@@ -106,7 +123,7 @@ class FavoriteFragment : Fragment(), OnItemClickedListener.OnAppsClickedListener
binding.favoriteAdapter.adapter = favoriteAdapter
val listener: OnItemMoveListener.OnItemActionListener = favoriteAdapter
val simpleItemTouchCallback = object : ItemTouchHelper.Callback() {
val simpleItemTouchCallback = object : ItemTouchHelper.Callback() {
override fun onChildDraw(
canvas: Canvas, recyclerView: RecyclerView,

View File

@@ -12,6 +12,7 @@ import androidx.annotation.RequiresApi
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.findNavController
import androidx.recyclerview.widget.StaggeredGridLayoutManager
import com.github.droidworksstudio.launcher.R
import com.github.droidworksstudio.launcher.data.entities.AppInfo
@@ -19,6 +20,7 @@ import com.github.droidworksstudio.launcher.databinding.FragmentHiddenBinding
import com.github.droidworksstudio.launcher.helper.AppHelper
import com.github.droidworksstudio.launcher.helper.FingerprintHelper
import com.github.droidworksstudio.launcher.listener.OnItemClickedListener
import com.github.droidworksstudio.launcher.listener.OnSwipeTouchListener
import com.github.droidworksstudio.launcher.ui.bottomsheetdialog.AppInfoBottomSheetFragment
import com.github.droidworksstudio.launcher.viewmodel.AppViewModel
import dagger.hilt.android.AndroidEntryPoint
@@ -64,6 +66,7 @@ class HiddenFragment : Fragment(), OnItemClickedListener.OnAppsClickedListener,
context = requireContext()
setupRecyclerView()
observeSwipeTouchListener()
observeHiddenApps()
}
@@ -76,6 +79,20 @@ class HiddenFragment : Fragment(), OnItemClickedListener.OnAppsClickedListener,
}
@SuppressLint("ClickableViewAccessibility")
private fun observeSwipeTouchListener() {
binding.touchArea.setOnTouchListener(getSwipeGestureListener(context))
}
private fun getSwipeGestureListener(context: Context): View.OnTouchListener {
return object : OnSwipeTouchListener(context) {
override fun onSwipeLeft() {
super.onSwipeLeft()
findNavController().popBackStack()
}
}
}
private fun observeHiddenApps() {
viewModel.compareInstalledAppInfo()
@Suppress("DEPRECATION")
@@ -90,7 +107,7 @@ class HiddenFragment : Fragment(), OnItemClickedListener.OnAppsClickedListener,
if (!appInfo.lock) {
appHelper.launchApp(context, appInfo)
} else {
fingerHelper.startFingerprintAuth(appInfo,this)
fingerHelper.startFingerprintAuth(appInfo, this)
}
}

View File

@@ -17,6 +17,7 @@ import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.findNavController
import androidx.recyclerview.widget.StaggeredGridLayoutManager
import com.github.droidworksstudio.launcher.R
import com.github.droidworksstudio.launcher.accessibility.MyAccessibilityService
@@ -90,10 +91,10 @@ class HomeFragment : Fragment(), OnItemClickedListener.OnAppsClickedListener,
super.onViewCreated(view, savedInstanceState)
initializeInjectedDependencies()
initSwipeTouchListener()
setupBattery()
setupRecyclerView()
observeUserInterfaceSettings()
}
@SuppressLint("ClickableViewAccessibility")
@@ -108,8 +109,11 @@ class HomeFragment : Fragment(), OnItemClickedListener.OnAppsClickedListener,
preferenceViewModel.setShowTime(preferenceHelper.showTime)
preferenceViewModel.setShowDate(preferenceHelper.showDate)
preferenceViewModel.setShowDailyWord(preferenceHelper.showDailyWord)
}
binding.mainView.setOnTouchListener(getSwipeGestureListener(context))
@SuppressLint("ClickableViewAccessibility")
private fun initSwipeTouchListener() {
binding.touchArea.setOnTouchListener(getSwipeGestureListener(context))
binding.clock.setOnClickListener { appHelper.launchClock(context) }
binding.date.setOnClickListener { appHelper.launchCalendar(context) }
@@ -134,7 +138,8 @@ class HomeFragment : Fragment(), OnItemClickedListener.OnAppsClickedListener,
private fun setupRecyclerView() {
val marginTopInPixels = 128
val params: ViewGroup.MarginLayoutParams = binding.appListAdapter.layoutParams as ViewGroup.MarginLayoutParams
val params: ViewGroup.MarginLayoutParams =
binding.appListAdapter.layoutParams as ViewGroup.MarginLayoutParams
params.topMargin = marginTopInPixels
binding.appListAdapter.apply {
@@ -168,7 +173,8 @@ class HomeFragment : Fragment(), OnItemClickedListener.OnAppsClickedListener,
preferenceViewModel.showTimeLiveData.observe(viewLifecycleOwner) {
Log.d("Tag", "ShowTime Home: $it")
appHelper.updateUI(binding.clock,
appHelper.updateUI(
binding.clock,
preferenceHelper.homeTimeAlignment,
preferenceHelper.timeColor,
preferenceHelper.timeTextSize,
@@ -177,15 +183,17 @@ class HomeFragment : Fragment(), OnItemClickedListener.OnAppsClickedListener,
}
preferenceViewModel.showDateLiveData.observe(viewLifecycleOwner) {
appHelper.updateUI(binding.date,
appHelper.updateUI(
binding.date,
preferenceHelper.homeDateAlignment,
preferenceHelper.dateColor,
preferenceHelper.dateTextSize,
preferenceHelper.showDate
)
}
preferenceViewModel.showBatteryLiveData.observe(viewLifecycleOwner){
appHelper.updateUI(binding.battery,
preferenceViewModel.showBatteryLiveData.observe(viewLifecycleOwner) {
appHelper.updateUI(
binding.battery,
Gravity.END,
preferenceHelper.batteryColor,
preferenceHelper.batteryTextSize,
@@ -194,7 +202,8 @@ class HomeFragment : Fragment(), OnItemClickedListener.OnAppsClickedListener,
}
preferenceViewModel.showDailyWordLiveData.observe(viewLifecycleOwner) {
appHelper.updateUI(binding.word,
appHelper.updateUI(
binding.word,
preferenceHelper.homeDailyWordAlignment,
preferenceHelper.dailyWordColor,
preferenceHelper.dailyWordTextSize,
@@ -217,7 +226,10 @@ class HomeFragment : Fragment(), OnItemClickedListener.OnAppsClickedListener,
}
private fun observeBioAuthCheck(appInfo: AppInfo) {
if (!appInfo.lock) appHelper.launchApp(context, appInfo) else fingerHelper.startFingerprintAuth(appInfo, this)
if (!appInfo.lock) appHelper.launchApp(
context,
appInfo
) else fingerHelper.startFingerprintAuth(appInfo, this)
}
private fun showSelectedApp(appInfo: AppInfo) {
@@ -239,13 +251,34 @@ class HomeFragment : Fragment(), OnItemClickedListener.OnAppsClickedListener,
@RequiresApi(Build.VERSION_CODES.P)
override fun onDoubleClick() {
super.onDoubleClick()
if(preferenceHelper.tapLockScreen) {
if (preferenceHelper.tapLockScreen) {
MyAccessibilityService.runAccessibilityMode(context)
MyAccessibilityService.instance()?.lockScreen()
} else {
return
}
}
override fun onSwipeLeft() {
super.onSwipeLeft()
findNavController().navigate(R.id.action_HomeFragment_to_DrawFragment)
}
override fun onSwipeRight() {
super.onSwipeRight()
findNavController().navigate(R.id.action_HomeFragment_to_FavoriteFragment)
}
override fun onSwipeDown() {
super.onSwipeDown()
if (preferenceHelper.swipeNotification) appHelper.expandNotificationDrawer(context)
}
override fun onSwipeUp() {
super.onSwipeUp()
if (preferenceHelper.swipeSearch) appHelper.searchView(context)
}
}
}
@@ -275,7 +308,7 @@ class HomeFragment : Fragment(), OnItemClickedListener.OnAppsClickedListener,
}
override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) {
fingerHelper.sendToTargetActivity(SettingsActivity::class.java)
findNavController().navigate(R.id.action_HomeFragment_to_SettingsFragment)
}
override fun onAuthenticationFailed() {
@@ -289,7 +322,7 @@ class HomeFragment : Fragment(), OnItemClickedListener.OnAppsClickedListener,
if (preferenceHelper.settingsLock) {
fingerHelper.startFingerprintSettingsAuth(SettingsActivity::class.java)
} else {
fingerHelper.sendToTargetActivity(SettingsActivity::class.java)
findNavController().navigate(R.id.action_HomeFragment_to_SettingsFragment)
}
}
}
@@ -321,9 +354,6 @@ class HomeFragment : Fragment(), OnItemClickedListener.OnAppsClickedListener,
Log.d("Tag", "Home LiveData Favorite : ${appInfo.favorite}")
}
override fun onBottomSheetDismissed() {
}
override fun onAppStateClicked(appInfo: AppInfo) {
viewModel.update(appInfo)
Log.d("Tag", "${appInfo.appName} : Home Favorite: ${appInfo.favorite}")
@@ -340,20 +370,15 @@ class HomeFragment : Fragment(), OnItemClickedListener.OnAppsClickedListener,
override fun onAuthenticationError(errorCode: Int, errorMessage: CharSequence?) {
when (errorCode) {
BiometricPrompt.ERROR_USER_CANCELED -> appHelper.showToast(requireContext(), getString(R.string.authentication_cancel))
else -> appHelper.showToast(requireContext(), getString(R.string.authentication_error).format(errorMessage, errorCode))
BiometricPrompt.ERROR_USER_CANCELED -> appHelper.showToast(
requireContext(),
getString(R.string.authentication_cancel)
)
else -> appHelper.showToast(
requireContext(),
getString(R.string.authentication_error).format(errorMessage, errorCode)
)
}
}
override fun onTopReached() {
if (preferenceHelper.swipeNotification) appHelper.expandNotificationDrawer(context)
}
override fun onBottomReached() {
if (preferenceHelper.swipeSearch) appHelper.searchView(context)
}
override fun onScroll(isTopReached: Boolean, isBottomReached: Boolean) {
Log.d("Tag", "onScroll")
}
}

View File

@@ -202,16 +202,4 @@ class SettingsFragment : Fragment(), ScrollEventListener {
preferenceViewModel.setLockSettings(isChecked)
}
}
override fun onTopReached() {
requireActivity().onBackPressedDispatcher.onBackPressed()
}
override fun onBottomReached() {
Log.d("Tag", "onBottomReached")
}
override fun onScroll(isTopReached: Boolean, isBottomReached: Boolean) {
Log.d("Tag", "onScroll")
}
}

View File

@@ -1,28 +0,0 @@
package com.github.droidworksstudio.launcher.ui.viewpager
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import androidx.lifecycle.Lifecycle
import androidx.viewpager2.adapter.FragmentStateAdapter
import com.github.droidworksstudio.launcher.ui.drawer.DrawFragment
import com.github.droidworksstudio.launcher.ui.home.HomeFragment
import com.github.droidworksstudio.launcher.ui.widgetmanager.WidgetManagerFragment
class ViewPagerAdapter(fragmentManager: FragmentManager, lifecycle: Lifecycle) :
FragmentStateAdapter(fragmentManager, lifecycle) {
private val fragments: ArrayList<Fragment> = arrayListOf(
WidgetManagerFragment(),
HomeFragment(),
DrawFragment(),
)
override fun getItemCount(): Int {
return fragments.size
}
override fun createFragment(position: Int): Fragment {
return fragments[position]
}
}

View File

@@ -1,24 +1,13 @@
package com.github.droidworksstudio.launcher.view
import android.annotation.SuppressLint
import android.content.Context
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.ViewConfiguration
import androidx.core.widget.NestedScrollView
import androidx.recyclerview.widget.RecyclerView
import com.github.droidworksstudio.launcher.listener.ScrollEventListener
class GestureNestedScrollView(context: Context, attrs: AttributeSet) : NestedScrollView(context, attrs){
private var startY: Float = 0f
private var startTouchY: Float = 0f
private var isTopReached: Boolean = false
private var isBottomReached: Boolean = false
private var isScrollingUp: Boolean = false
private var isPullingDown: Boolean = false
private var isPullingUp: Boolean = false
var scrollEventListener: ScrollEventListener? = null
@@ -26,73 +15,12 @@ class GestureNestedScrollView(context: Context, attrs: AttributeSet) : NestedScr
isNestedScrollingEnabled = true
}
override fun onInterceptTouchEvent(ev: MotionEvent): Boolean {
when (ev.action) {
MotionEvent.ACTION_DOWN -> {
startY = ev.y
startTouchY = ev.y
isScrollingUp = false
isPullingDown = false
isPullingUp = false
}
MotionEvent.ACTION_MOVE -> {
val deltaY = ev.y - startY
isTopReached = !canScrollVertically(-1)
isBottomReached = !canScrollVertically(1)
isScrollingUp = deltaY < 0 && isTopReached
val distanceY = ev.y - startTouchY
val threshold = ViewConfiguration.get(context).scaledTouchSlop.toFloat()
isPullingDown = distanceY > threshold && isTopReached
isPullingUp = distanceY < -threshold && isBottomReached
}
}
return super.onInterceptTouchEvent(ev)
}
@SuppressLint("ClickableViewAccessibility")
override fun onTouchEvent(ev: MotionEvent): Boolean {
when (ev.action) {
MotionEvent.ACTION_DOWN -> {
startY = ev.y
startTouchY = ev.y
isScrollingUp = false
isPullingDown = false
isPullingUp = false
}
MotionEvent.ACTION_MOVE -> {
val deltaY = ev.y - startY
isTopReached = !canScrollVertically(-1)
isBottomReached = !canScrollVertically(1)
isScrollingUp = deltaY < 0 && isTopReached
val distanceY = ev.y - startTouchY
val threshold = 200
isPullingDown = distanceY > threshold && isTopReached
isPullingUp = distanceY < -threshold && isBottomReached
}
MotionEvent.ACTION_UP -> {
startY = 0f
if (isPullingDown) {
scrollEventListener?.onTopReached()
return true
} else if (isPullingUp) {
scrollEventListener?.onBottomReached()
return true
}
}
}
return super.onTouchEvent(ev)
}
fun isTopReached(): Boolean {
return !canScrollVertically(-1)
// return isTopReached && isScrollingUp
}
fun isBottomReached(): Boolean {
return !canScrollVertically(1)
// return isBottomReached && !isScrollingUp
}
fun registerRecyclerView(recyclerView: RecyclerView, eventListener: ScrollEventListener) {

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="300"
android:fromYDelta="100%"
android:toYDelta="0%" />
</set>

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="300"
android:fromXDelta="-100%"
android:toXDelta="0%" />
</set>

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="300"
android:fromXDelta="100%"
android:toXDelta="0%" />
</set>

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="300"
android:fromYDelta="-100%"
android:toYDelta="0%" />
</set>

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="300"
android:fromYDelta="0%"
android:toYDelta="100%" />
</set>

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="300"
android:fromXDelta="0%"
android:toXDelta="-100%" />
</set>

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="300"
android:fromXDelta="0%"
android:toXDelta="100%" />
</set>

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="300"
android:fromYDelta="0%"
android:toYDelta="-100%" />
</set>

View File

@@ -1,32 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/mainActivityLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.activities.MainActivity">
android:animateLayoutChanges="true">
<androidx.fragment.app.FragmentContainerView
<fragment
android:id="@+id/nav_host_fragment_content_main"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="0dp"
android:layout_height="0dp"
app:defaultNavHost="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navGraph="@navigation/nav_graph" />
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toStartOf="parent" />
<!--include layout="@layout/content_main"-->
</androidx.coordinatorlayout.widget.CoordinatorLayout>
app:defaultNavHost="true"
app:navGraph="@navigation/nav_graph"
tools:ignore="FragmentTagUsage" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -8,6 +8,7 @@
tools:context=".ui.drawer.DrawFragment">
<androidx.appcompat.widget.LinearLayoutCompat
android:id="@+id/mainView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
@@ -50,6 +51,13 @@
</androidx.appcompat.widget.LinearLayoutCompat>
<FrameLayout
android:id="@+id/touchArea"
android:layout_marginTop="20dp"
android:layout_marginBottom="20dp"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/draw_search_button"
style="@style/Widget.MaterialComponents.FloatingActionButton"

View File

@@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
@@ -8,39 +7,42 @@
android:id="@+id/favorite_view"
tools:context=".ui.favorite.FavoriteFragment">
<FrameLayout
android:id="@+id/fragment_container"
<FrameLayout
android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:clickable="true"
android:focusable="true"
android:layout_height="match_parent"
android:layout_marginVertical="32dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent">
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/topTextView"
android:layout_width="match_parent"
android:clickable="true"
android:focusable="true"
android:layout_height="match_parent"
android:layout_marginVertical="32dp"
android:layout_height="wrap_content"
android:layout_margin="20dp"
android:text="Home App Order"
android:textSize="@dimen/text_super_large"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent">
app:layout_constraintEnd_toEndOf="parent"
style="@style/TextDefaultStyle" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/topTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="20dp"
android:text="Home App Order"
android:textSize="@dimen/text_super_large"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
style="@style/TextDefaultStyle"/>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/favoriteAdapter"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:layout_marginHorizontal="20dp"
android:layout_marginTop="92dp"
app:layout_constraintTop_toBottomOf="@id/topTextView" />
</FrameLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/favoriteAdapter"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:layout_marginHorizontal="20dp"
android:layout_marginTop="92dp"
app:layout_constraintTop_toBottomOf="@id/topTextView"
/>
</FrameLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
<FrameLayout
android:id="@+id/touchArea"
android:layout_marginTop="20dp"
android:layout_marginBottom="20dp"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -1,12 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/hidden_view"
tools:context=".ui.favorite.FavoriteFragment">
tools:context=".ui.hidden.HiddenFragment">
<FrameLayout
android:id="@+id/fragment_container"
@@ -36,10 +35,13 @@
android:layout_weight="1"
android:layout_marginHorizontal="20dp"
android:layout_marginTop="92dp"
app:layout_constraintTop_toBottomOf="@id/topTextView"
/>
app:layout_constraintTop_toBottomOf="@id/topTextView" />
</FrameLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
<FrameLayout
android:id="@+id/touchArea"
android:layout_marginTop="20dp"
android:layout_marginBottom="20dp"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -92,4 +92,11 @@
</com.github.droidworksstudio.launcher.view.GestureNestedScrollView>
<FrameLayout
android:id="@+id/touchArea"
android:layout_marginTop="20dp"
android:layout_marginBottom="20dp"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -777,4 +777,11 @@
</androidx.appcompat.widget.LinearLayoutCompat>
</com.github.droidworksstudio.launcher.view.GestureNestedScrollView>
<FrameLayout
android:id="@+id/touchArea"
android:layout_marginTop="20dp"
android:layout_marginBottom="20dp"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</FrameLayout>

View File

@@ -19,8 +19,15 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp"/>
android:padding="16dp" />
</FrameLayout>
<FrameLayout
android:id="@+id/touchArea"
android:layout_marginTop="20dp"
android:layout_marginBottom="20dp"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -12,21 +12,57 @@
<action
android:id="@+id/action_HomeFragment_to_DrawFragment"
app:destination="@id/DrawFragment" />
app:destination="@id/DrawFragment"
app:enterAnim="@anim/slide_in_right"
app:exitAnim="@anim/slide_out_left"
app:popEnterAnim="@anim/slide_in_left"
app:popExitAnim="@anim/slide_out_right" />
<action
android:id="@+id/action_HomeFragment_to_SettingsFragment"
app:destination="@id/SettingsFragment" />
app:destination="@id/SettingsFragment"
app:enterAnim="@anim/slide_in_top"
app:exitAnim="@anim/slide_out_top"
app:popEnterAnim="@anim/slide_in_bottom"
app:popExitAnim="@anim/slide_out_bottom" />
<action
android:id="@+id/action_HomeFragment_to_FavoriteFragment"
app:destination="@id/FavoriteFragment" />
app:destination="@id/FavoriteFragment"
app:enterAnim="@anim/slide_in_left"
app:exitAnim="@anim/slide_out_right"
app:popEnterAnim="@anim/slide_in_right"
app:popExitAnim="@anim/slide_out_left" />
<action
android:id="@+id/action_HomeFragment_to_WidgetsFragment"
app:destination="@id/WidgetsFragment"
app:enterAnim="@anim/slide_in_left"
app:exitAnim="@anim/slide_out_right"
app:popEnterAnim="@anim/slide_in_right"
app:popExitAnim="@anim/slide_out_left" />
</fragment>
<fragment
android:id="@+id/SettingsFragment"
android:name="com.github.droidworksstudio.launcher.ui.settings.SettingsFragment"
android:label="@string/settings_fragment_label"
tools:layout="@layout/fragment_settings" />
<fragment
android:id="@+id/WidgetsFragment"
android:name="com.github.droidworksstudio.launcher.ui.widgetmanager.WidgetManagerFragment"
android:label="@string/widgets_fragment_label"
tools:layout="@layout/fragment_widget_manager" />
<fragment
android:id="@+id/DrawFragment"
android:name="com.github.droidworksstudio.launcher.ui.drawer.DrawFragment"
android:label="@string/draw_fragment_label"
tools:layout="@layout/fragment_draw">
</fragment>
tools:layout="@layout/fragment_draw" />
<fragment
android:id="@+id/FavoriteFragment"
android:name="com.github.droidworksstudio.launcher.ui.favorite.FavoriteFragment"
android:label="@string/favorite_fragment_label"
tools:layout="@layout/fragment_favorite" />
</navigation>

View File

@@ -9,30 +9,32 @@
android:name="com.github.droidworksstudio.launcher.ui.settings.SettingsFragment"
android:label="@string/home_fragment_label"
tools:layout="@layout/fragment_settings">
<action
android:id="@+id/action_SettingsFragment_to_FavoriteFragment"
app:destination="@id/FavoriteFragment" />
app:destination="@id/FavoriteFragment"
app:enterAnim="@anim/slide_in_right"
app:exitAnim="@anim/slide_out_left"
app:popEnterAnim="@anim/slide_in_left"
app:popExitAnim="@anim/slide_out_right" />
<action
android:id="@+id/action_SettingsFragment_to_HiddenFragment"
app:destination="@id/HiddenFragment" />
app:destination="@id/HiddenFragment"
app:enterAnim="@anim/slide_in_right"
app:exitAnim="@anim/slide_out_left"
app:popEnterAnim="@anim/slide_in_left"
app:popExitAnim="@anim/slide_out_right" />
</fragment>
<fragment
android:id="@+id/FavoriteFragment"
android:name="com.github.droidworksstudio.launcher.ui.favorite.FavoriteFragment"
android:label="@string/draw_fragment_label"
tools:layout="@layout/fragment_favorite">
</fragment>
android:label="@string/favorite_fragment_label"
tools:layout="@layout/fragment_favorite" />
<fragment
android:id="@+id/HiddenFragment"
android:name="com.github.droidworksstudio.launcher.ui.hidden.HiddenFragment"
android:label="@string/draw_fragment_label"
tools:layout="@layout/fragment_favorite">
</fragment>
android:label="@string/hidden_fragment_label"
tools:layout="@layout/fragment_favorite" />
</navigation>

File diff suppressed because it is too large Load Diff

View File

@@ -13,7 +13,6 @@ lifecycle = "2.8.0"
dagger = "2.51.1"
work = "2.9.0"
recyclerview = "1.3.2"
viewpager2 = "1.1.0"
preference = "1.2.1"
room = "2.6.1"
biometric = "1.2.0-alpha05"
@@ -31,7 +30,6 @@ lifecycle-process = { group = "androidx.lifecycle", name = "lifecycle-process",
lifecycle-runtime-ktx = { group = "androidx.lifecycle", name = "lifecycle-runtime-ktx", version.ref = "lifecycle" }
work-runtime-ktx = { group = "androidx.work", name = "work-runtime-ktx", version.ref = "work" }
recyclerview = { group = "androidx.recyclerview", name = "recyclerview", version.ref = "recyclerview" }
viewpager2 = { group = "androidx.viewpager2", name = "viewpager2", version.ref = "viewpager2" }
preference = { group = "androidx.preference", name = "preference-ktx", version.ref = "preference" }
biometric-ktx = { group = "androidx.biometric", name = "biometric-ktx", version.ref = "biometric" }
color-chooser = { group = "net.mm2d.color-chooser", name = "color-chooser", version.ref = "color-chooser" }