diff --git a/app/build.gradle b/app/build.gradle index 145ffd02..d27b0f93 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,6 +1,5 @@ apply plugin: 'com.android.application' apply plugin: 'kotlin-android' -apply plugin: 'kotlin-android-extensions' def keystorePropertiesFile = rootProject.file("keystore.properties") def keystoreProperties = new Properties() @@ -9,12 +8,13 @@ if (keystorePropertiesFile.exists()) { } android { - compileSdkVersion 33 + namespace "com.simplemobiletools.filemanager.pro" + compileSdk 34 defaultConfig { applicationId "com.simplemobiletools.filemanager.pro" - minSdkVersion 23 - targetSdkVersion 33 + minSdk 23 + targetSdk 34 versionCode 135 versionName "6.16.0" multiDexEnabled true @@ -33,6 +33,11 @@ android { } } + buildFeatures { + buildConfig true + viewBinding true + } + buildTypes { debug { applicationIdSuffix ".debug" @@ -46,7 +51,16 @@ android { } } - flavorDimensions "variants" + compileOptions { + sourceCompatibility JavaVersion.VERSION_17 + targetCompatibility JavaVersion.VERSION_17 + } + + kotlinOptions { + jvmTarget = '17' + } + + flavorDimensions = ["variants"] productFlavors { core {} fdroid {} @@ -64,7 +78,7 @@ android { } dependencies { - implementation 'com.github.SimpleMobileTools:Simple-Commons:ae8713396b' + implementation 'com.github.SimpleMobileTools:Simple-Commons:d1629c7f1a' implementation 'com.github.tibbi:AndroidPdfViewer:e6a533125b' implementation 'com.github.Stericson:RootTools:df729dcb13' implementation 'com.github.Stericson:RootShell:1.6' diff --git a/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/activities/DecompressActivity.kt b/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/activities/DecompressActivity.kt index f3a15dc0..ce7a501f 100644 --- a/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/activities/DecompressActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/activities/DecompressActivity.kt @@ -11,20 +11,22 @@ import com.simplemobiletools.commons.helpers.ensureBackgroundThread import com.simplemobiletools.commons.helpers.isOreoPlus import com.simplemobiletools.filemanager.pro.R import com.simplemobiletools.filemanager.pro.adapters.DecompressItemsAdapter +import com.simplemobiletools.filemanager.pro.databinding.ActivityDecompressBinding import com.simplemobiletools.filemanager.pro.extensions.config import com.simplemobiletools.filemanager.pro.models.ListItem -import kotlinx.android.synthetic.main.activity_decompress.* import net.lingala.zip4j.exception.ZipException import net.lingala.zip4j.exception.ZipException.Type import net.lingala.zip4j.io.inputstream.ZipInputStream import net.lingala.zip4j.model.LocalFileHeader import java.io.BufferedInputStream +import java.io.File class DecompressActivity : SimpleActivity() { companion object { private const val PASSWORD = "password" } + private val binding by lazy(LazyThreadSafetyMode.NONE) { ActivityDecompressBinding.inflate(layoutInflater) } private val allFiles = ArrayList() private var currentPath = "" private var uri: Uri? = null @@ -34,10 +36,12 @@ class DecompressActivity : SimpleActivity() { override fun onCreate(savedInstanceState: Bundle?) { isMaterialActivity = true super.onCreate(savedInstanceState) - setContentView(R.layout.activity_decompress) + setContentView(binding.root) setupOptionsMenu() - updateMaterialActivityViews(decompress_coordinator, decompress_list, useTransparentNavigation = true, useTopSearchMenu = false) - setupMaterialScrollListener(decompress_list, decompress_toolbar) + binding.apply { + updateMaterialActivityViews(decompressCoordinator, decompressList, useTransparentNavigation = true, useTopSearchMenu = false) + setupMaterialScrollListener(decompressList, decompressToolbar) + } uri = intent.data if (uri == null) { @@ -48,13 +52,13 @@ class DecompressActivity : SimpleActivity() { password = savedInstanceState?.getString(PASSWORD, null) val realPath = getRealPathFromURI(uri!!) - decompress_toolbar.title = realPath?.getFilenameFromPath() ?: Uri.decode(uri.toString().getFilenameFromPath()) + binding.decompressToolbar.title = realPath?.getFilenameFromPath() ?: Uri.decode(uri.toString().getFilenameFromPath()) setupFilesList() } override fun onResume() { super.onResume() - setupToolbar(decompress_toolbar, NavigationIcon.Arrow) + setupToolbar(binding.decompressToolbar, NavigationIcon.Arrow) } override fun onSaveInstanceState(outState: Bundle) { @@ -63,7 +67,7 @@ class DecompressActivity : SimpleActivity() { } private fun setupOptionsMenu() { - decompress_toolbar.setOnMenuItemClickListener { menuItem -> + binding.decompressToolbar.setOnMenuItemClickListener { menuItem -> when (menuItem.itemId) { R.id.decompress -> decompressFiles() else -> return@setOnMenuItemClickListener false @@ -90,12 +94,12 @@ class DecompressActivity : SimpleActivity() { currentPath = path try { val listItems = getFolderItems(currentPath) - DecompressItemsAdapter(this, listItems, decompress_list) { + DecompressItemsAdapter(this, listItems, binding.decompressList) { if ((it as ListItem).isDirectory) { updateCurrentPath(it.path) } }.apply { - decompress_list.adapter = this + binding.decompressList.adapter = this } } catch (e: Exception) { showErrorToast(e) @@ -141,6 +145,11 @@ class DecompressActivity : SimpleActivity() { continue } + val isVulnerableForZipPathTraversal = !File(newPath).canonicalPath.startsWith(parent) + if (isVulnerableForZipPathTraversal) { + continue + } + val fos = getFileOutputStreamSync(newPath, newPath.getMimeType()) var count: Int while (true) { diff --git a/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/activities/FavoritesActivity.kt b/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/activities/FavoritesActivity.kt index 911f06bc..0adf4089 100644 --- a/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/activities/FavoritesActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/activities/FavoritesActivity.kt @@ -10,28 +10,31 @@ import com.simplemobiletools.commons.helpers.NavigationIcon import com.simplemobiletools.commons.interfaces.RefreshRecyclerViewListener import com.simplemobiletools.filemanager.pro.R import com.simplemobiletools.filemanager.pro.adapters.ManageFavoritesAdapter +import com.simplemobiletools.filemanager.pro.databinding.ActivityFavoritesBinding import com.simplemobiletools.filemanager.pro.extensions.config -import kotlinx.android.synthetic.main.activity_favorites.* class FavoritesActivity : SimpleActivity(), RefreshRecyclerViewListener { + private val binding by lazy(LazyThreadSafetyMode.NONE) { ActivityFavoritesBinding.inflate(layoutInflater) } override fun onCreate(savedInstanceState: Bundle?) { isMaterialActivity = true super.onCreate(savedInstanceState) - setContentView(R.layout.activity_favorites) + setContentView(binding.root) setupOptionsMenu() updateFavorites() - updateMaterialActivityViews(manage_favorites_coordinator, manage_favorites_list, useTransparentNavigation = true, useTopSearchMenu = false) - setupMaterialScrollListener(manage_favorites_list, manage_favorites_toolbar) + binding.apply { + updateMaterialActivityViews(manageFavoritesCoordinator, manageFavoritesList, useTransparentNavigation = true, useTopSearchMenu = false) + setupMaterialScrollListener(manageFavoritesList, manageFavoritesToolbar) + } } override fun onResume() { super.onResume() - setupToolbar(manage_favorites_toolbar, NavigationIcon.Arrow) + setupToolbar(binding.manageFavoritesToolbar, NavigationIcon.Arrow) } private fun setupOptionsMenu() { - manage_favorites_toolbar.setOnMenuItemClickListener { menuItem -> + binding.manageFavoritesToolbar.setOnMenuItemClickListener { menuItem -> when (menuItem.itemId) { R.id.add_favorite -> addFavorite() else -> return@setOnMenuItemClickListener false @@ -41,22 +44,24 @@ class FavoritesActivity : SimpleActivity(), RefreshRecyclerViewListener { } private fun updateFavorites() { - val favorites = ArrayList() - config.favorites.mapTo(favorites) { it } - manage_favorites_placeholder.beVisibleIf(favorites.isEmpty()) - manage_favorites_placeholder.setTextColor(getProperTextColor()) + binding.apply { + val favorites = ArrayList() + config.favorites.mapTo(favorites) { it } + manageFavoritesPlaceholder.beVisibleIf(favorites.isEmpty()) + manageFavoritesPlaceholder.setTextColor(getProperTextColor()) - manage_favorites_placeholder_2.apply { - paintFlags = paintFlags or Paint.UNDERLINE_TEXT_FLAG - beVisibleIf(favorites.isEmpty()) - setTextColor(getProperPrimaryColor()) - setOnClickListener { - addFavorite() + manageFavoritesPlaceholder2.apply { + paintFlags = paintFlags or Paint.UNDERLINE_TEXT_FLAG + beVisibleIf(favorites.isEmpty()) + setTextColor(getProperPrimaryColor()) + setOnClickListener { + addFavorite() + } } - } - ManageFavoritesAdapter(this, favorites, this, manage_favorites_list) { }.apply { - manage_favorites_list.adapter = this + ManageFavoritesAdapter(this@FavoritesActivity, favorites, this@FavoritesActivity, manageFavoritesList) { }.apply { + manageFavoritesList.adapter = this + } } } diff --git a/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/activities/MainActivity.kt b/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/activities/MainActivity.kt index eb4a3261..ce2a2e83 100644 --- a/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/activities/MainActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/activities/MainActivity.kt @@ -25,6 +25,7 @@ import com.simplemobiletools.commons.models.Release import com.simplemobiletools.filemanager.pro.BuildConfig import com.simplemobiletools.filemanager.pro.R import com.simplemobiletools.filemanager.pro.adapters.ViewPagerAdapter +import com.simplemobiletools.filemanager.pro.databinding.ActivityMainBinding import com.simplemobiletools.filemanager.pro.dialogs.ChangeSortingDialog import com.simplemobiletools.filemanager.pro.dialogs.ChangeViewTypeDialog import com.simplemobiletools.filemanager.pro.dialogs.InsertFilenameDialog @@ -38,11 +39,6 @@ import com.simplemobiletools.filemanager.pro.helpers.MAX_COLUMN_COUNT import com.simplemobiletools.filemanager.pro.helpers.RootHelpers import com.simplemobiletools.filemanager.pro.interfaces.ItemOperationsListener import com.stericson.RootTools.RootTools -import kotlinx.android.synthetic.main.activity_main.* -import kotlinx.android.synthetic.main.items_fragment.* -import kotlinx.android.synthetic.main.items_fragment.view.* -import kotlinx.android.synthetic.main.recents_fragment.* -import kotlinx.android.synthetic.main.storage_fragment.* import me.grantland.widget.AutofitHelper import java.io.File @@ -50,6 +46,8 @@ class MainActivity : SimpleActivity() { private val BACK_PRESS_TIMEOUT = 5000 private val MANAGE_STORAGE_RC = 201 private val PICKED_PATH = "picked_path" + private val binding by lazy(LazyThreadSafetyMode.NONE) { ActivityMainBinding.inflate(layoutInflater) } + private var wasBackJustPressed = false private var mIsPasswordProtectionPending = false private var mWasProtectionHandled = false @@ -63,7 +61,7 @@ class MainActivity : SimpleActivity() { override fun onCreate(savedInstanceState: Bundle?) { isMaterialActivity = true super.onCreate(savedInstanceState) - setContentView(R.layout.activity_main) + setContentView(binding.root) appLaunched(BuildConfig.APPLICATION_ID) setupOptionsMenu() refreshMenuItems() @@ -79,7 +77,7 @@ class MainActivity : SimpleActivity() { storeStateVariables() setupTabs() - updateMaterialActivityViews(main_coordinator, null, useTransparentNavigation = false, useTopSearchMenu = true) + updateMaterialActivityViews(binding.mainCoordinator, null, useTransparentNavigation = false, useTopSearchMenu = true) mIsPasswordProtectionPending = config.isAppPasswordProtectionOn @@ -132,7 +130,7 @@ class MainActivity : SimpleActivity() { } } - if (main_view_pager.adapter == null && mWasProtectionHandled) { + if (binding.mainViewPager.adapter == null && mWasProtectionHandled) { initFragments() } } @@ -140,7 +138,7 @@ class MainActivity : SimpleActivity() { override fun onPause() { super.onPause() storeStateVariables() - config.lastUsedViewPagerPage = main_view_pager.currentItem + config.lastUsedViewPagerPage = binding.mainViewPager.currentItem } override fun onDestroy() { @@ -150,11 +148,11 @@ class MainActivity : SimpleActivity() { override fun onBackPressed() { val currentFragment = getCurrentFragment() - if (main_menu.isSearchOpen) { - main_menu.closeSearch() + if (binding.mainMenu.isSearchOpen) { + binding.mainMenu.closeSearch() } else if (currentFragment is RecentsFragment || currentFragment is StorageFragment) { super.onBackPressed() - } else if (currentFragment!!.breadcrumbs.getItemCount() <= 1) { + } else if ((currentFragment as ItemsFragment).getBreadcrumbs().getItemCount() <= 1) { if (!wasBackJustPressed && config.pressBackTwice) { wasBackJustPressed = true toast(R.string.press_back_again) @@ -165,8 +163,8 @@ class MainActivity : SimpleActivity() { finish() } } else { - currentFragment.breadcrumbs?.removeBreadcrumb() - openPath(currentFragment.breadcrumbs.getLastItem().path) + currentFragment.getBreadcrumbs().removeBreadcrumb() + openPath(currentFragment.getBreadcrumbs().getLastItem().path) } } @@ -176,7 +174,7 @@ class MainActivity : SimpleActivity() { val currentViewType = config.getFolderViewType(currentFragment.currentPath) val favorites = config.favorites - main_menu.getToolbar().menu.apply { + binding.mainMenu.getToolbar().menu.apply { findItem(R.id.sort).isVisible = currentFragment is ItemsFragment findItem(R.id.change_view_type).isVisible = currentFragment !is StorageFragment @@ -200,49 +198,51 @@ class MainActivity : SimpleActivity() { } private fun setupOptionsMenu() { - main_menu.getToolbar().inflateMenu(R.menu.menu) - main_menu.toggleHideOnScroll(false) - main_menu.setupMenu() + binding.mainMenu.apply { + getToolbar().inflateMenu(R.menu.menu) + toggleHideOnScroll(false) + setupMenu() - main_menu.onSearchClosedListener = { - getAllFragments().forEach { - it?.searchQueryChanged("") + onSearchClosedListener = { + getAllFragments().forEach { + it?.searchQueryChanged("") + } } - } - main_menu.onSearchTextChangedListener = { text -> - getCurrentFragment()?.searchQueryChanged(text) - } + onSearchTextChangedListener = { text -> + getCurrentFragment()?.searchQueryChanged(text) + } - main_menu.getToolbar().setOnMenuItemClickListener { menuItem -> - if (getCurrentFragment() == null) { + getToolbar().setOnMenuItemClickListener { menuItem -> + if (getCurrentFragment() == null) { + return@setOnMenuItemClickListener true + } + + when (menuItem.itemId) { + R.id.go_home -> goHome() + R.id.go_to_favorite -> goToFavorite() + R.id.sort -> showSortingDialog() + R.id.add_favorite -> addFavorite() + R.id.remove_favorite -> removeFavorite() + R.id.toggle_filename -> toggleFilenameVisibility() + R.id.set_as_home -> setAsHome() + R.id.change_view_type -> changeViewType() + R.id.temporarily_show_hidden -> tryToggleTemporarilyShowHidden() + R.id.stop_showing_hidden -> tryToggleTemporarilyShowHidden() + R.id.column_count -> changeColumnCount() + R.id.more_apps_from_us -> launchMoreAppsFromUsIntent() + R.id.settings -> launchSettings() + R.id.about -> launchAbout() + else -> return@setOnMenuItemClickListener false + } return@setOnMenuItemClickListener true } - - when (menuItem.itemId) { - R.id.go_home -> goHome() - R.id.go_to_favorite -> goToFavorite() - R.id.sort -> showSortingDialog() - R.id.add_favorite -> addFavorite() - R.id.remove_favorite -> removeFavorite() - R.id.toggle_filename -> toggleFilenameVisibility() - R.id.set_as_home -> setAsHome() - R.id.change_view_type -> changeViewType() - R.id.temporarily_show_hidden -> tryToggleTemporarilyShowHidden() - R.id.stop_showing_hidden -> tryToggleTemporarilyShowHidden() - R.id.column_count -> changeColumnCount() - R.id.more_apps_from_us -> launchMoreAppsFromUsIntent() - R.id.settings -> launchSettings() - R.id.about -> launchAbout() - else -> return@setOnMenuItemClickListener false - } - return@setOnMenuItemClickListener true } } override fun onSaveInstanceState(outState: Bundle) { super.onSaveInstanceState(outState) - outState.putString(PICKED_PATH, items_fragment?.currentPath ?: "") + outState.putString(PICKED_PATH, getItemsFragment()?.currentPath ?: "") outState.putBoolean(WAS_PROTECTION_HANDLED, mWasProtectionHandled) } @@ -251,8 +251,8 @@ class MainActivity : SimpleActivity() { mWasProtectionHandled = savedInstanceState.getBoolean(WAS_PROTECTION_HANDLED, false) val path = savedInstanceState.getString(PICKED_PATH) ?: internalStoragePath - if (main_view_pager.adapter == null) { - main_view_pager.onGlobalLayout { + if (binding.mainViewPager.adapter == null) { + binding.mainViewPager.onGlobalLayout { restorePath(path) } } else { @@ -287,7 +287,7 @@ class MainActivity : SimpleActivity() { private fun updateMenuColors() { updateStatusbarColor(getProperBackgroundColor()) - main_menu.updateColors() + binding.mainMenu.updateColors() } private fun storeStateVariables() { @@ -304,11 +304,11 @@ class MainActivity : SimpleActivity() { handleStoragePermission { checkOTGPath() if (it) { - if (main_view_pager.adapter == null) { + if (binding.mainViewPager.adapter == null) { initFragments() } - main_view_pager.onGlobalLayout { + binding.mainViewPager.onGlobalLayout { initFileManager(!hadPermission) } } else { @@ -368,41 +368,43 @@ class MainActivity : SimpleActivity() { tryOpenPathIntent(data.path!!, false, finishActivity = true) } - main_view_pager.currentItem = 0 + binding.mainViewPager.currentItem = 0 } else { openPath(config.homeFolder) } if (refreshRecents) { - recents_fragment?.refreshFragment() + getRecentsFragment()?.refreshFragment() } } private fun initFragments() { - main_view_pager.adapter = ViewPagerAdapter(this, mTabsToShow) - main_view_pager.offscreenPageLimit = 2 - main_view_pager.addOnPageChangeListener(object : ViewPager.OnPageChangeListener { - override fun onPageScrollStateChanged(state: Int) {} + binding.mainViewPager.apply { + adapter = ViewPagerAdapter(this@MainActivity, mTabsToShow) + offscreenPageLimit = 2 + addOnPageChangeListener(object : ViewPager.OnPageChangeListener { + override fun onPageScrollStateChanged(state: Int) {} - override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {} + override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {} - override fun onPageSelected(position: Int) { - main_tabs_holder.getTabAt(position)?.select() - getAllFragments().forEach { - (it as? ItemOperationsListener)?.finishActMode() + override fun onPageSelected(position: Int) { + binding.mainTabsHolder.getTabAt(position)?.select() + getAllFragments().forEach { + (it as? ItemOperationsListener)?.finishActMode() + } + refreshMenuItems() } + }) + currentItem = config.lastUsedViewPagerPage + + onGlobalLayout { refreshMenuItems() } - }) - main_view_pager.currentItem = config.lastUsedViewPagerPage - - main_view_pager.onGlobalLayout { - refreshMenuItems() } } private fun setupTabs() { - main_tabs_holder.removeAllTabs() + binding.mainTabsHolder.removeAllTabs() val action = intent.action val isPickFileIntent = action == RingtoneManager.ACTION_RINGTONE_PICKER || action == Intent.ACTION_GET_CONTENT || action == Intent.ACTION_PICK val isCreateDocumentIntent = action == Intent.ACTION_CREATE_DOCUMENT @@ -421,41 +423,45 @@ class MainActivity : SimpleActivity() { mTabsToShow.forEachIndexed { index, value -> if (config.showTabs and value != 0) { - main_tabs_holder.newTab().setCustomView(R.layout.bottom_tablayout_item).apply { + binding.mainTabsHolder.newTab().setCustomView(R.layout.bottom_tablayout_item).apply { customView?.findViewById(R.id.tab_item_icon)?.setImageDrawable(getTabIcon(index)) customView?.findViewById(R.id.tab_item_label)?.text = getTabLabel(index) AutofitHelper.create(customView?.findViewById(R.id.tab_item_label)) - main_tabs_holder.addTab(this) + binding.mainTabsHolder.addTab(this) } } } - main_tabs_holder.onTabSelectionChanged( - tabUnselectedAction = { - updateBottomTabItemColors(it.customView, false, getDeselectedTabDrawableIds()[it.position]) - }, - tabSelectedAction = { - main_menu.closeSearch() - main_view_pager.currentItem = it.position - updateBottomTabItemColors(it.customView, true, getSelectedTabDrawableIds()[it.position]) - } - ) + binding.mainTabsHolder.apply { + onTabSelectionChanged( + tabUnselectedAction = { + updateBottomTabItemColors(it.customView, false, getDeselectedTabDrawableIds()[it.position]) + }, + tabSelectedAction = { + binding.mainMenu.closeSearch() + binding.mainViewPager.currentItem = it.position + updateBottomTabItemColors(it.customView, true, getSelectedTabDrawableIds()[it.position]) + } + ) - main_tabs_holder.beGoneIf(main_tabs_holder.tabCount == 1) + beGoneIf(tabCount == 1) + } } private fun setupTabColors() { - val activeView = main_tabs_holder.getTabAt(main_view_pager.currentItem)?.customView - updateBottomTabItemColors(activeView, true, getSelectedTabDrawableIds()[main_view_pager.currentItem]) + binding.apply { + val activeView = mainTabsHolder.getTabAt(mainViewPager.currentItem)?.customView + updateBottomTabItemColors(activeView, true, getSelectedTabDrawableIds()[mainViewPager.currentItem]) - getInactiveTabIndexes(main_view_pager.currentItem).forEach { index -> - val inactiveView = main_tabs_holder.getTabAt(index)?.customView - updateBottomTabItemColors(inactiveView, false, getDeselectedTabDrawableIds()[index]) + getInactiveTabIndexes(mainViewPager.currentItem).forEach { index -> + val inactiveView = mainTabsHolder.getTabAt(index)?.customView + updateBottomTabItemColors(inactiveView, false, getDeselectedTabDrawableIds()[index]) + } + + val bottomBarColor = getBottomNavigationBackgroundColor() + updateNavigationBarColor(bottomBarColor) + mainTabsHolder.setBackgroundColor(bottomBarColor) } - - val bottomBarColor = getBottomNavigationBackgroundColor() - updateNavigationBarColor(bottomBarColor) - main_tabs_holder.setBackgroundColor(bottomBarColor) } private fun getTabIcon(position: Int): Drawable { @@ -504,7 +510,7 @@ class MainActivity : SimpleActivity() { newPath = internalStoragePath } - items_fragment?.openPath(newPath, forceRefresh) + getItemsFragment()?.openPath(newPath, forceRefresh) } private fun goHome() { @@ -714,12 +720,12 @@ class MainActivity : SimpleActivity() { } fun openedDirectory() { - if (main_menu.isSearchOpen) { - main_menu.closeSearch() + if (binding.mainMenu.isSearchOpen) { + binding.mainMenu.closeSearch() } } - private fun getInactiveTabIndexes(activeIndex: Int) = (0 until main_tabs_holder.tabCount).filter { it != activeIndex } + private fun getInactiveTabIndexes(activeIndex: Int) = (0 until binding.mainTabsHolder.tabCount).filter { it != activeIndex } private fun getSelectedTabDrawableIds(): ArrayList { val showTabs = config.showTabs @@ -759,24 +765,28 @@ class MainActivity : SimpleActivity() { return icons } - private fun getAllFragments(): ArrayList = arrayListOf(items_fragment, recents_fragment, storage_fragment) + private fun getRecentsFragment() = findViewById(R.id.recents_fragment); + private fun getItemsFragment() = findViewById(R.id.items_fragment); + private fun getStorageFragment() = findViewById(R.id.storage_fragment); + private fun getAllFragments(): ArrayList?> = + arrayListOf(getItemsFragment(), getRecentsFragment(), getStorageFragment()) - private fun getCurrentFragment(): MyViewPagerFragment? { + private fun getCurrentFragment(): MyViewPagerFragment<*>? { val showTabs = config.showTabs - val fragments = arrayListOf() + val fragments = arrayListOf>() if (showTabs and TAB_FILES != 0) { - fragments.add(items_fragment) + fragments.add(getItemsFragment()) } if (showTabs and TAB_RECENT_FILES != 0) { - fragments.add(recents_fragment) + fragments.add(getRecentsFragment()) } if (showTabs and TAB_STORAGE_ANALYSIS != 0) { - fragments.add(storage_fragment) + fragments.add(getStorageFragment()) } - return fragments.getOrNull(main_view_pager.currentItem) + return fragments.getOrNull(binding.mainViewPager.currentItem) } private fun getTabsList() = arrayListOf(TAB_FILES, TAB_RECENT_FILES, TAB_STORAGE_ANALYSIS) diff --git a/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/activities/MimeTypesActivity.kt b/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/activities/MimeTypesActivity.kt index a05b60fd..aadb2f5c 100644 --- a/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/activities/MimeTypesActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/activities/MimeTypesActivity.kt @@ -21,6 +21,7 @@ import com.simplemobiletools.commons.views.MyGridLayoutManager import com.simplemobiletools.commons.views.MyRecyclerView import com.simplemobiletools.filemanager.pro.R import com.simplemobiletools.filemanager.pro.adapters.ItemsAdapter +import com.simplemobiletools.filemanager.pro.databinding.ActivityMimetypesBinding import com.simplemobiletools.filemanager.pro.dialogs.ChangeSortingDialog import com.simplemobiletools.filemanager.pro.dialogs.ChangeViewTypeDialog import com.simplemobiletools.filemanager.pro.extensions.config @@ -28,10 +29,10 @@ import com.simplemobiletools.filemanager.pro.extensions.tryOpenPathIntent import com.simplemobiletools.filemanager.pro.helpers.* import com.simplemobiletools.filemanager.pro.interfaces.ItemOperationsListener import com.simplemobiletools.filemanager.pro.models.ListItem -import kotlinx.android.synthetic.main.activity_mimetypes.* import java.util.Locale class MimeTypesActivity : SimpleActivity(), ItemOperationsListener { + private val binding by lazy(LazyThreadSafetyMode.NONE) { ActivityMimetypesBinding.inflate(layoutInflater) } private var isSearchOpen = false private var currentMimeType = "" private var lastSearchedText = "" @@ -43,14 +44,16 @@ class MimeTypesActivity : SimpleActivity(), ItemOperationsListener { override fun onCreate(savedInstanceState: Bundle?) { isMaterialActivity = true super.onCreate(savedInstanceState) - setContentView(R.layout.activity_mimetypes) + setContentView(binding.root) setupOptionsMenu() refreshMenuItems() - updateMaterialActivityViews(mimetypes_coordinator, mimetypes_list, useTransparentNavigation = true, useTopSearchMenu = false) - setupMaterialScrollListener(mimetypes_list, mimetypes_toolbar) + binding.apply { + updateMaterialActivityViews(mimetypesCoordinator, mimetypesList, useTransparentNavigation = true, useTopSearchMenu = false) + setupMaterialScrollListener(mimetypesList, mimetypesToolbar) + } currentMimeType = intent.getStringExtra(SHOW_MIMETYPE) ?: return - mimetypes_toolbar.title = getString( + binding.mimetypesToolbar.title = getString( when (currentMimeType) { IMAGES -> R.string.images VIDEOS -> R.string.videos @@ -70,20 +73,22 @@ class MimeTypesActivity : SimpleActivity(), ItemOperationsListener { reFetchItems() } - mimetypes_fastscroller.updateColors(getProperPrimaryColor()) - mimetypes_placeholder.setTextColor(getProperTextColor()) - mimetypes_placeholder_2.setTextColor(getProperTextColor()) + binding.apply { + mimetypesFastscroller.updateColors(getProperPrimaryColor()) + mimetypesPlaceholder.setTextColor(getProperTextColor()) + mimetypesPlaceholder2.setTextColor(getProperTextColor()) + } } override fun onResume() { super.onResume() - setupToolbar(mimetypes_toolbar, NavigationIcon.Arrow, searchMenuItem = searchMenuItem) + setupToolbar(binding.mimetypesToolbar, NavigationIcon.Arrow, searchMenuItem = searchMenuItem) } private fun refreshMenuItems() { val currentViewType = config.getFolderViewType(currentMimeType) - mimetypes_toolbar.menu.apply { + binding.mimetypesToolbar.menu.apply { findItem(R.id.toggle_filename).isVisible = currentViewType == VIEW_TYPE_GRID findItem(R.id.temporarily_show_hidden).isVisible = !config.shouldShowHidden() @@ -94,8 +99,8 @@ class MimeTypesActivity : SimpleActivity(), ItemOperationsListener { } private fun setupOptionsMenu() { - setupSearch(mimetypes_toolbar.menu) - mimetypes_toolbar.setOnMenuItemClickListener { menuItem -> + setupSearch(binding.mimetypesToolbar.menu) + binding.mimetypesToolbar.setOnMenuItemClickListener { menuItem -> when (menuItem.itemId) { R.id.sort -> showSortingDialog() R.id.toggle_filename -> toggleFilenameVisibility() @@ -130,15 +135,19 @@ class MimeTypesActivity : SimpleActivity(), ItemOperationsListener { lastSearchedText = searchText when { searchText.isEmpty() -> { - mimetypes_fastscroller.beVisible() - getRecyclerAdapter()?.updateItems(storedItems) - mimetypes_placeholder.beGoneIf(storedItems.isNotEmpty()) - mimetypes_placeholder_2.beGone() + binding.apply { + mimetypesFastscroller.beVisible() + getRecyclerAdapter()?.updateItems(storedItems) + mimetypesPlaceholder.beGoneIf(storedItems.isNotEmpty()) + mimetypesPlaceholder2.beGone() + } } searchText.length == 1 -> { - mimetypes_fastscroller.beGone() - mimetypes_placeholder.beVisible() - mimetypes_placeholder_2.beVisible() + binding.apply { + mimetypesFastscroller.beGone() + mimetypesPlaceholder.beVisible() + mimetypesPlaceholder2.beVisible() + } } else -> { ensureBackgroundThread { @@ -150,9 +159,11 @@ class MimeTypesActivity : SimpleActivity(), ItemOperationsListener { runOnUiThread { getRecyclerAdapter()?.updateItems(listItems, text) - mimetypes_fastscroller.beVisibleIf(listItems.isNotEmpty()) - mimetypes_placeholder.beVisibleIf(listItems.isEmpty()) - mimetypes_placeholder_2.beGone() + binding.apply { + mimetypesFastscroller.beVisibleIf(listItems.isNotEmpty()) + mimetypesPlaceholder.beVisibleIf(listItems.isEmpty()) + mimetypesPlaceholder2.beGone() + } } } } @@ -199,7 +210,7 @@ class MimeTypesActivity : SimpleActivity(), ItemOperationsListener { } override fun columnCountChanged() { - (mimetypes_list.layoutManager as MyGridLayoutManager).spanCount = config.fileColumnCnt + (binding.mimetypesList.layoutManager as MyGridLayoutManager).spanCount = config.fileColumnCnt refreshMenuItems() getRecyclerAdapter()?.apply { notifyItemRangeChanged(0, listItems.size) @@ -337,21 +348,21 @@ class MimeTypesActivity : SimpleActivity(), ItemOperationsListener { } storedItems = items - ItemsAdapter(this as SimpleActivity, storedItems, this, mimetypes_list, false, null) { + ItemsAdapter(this as SimpleActivity, storedItems, this, binding.mimetypesList, false, null) { tryOpenPathIntent((it as ListItem).path, false) }.apply { setupZoomListener(zoomListener) - mimetypes_list.adapter = this + binding.mimetypesList.adapter = this } if (areSystemAnimationsEnabled) { - mimetypes_list.scheduleLayoutAnimation() + binding.mimetypesList.scheduleLayoutAnimation() } - mimetypes_placeholder.beVisibleIf(items.isEmpty()) + binding.mimetypesPlaceholder.beVisibleIf(items.isEmpty()) } - private fun getRecyclerAdapter() = mimetypes_list.adapter as? ItemsAdapter + private fun getRecyclerAdapter() = binding.mimetypesList.adapter as? ItemsAdapter private fun showSortingDialog() { ChangeSortingDialog(this, currentMimeType) { @@ -396,13 +407,13 @@ class MimeTypesActivity : SimpleActivity(), ItemOperationsListener { setupListLayoutManager() } - mimetypes_list.adapter = null + binding.mimetypesList.adapter = null initZoomListener() addItems(storedItems) } private fun setupGridLayoutManager() { - val layoutManager = mimetypes_list.layoutManager as MyGridLayoutManager + val layoutManager = binding.mimetypesList.layoutManager as MyGridLayoutManager layoutManager.spanCount = config.fileColumnCnt ?: 3 layoutManager.spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() { @@ -417,14 +428,14 @@ class MimeTypesActivity : SimpleActivity(), ItemOperationsListener { } private fun setupListLayoutManager() { - val layoutManager = mimetypes_list.layoutManager as MyGridLayoutManager + val layoutManager = binding.mimetypesList.layoutManager as MyGridLayoutManager layoutManager.spanCount = 1 zoomListener = null } private fun initZoomListener() { if (config.getFolderViewType(currentMimeType) == VIEW_TYPE_GRID) { - val layoutManager = mimetypes_list.layoutManager as MyGridLayoutManager + val layoutManager = binding.mimetypesList.layoutManager as MyGridLayoutManager zoomListener = object : MyRecyclerView.MyZoomListener { override fun zoomIn() { if (layoutManager.spanCount > 1) { diff --git a/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/activities/PDFViewerActivity.kt b/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/activities/PDFViewerActivity.kt index 7fa0f894..53c75398 100644 --- a/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/activities/PDFViewerActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/activities/PDFViewerActivity.kt @@ -16,15 +16,13 @@ import com.simplemobiletools.commons.extensions.* import com.simplemobiletools.commons.helpers.REAL_FILE_PATH import com.simplemobiletools.commons.helpers.isPiePlus import com.simplemobiletools.filemanager.pro.R +import com.simplemobiletools.filemanager.pro.databinding.ActivityPdfViewerBinding import com.simplemobiletools.filemanager.pro.extensions.hideSystemUI import com.simplemobiletools.filemanager.pro.extensions.showSystemUI import com.simplemobiletools.filemanager.pro.helpers.PdfDocumentAdapter -import kotlinx.android.synthetic.main.activity_pdf_viewer.pdf_viewer -import kotlinx.android.synthetic.main.activity_pdf_viewer.pdf_viewer_appbar -import kotlinx.android.synthetic.main.activity_pdf_viewer.pdf_viewer_toolbar -import kotlinx.android.synthetic.main.activity_pdf_viewer.top_shadow class PDFViewerActivity : SimpleActivity() { + private val binding by lazy(LazyThreadSafetyMode.NONE) { ActivityPdfViewerBinding.inflate(layoutInflater) } private var realFilePath = "" private var isFullScreen = false private var passwordDialog: EnterPasswordDialog? = null @@ -33,14 +31,14 @@ class PDFViewerActivity : SimpleActivity() { showTransparentTop = true super.onCreate(savedInstanceState) - setContentView(R.layout.activity_pdf_viewer) + setContentView(binding.root) if (checkAppSideloading()) { return } checkNotchSupport() - pdf_viewer_toolbar.apply { + binding.pdfViewerToolbar.apply { setTitleTextColor(Color.WHITE) overflowIcon = resources.getColoredDrawableWithColor(R.drawable.ic_three_dots_vector, Color.WHITE) navigationIcon = resources.getColoredDrawableWithColor(R.drawable.ic_arrow_left_vector, Color.WHITE) @@ -48,7 +46,7 @@ class PDFViewerActivity : SimpleActivity() { if (intent.extras?.containsKey(REAL_FILE_PATH) == true) { realFilePath = intent.extras?.get(REAL_FILE_PATH)?.toString() ?: "" - pdf_viewer_toolbar.title = realFilePath.getFilenameFromPath() + binding.pdfViewerToolbar.title = realFilePath.getFilenameFromPath() } setupMenu() @@ -61,8 +59,8 @@ class PDFViewerActivity : SimpleActivity() { } private fun setupMenu() { - (pdf_viewer_appbar.layoutParams as RelativeLayout.LayoutParams).topMargin = statusBarHeight - pdf_viewer_toolbar.menu.apply { + (binding.pdfViewerAppbar.layoutParams as RelativeLayout.LayoutParams).topMargin = statusBarHeight + binding.pdfViewerToolbar.menu.apply { findItem(R.id.menu_print).isVisible = realFilePath.isNotEmpty() findItem(R.id.menu_print).setOnMenuItemClickListener { printText() @@ -70,24 +68,24 @@ class PDFViewerActivity : SimpleActivity() { } } - pdf_viewer_toolbar.setNavigationOnClickListener { + binding.pdfViewerToolbar.setNavigationOnClickListener { finish() } if (!portrait && navigationBarOnSide && navigationBarWidth > 0) { - pdf_viewer_appbar.setPadding(0, 0, navigationBarWidth, 0) + binding.pdfViewerAppbar.setPadding(0, 0, navigationBarWidth, 0) } else { - pdf_viewer_appbar.setPadding(0, 0, 0, 0) + binding.pdfViewerAppbar.setPadding(0, 0, 0, 0) } } override fun onConfigurationChanged(newConfig: Configuration) { super.onConfigurationChanged(newConfig) - (pdf_viewer_appbar.layoutParams as RelativeLayout.LayoutParams).topMargin = statusBarHeight + (binding.pdfViewerAppbar.layoutParams as RelativeLayout.LayoutParams).topMargin = statusBarHeight if (!portrait && navigationBarOnSide && navigationBarWidth > 0) { - pdf_viewer_appbar.setPadding(0, 0, navigationBarWidth, 0) + binding.pdfViewerAppbar.setPadding(0, 0, navigationBarWidth, 0) } else { - pdf_viewer_appbar.setPadding(0, 0, 0, 0) + binding.pdfViewerAppbar.setPadding(0, 0, 0, 0) } } @@ -103,8 +101,8 @@ class PDFViewerActivity : SimpleActivity() { private fun loadPdfViewer(uri: Uri, filePassword: String? = null) { val primaryColor = getProperPrimaryColor() - pdf_viewer.setBackgroundColor(getProperBackgroundColor()) - pdf_viewer.fromUri(uri) + binding.pdfViewer.setBackgroundColor(getProperBackgroundColor()) + binding.pdfViewer.fromUri(uri) .password(filePassword) .scrollHandle(DefaultScrollHandle(this, primaryColor.getContrastColor(), primaryColor)) .spacing(15) @@ -140,7 +138,7 @@ class PDFViewerActivity : SimpleActivity() { val filename = getFilenameFromUri(uri) if (filename.isNotEmpty()) { - pdf_viewer_toolbar.title = filename + binding.pdfViewerToolbar.title = filename } } @@ -163,14 +161,14 @@ class PDFViewerActivity : SimpleActivity() { showSystemUI(true) } - top_shadow.animate().alpha(newAlpha).start() - pdf_viewer_appbar.animate().alpha(newAlpha).withStartAction { + binding.topShadow.animate().alpha(newAlpha).start() + binding.pdfViewerAppbar.animate().alpha(newAlpha).withStartAction { if (newAlpha == 1f) { - pdf_viewer_appbar.beVisible() + binding.pdfViewerAppbar.beVisible() } }.withEndAction { if (newAlpha == 0f) { - pdf_viewer_appbar.beGone() + binding.pdfViewerAppbar.beGone() } }.start() diff --git a/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/activities/ReadTextActivity.kt b/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/activities/ReadTextActivity.kt index 8f511b44..04085aba 100644 --- a/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/activities/ReadTextActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/activities/ReadTextActivity.kt @@ -21,17 +21,17 @@ import com.simplemobiletools.commons.helpers.SAVE_DISCARD_PROMPT_INTERVAL import com.simplemobiletools.commons.helpers.ensureBackgroundThread import com.simplemobiletools.commons.views.MyEditText import com.simplemobiletools.filemanager.pro.R +import com.simplemobiletools.filemanager.pro.databinding.ActivityReadTextBinding import com.simplemobiletools.filemanager.pro.dialogs.SaveAsDialog -import com.simplemobiletools.filemanager.pro.extensions.config import com.simplemobiletools.filemanager.pro.extensions.openPath import com.simplemobiletools.filemanager.pro.views.GestureEditText -import kotlinx.android.synthetic.main.activity_read_text.* import java.io.File import java.io.OutputStream class ReadTextActivity : SimpleActivity() { private val SELECT_SAVE_FILE_INTENT = 1 private val SELECT_SAVE_FILE_AND_EXIT_INTENT = 2 + private val binding by lazy(LazyThreadSafetyMode.NONE) { ActivityReadTextBinding.inflate(layoutInflater) } private var filePath = "" private var originalText = "" @@ -48,10 +48,12 @@ class ReadTextActivity : SimpleActivity() { override fun onCreate(savedInstanceState: Bundle?) { isMaterialActivity = true super.onCreate(savedInstanceState) - setContentView(R.layout.activity_read_text) + setContentView(binding.root) setupOptionsMenu() - updateMaterialActivityViews(read_text_coordinator, read_text_view, useTransparentNavigation = true, useTopSearchMenu = false) - setupMaterialScrollListener(read_text_holder, read_text_toolbar) + binding.apply { + updateMaterialActivityViews(readTextCoordinator, readTextView, useTransparentNavigation = true, useTopSearchMenu = false) + setupMaterialScrollListener(readTextHolder, readTextToolbar) + } searchQueryET = findViewById(R.id.search_query) searchPrevBtn = findViewById(R.id.search_previous) @@ -75,10 +77,10 @@ class ReadTextActivity : SimpleActivity() { val filename = getFilenameFromUri(uri) if (filename.isNotEmpty()) { - read_text_toolbar.title = Uri.decode(filename) + binding.readTextToolbar.title = Uri.decode(filename) } - read_text_view.onGlobalLayout { + binding.readTextView.onGlobalLayout { ensureBackgroundThread { checkIntent(uri) } @@ -89,7 +91,7 @@ class ReadTextActivity : SimpleActivity() { override fun onResume() { super.onResume() - setupToolbar(read_text_toolbar, NavigationIcon.Arrow) + setupToolbar(binding.readTextToolbar, NavigationIcon.Arrow) } override fun onActivityResult(requestCode: Int, resultCode: Int, resultData: Intent?) { @@ -107,7 +109,7 @@ class ReadTextActivity : SimpleActivity() { } override fun onBackPressed() { - val hasUnsavedChanges = originalText != read_text_view.text.toString() + val hasUnsavedChanges = originalText != binding.readTextView.text.toString() when { isSearchActive -> closeSearch() hasUnsavedChanges && System.currentTimeMillis() - lastSavePromptTS > SAVE_DISCARD_PROMPT_INTERVAL -> { @@ -125,7 +127,7 @@ class ReadTextActivity : SimpleActivity() { } private fun setupOptionsMenu() { - read_text_toolbar.setOnMenuItemClickListener { menuItem -> + binding.readTextToolbar.setOnMenuItemClickListener { menuItem -> when (menuItem.itemId) { R.id.menu_search -> openSearch() R.id.menu_save -> saveText() @@ -139,11 +141,11 @@ class ReadTextActivity : SimpleActivity() { private fun openSearch() { isSearchActive = true - search_wrapper.beVisible() + binding.searchWrapper.beVisible() showKeyboard(searchQueryET) - read_text_view.requestFocus() - read_text_view.setSelection(0) + binding.readTextView.requestFocus() + binding.readTextView.setSelection(0) searchQueryET.postDelayed({ searchQueryET.requestFocus() @@ -187,7 +189,7 @@ class ReadTextActivity : SimpleActivity() { private fun saveTextContent(outputStream: OutputStream?, shouldExitAfterSaving: Boolean, shouldOverwriteOriginalText: Boolean) { if (outputStream != null) { - val currentText = read_text_view.text.toString() + val currentText = binding.readTextView.text.toString() outputStream.bufferedWriter().use { it.write(currentText) } toast(R.string.file_saved) hideKeyboard() @@ -215,7 +217,7 @@ class ReadTextActivity : SimpleActivity() { } } - webView.loadData(read_text_view.text.toString(), "text/plain", "UTF-8") + webView.loadData(binding.readTextView.text.toString(), "text/plain", "UTF-8") } catch (e: Exception) { showErrorToast(e) } @@ -264,11 +266,11 @@ class ReadTextActivity : SimpleActivity() { } runOnUiThread { - read_text_view.setText(originalText) + binding.readTextView.setText(originalText) if (originalText.isNotEmpty()) { hideKeyboard() } else { - showKeyboard(read_text_view) + showKeyboard(binding.readTextView) } } } @@ -299,7 +301,7 @@ class ReadTextActivity : SimpleActivity() { false }) - search_wrapper.setBackgroundColor(getProperPrimaryColor()) + binding.searchWrapper.setBackgroundColor(getProperPrimaryColor()) val contrastColor = getProperPrimaryColor().getContrastColor() arrayListOf(searchPrevBtn, searchNextBtn, searchClearBtn).forEach { it.applyColorFilter(contrastColor) @@ -307,16 +309,16 @@ class ReadTextActivity : SimpleActivity() { } private fun searchTextChanged(text: String) { - read_text_view.text?.clearBackgroundSpans() + binding.readTextView.text?.clearBackgroundSpans() if (text.isNotBlank() && text.length > 1) { - searchMatches = read_text_view.value.searchMatches(text) - read_text_view.highlightText(text, getProperPrimaryColor()) + searchMatches = binding.readTextView.value.searchMatches(text) + binding.readTextView.highlightText(text, getProperPrimaryColor()) } if (searchMatches.isNotEmpty()) { - read_text_view.requestFocus() - read_text_view.setSelection(searchMatches.getOrNull(searchIndex) ?: 0) + binding.readTextView.requestFocus() + binding.readTextView.setSelection(searchMatches.getOrNull(searchIndex) ?: 0) } searchQueryET.postDelayed({ @@ -331,7 +333,7 @@ class ReadTextActivity : SimpleActivity() { searchIndex = searchMatches.lastIndex } - selectSearchMatch(read_text_view) + selectSearchMatch(binding.readTextView) } private fun goToNextSearchResult() { @@ -341,13 +343,13 @@ class ReadTextActivity : SimpleActivity() { searchIndex = 0 } - selectSearchMatch(read_text_view) + selectSearchMatch(binding.readTextView) } private fun closeSearch() { searchQueryET.text?.clear() isSearchActive = false - search_wrapper.beGone() + binding.searchWrapper.beGone() hideKeyboard() } diff --git a/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/activities/SaveAsActivity.kt b/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/activities/SaveAsActivity.kt index 44d53f1e..73d10323 100644 --- a/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/activities/SaveAsActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/activities/SaveAsActivity.kt @@ -8,14 +8,16 @@ import com.simplemobiletools.commons.extensions.* import com.simplemobiletools.commons.helpers.NavigationIcon import com.simplemobiletools.commons.helpers.ensureBackgroundThread import com.simplemobiletools.filemanager.pro.R +import com.simplemobiletools.filemanager.pro.databinding.ActivitySaveAsBinding import com.simplemobiletools.filemanager.pro.extensions.config -import kotlinx.android.synthetic.main.activity_save_as.activity_save_as_toolbar import java.io.File class SaveAsActivity : SimpleActivity() { + private val binding by lazy(LazyThreadSafetyMode.NONE) { ActivitySaveAsBinding.inflate(layoutInflater) } + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - setContentView(R.layout.activity_save_as) + setContentView(binding.root) if (intent.action == Intent.ACTION_SEND && intent.extras?.containsKey(Intent.EXTRA_STREAM) == true) { FilePickerDialog(this, pickFile = false, showHidden = config.shouldShowHidden(), showFAB = true, showFavoritesButton = true) { @@ -59,6 +61,6 @@ class SaveAsActivity : SimpleActivity() { override fun onResume() { super.onResume() - setupToolbar(activity_save_as_toolbar, NavigationIcon.Arrow) + setupToolbar(binding.activitySaveAsToolbar, NavigationIcon.Arrow) } } diff --git a/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/activities/SettingsActivity.kt b/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/activities/SettingsActivity.kt index 64f6bcde..afadbd3b 100644 --- a/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/activities/SettingsActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/activities/SettingsActivity.kt @@ -10,26 +10,29 @@ import com.simplemobiletools.commons.extensions.* import com.simplemobiletools.commons.helpers.* import com.simplemobiletools.commons.models.RadioItem import com.simplemobiletools.filemanager.pro.R +import com.simplemobiletools.filemanager.pro.databinding.ActivitySettingsBinding import com.simplemobiletools.filemanager.pro.dialogs.ManageVisibleTabsDialog import com.simplemobiletools.filemanager.pro.extensions.config import com.simplemobiletools.filemanager.pro.helpers.RootHelpers -import kotlinx.android.synthetic.main.activity_settings.* -import java.util.* +import java.util.Locale import kotlin.system.exitProcess class SettingsActivity : SimpleActivity() { + private val binding by lazy(LazyThreadSafetyMode.NONE) { ActivitySettingsBinding.inflate(layoutInflater) } override fun onCreate(savedInstanceState: Bundle?) { isMaterialActivity = true super.onCreate(savedInstanceState) - setContentView(R.layout.activity_settings) - updateMaterialActivityViews(settings_coordinator, settings_holder, useTransparentNavigation = true, useTopSearchMenu = false) - setupMaterialScrollListener(settings_nested_scrollview, settings_toolbar) + setContentView(binding.root) + binding.apply { + updateMaterialActivityViews(settingsCoordinator, settingsHolder, useTransparentNavigation = true, useTopSearchMenu = false) + setupMaterialScrollListener(settingsNestedScrollview, settingsToolbar) + } } override fun onResume() { super.onResume() - setupToolbar(settings_toolbar, NavigationIcon.Arrow) + setupToolbar(binding.settingsToolbar, NavigationIcon.Arrow) setupCustomizeColors() setupUseEnglish() @@ -47,65 +50,71 @@ class SettingsActivity : SimpleActivity() { setupKeepLastModified() setupDeleteConfirmation() setupEnableRootAccess() - updateTextColors(settings_nested_scrollview) + updateTextColors(binding.settingsNestedScrollview) - arrayOf( - settings_color_customization_section_label, - settings_general_settings_label, - settings_visibility_label, - settings_scrolling_label, - settings_file_operations_label, - settings_security_label - ).forEach { - it.setTextColor(getProperPrimaryColor()) + binding.apply { + arrayOf( + settingsColorCustomizationSectionLabel, + settingsGeneralSettingsLabel, + settingsVisibilityLabel, + settingsScrollingLabel, + settingsFileOperationsLabel, + settingsSecurityLabel + ).forEach { + it.setTextColor(getProperPrimaryColor()) + } } } private fun setupCustomizeColors() { - settings_color_customization_holder.setOnClickListener { + binding.settingsColorCustomizationHolder.setOnClickListener { startCustomizationActivity() } } private fun setupUseEnglish() { - settings_use_english_holder.beVisibleIf((config.wasUseEnglishToggled || Locale.getDefault().language != "en") && !isTiramisuPlus()) - settings_use_english.isChecked = config.useEnglish - settings_use_english_holder.setOnClickListener { - settings_use_english.toggle() - config.useEnglish = settings_use_english.isChecked - exitProcess(0) + binding.apply { + settingsUseEnglishHolder.beVisibleIf((config.wasUseEnglishToggled || Locale.getDefault().language != "en") && !isTiramisuPlus()) + settingsUseEnglish.isChecked = config.useEnglish + settingsUseEnglishHolder.setOnClickListener { + settingsUseEnglish.toggle() + config.useEnglish = settingsUseEnglish.isChecked + exitProcess(0) + } } } private fun setupLanguage() { - settings_language.text = Locale.getDefault().displayLanguage - settings_language_holder.beVisibleIf(isTiramisuPlus()) - settings_language_holder.setOnClickListener { - launchChangeAppLanguageIntent() + binding.apply { + settingsLanguage.text = Locale.getDefault().displayLanguage + settingsLanguageHolder.beVisibleIf(isTiramisuPlus()) + settingsLanguageHolder.setOnClickListener { + launchChangeAppLanguageIntent() + } } } private fun setupManageFavorites() { - settings_manage_favorites_holder.setOnClickListener { + binding.settingsManageFavoritesHolder.setOnClickListener { startActivity(Intent(this, FavoritesActivity::class.java)) } } private fun setupManageShownTabs() { - settings_manage_tabs_holder.setOnClickListener { + binding.settingsManageTabsHolder.setOnClickListener { ManageVisibleTabsDialog(this) } } private fun setupChangeDateTimeFormat() { - settings_change_date_time_format_holder.setOnClickListener { + binding.settingsChangeDateTimeFormatHolder.setOnClickListener { ChangeDateTimeFormatDialog(this) {} } } private fun setupFontSize() { - settings_font_size.text = getFontSizeText() - settings_font_size_holder.setOnClickListener { + binding.settingsFontSize.text = getFontSizeText() + binding.settingsFontSizeHolder.setOnClickListener { val items = arrayListOf( RadioItem(FONT_SIZE_SMALL, getString(R.string.small)), RadioItem(FONT_SIZE_MEDIUM, getString(R.string.medium)), @@ -115,14 +124,14 @@ class SettingsActivity : SimpleActivity() { RadioGroupDialog(this@SettingsActivity, items, config.fontSize) { config.fontSize = it as Int - settings_font_size.text = getFontSizeText() + binding.settingsFontSize.text = getFontSizeText() } } } private fun setupShowHidden() { - settings_show_hidden.isChecked = config.showHidden - settings_show_hidden_holder.setOnClickListener { + binding.settingsShowHidden.isChecked = config.showHidden + binding.settingsShowHiddenHolder.setOnClickListener { if (config.showHidden) { toggleShowHidden() } else { @@ -134,34 +143,38 @@ class SettingsActivity : SimpleActivity() { } private fun toggleShowHidden() { - settings_show_hidden.toggle() - config.showHidden = settings_show_hidden.isChecked + binding.settingsShowHidden.toggle() + config.showHidden = binding.settingsShowHidden.isChecked } private fun setupEnablePullToRefresh() { - settings_enable_pull_to_refresh.isChecked = config.enablePullToRefresh - settings_enable_pull_to_refresh_holder.setOnClickListener { - settings_enable_pull_to_refresh.toggle() - config.enablePullToRefresh = settings_enable_pull_to_refresh.isChecked + binding.apply { + settingsEnablePullToRefresh.isChecked = config.enablePullToRefresh + settingsEnablePullToRefreshHolder.setOnClickListener { + settingsEnablePullToRefresh.toggle() + config.enablePullToRefresh = settingsEnablePullToRefresh.isChecked + } } } private fun setupPressBackTwice() { - settings_press_back_twice.isChecked = config.pressBackTwice - settings_press_back_twice_holder.setOnClickListener { - settings_press_back_twice.toggle() - config.pressBackTwice = settings_press_back_twice.isChecked + binding.apply { + settingsPressBackTwice.isChecked = config.pressBackTwice + settingsPressBackTwiceHolder.setOnClickListener { + settingsPressBackTwice.toggle() + config.pressBackTwice = settingsPressBackTwice.isChecked + } } } private fun setupHiddenItemPasswordProtection() { - settings_password_protection.isChecked = config.isHiddenPasswordProtectionOn - settings_password_protection_holder.setOnClickListener { + binding.settingsPasswordProtection.isChecked = config.isHiddenPasswordProtectionOn + binding.settingsPasswordProtectionHolder.setOnClickListener { val tabToShow = if (config.isHiddenPasswordProtectionOn) config.hiddenProtectionType else SHOW_ALL_TABS SecurityDialog(this, config.hiddenPasswordHash, tabToShow) { hash, type, success -> if (success) { val hasPasswordProtection = config.isHiddenPasswordProtectionOn - settings_password_protection.isChecked = !hasPasswordProtection + binding.settingsPasswordProtection.isChecked = !hasPasswordProtection config.isHiddenPasswordProtectionOn = !hasPasswordProtection config.hiddenPasswordHash = if (hasPasswordProtection) "" else hash config.hiddenProtectionType = type @@ -177,13 +190,13 @@ class SettingsActivity : SimpleActivity() { } private fun setupAppPasswordProtection() { - settings_app_password_protection.isChecked = config.isAppPasswordProtectionOn - settings_app_password_protection_holder.setOnClickListener { + binding.settingsAppPasswordProtection.isChecked = config.isAppPasswordProtectionOn + binding.settingsAppPasswordProtectionHolder.setOnClickListener { val tabToShow = if (config.isAppPasswordProtectionOn) config.appProtectionType else SHOW_ALL_TABS SecurityDialog(this, config.appPasswordHash, tabToShow) { hash, type, success -> if (success) { val hasPasswordProtection = config.isAppPasswordProtectionOn - settings_app_password_protection.isChecked = !hasPasswordProtection + binding.settingsAppPasswordProtection.isChecked = !hasPasswordProtection config.isAppPasswordProtectionOn = !hasPasswordProtection config.appPasswordHash = if (hasPasswordProtection) "" else hash config.appProtectionType = type @@ -199,13 +212,13 @@ class SettingsActivity : SimpleActivity() { } private fun setupFileDeletionPasswordProtection() { - settings_file_deletion_password_protection.isChecked = config.isDeletePasswordProtectionOn - settings_file_deletion_password_protection_holder.setOnClickListener { + binding.settingsFileDeletionPasswordProtection.isChecked = config.isDeletePasswordProtectionOn + binding.settingsFileDeletionPasswordProtectionHolder.setOnClickListener { val tabToShow = if (config.isDeletePasswordProtectionOn) config.deleteProtectionType else SHOW_ALL_TABS SecurityDialog(this, config.deletePasswordHash, tabToShow) { hash, type, success -> if (success) { val hasPasswordProtection = config.isDeletePasswordProtectionOn - settings_file_deletion_password_protection.isChecked = !hasPasswordProtection + binding.settingsFileDeletionPasswordProtection.isChecked = !hasPasswordProtection config.isDeletePasswordProtectionOn = !hasPasswordProtection config.deletePasswordHash = if (hasPasswordProtection) "" else hash config.deleteProtectionType = type @@ -221,37 +234,43 @@ class SettingsActivity : SimpleActivity() { } private fun setupKeepLastModified() { - settings_keep_last_modified.isChecked = config.keepLastModified - settings_keep_last_modified_holder.setOnClickListener { - settings_keep_last_modified.toggle() - config.keepLastModified = settings_keep_last_modified.isChecked + binding.apply { + settingsKeepLastModified.isChecked = config.keepLastModified + settingsKeepLastModifiedHolder.setOnClickListener { + settingsKeepLastModified.toggle() + config.keepLastModified = settingsKeepLastModified.isChecked + } } } private fun setupDeleteConfirmation() { - settings_skip_delete_confirmation.isChecked = config.skipDeleteConfirmation - settings_skip_delete_confirmation_holder.setOnClickListener { - settings_skip_delete_confirmation.toggle() - config.skipDeleteConfirmation = settings_skip_delete_confirmation.isChecked + binding.apply { + settingsSkipDeleteConfirmation.isChecked = config.skipDeleteConfirmation + settingsSkipDeleteConfirmationHolder.setOnClickListener { + settingsSkipDeleteConfirmation.toggle() + config.skipDeleteConfirmation = settingsSkipDeleteConfirmation.isChecked + } } } private fun setupEnableRootAccess() { - settings_enable_root_access_holder.beVisibleIf(config.isRootAvailable) - settings_enable_root_access.isChecked = config.enableRootAccess - settings_enable_root_access_holder.setOnClickListener { - if (!config.enableRootAccess) { - RootHelpers(this).askRootIfNeeded { - toggleRootAccess(it) + binding.apply { + settingsEnableRootAccessHolder.beVisibleIf(config.isRootAvailable) + settingsEnableRootAccess.isChecked = config.enableRootAccess + settingsEnableRootAccessHolder.setOnClickListener { + if (!config.enableRootAccess) { + RootHelpers(this@SettingsActivity).askRootIfNeeded { + toggleRootAccess(it) + } + } else { + toggleRootAccess(false) } - } else { - toggleRootAccess(false) } } } private fun toggleRootAccess(enable: Boolean) { - settings_enable_root_access.isChecked = enable + binding.settingsEnableRootAccess.isChecked = enable config.enableRootAccess = enable } } diff --git a/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/adapters/DecompressItemsAdapter.kt b/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/adapters/DecompressItemsAdapter.kt index abc7a9a9..53ac45cc 100644 --- a/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/adapters/DecompressItemsAdapter.kt +++ b/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/adapters/DecompressItemsAdapter.kt @@ -18,10 +18,9 @@ import com.simplemobiletools.commons.helpers.getFilePlaceholderDrawables import com.simplemobiletools.commons.views.MyRecyclerView import com.simplemobiletools.filemanager.pro.R import com.simplemobiletools.filemanager.pro.activities.SimpleActivity +import com.simplemobiletools.filemanager.pro.databinding.ItemDecompressionListFileDirBinding import com.simplemobiletools.filemanager.pro.extensions.config import com.simplemobiletools.filemanager.pro.models.ListItem -import kotlinx.android.synthetic.main.item_file_dir_list.view.* -import java.util.* class DecompressItemsAdapter(activity: SimpleActivity, var listItems: MutableList, recyclerView: MyRecyclerView, itemClick: (Any) -> Unit) : MyRecyclerViewAdapter(activity, recyclerView, itemClick) { @@ -60,7 +59,9 @@ class DecompressItemsAdapter(activity: SimpleActivity, var listItems: MutableLis override fun onActionModeDestroyed() {} - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = createViewHolder(R.layout.item_decompression_list_file_dir, parent) + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { + return createViewHolder(ItemDecompressionListFileDirBinding.inflate(layoutInflater, parent, false).root) + } override fun onBindViewHolder(holder: MyRecyclerViewAdapter.ViewHolder, position: Int) { val fileDirItem = listItems[position] @@ -75,22 +76,23 @@ class DecompressItemsAdapter(activity: SimpleActivity, var listItems: MutableLis override fun onViewRecycled(holder: ViewHolder) { super.onViewRecycled(holder) if (!activity.isDestroyed && !activity.isFinishing) { - val icon = holder.itemView.item_icon - if (icon != null) { - Glide.with(activity).clear(icon) + ItemDecompressionListFileDirBinding.bind(holder.itemView).apply { + if (itemIcon != null) { + Glide.with(activity).clear(itemIcon) + } } } } private fun setupView(view: View, listItem: ListItem) { - view.apply { + ItemDecompressionListFileDirBinding.bind(view).apply { val fileName = listItem.name - item_name.text = fileName - item_name.setTextColor(textColor) - item_name.setTextSize(TypedValue.COMPLEX_UNIT_PX, fontSize) + itemName.text = fileName + itemName.setTextColor(textColor) + itemName.setTextSize(TypedValue.COMPLEX_UNIT_PX, fontSize) if (listItem.isDirectory) { - item_icon.setImageDrawable(folderDrawable) + itemIcon.setImageDrawable(folderDrawable) } else { val drawable = fileDrawables.getOrElse(fileName.substringAfterLast(".").toLowerCase(), { fileDrawable }) val options = RequestOptions() @@ -105,7 +107,7 @@ class DecompressItemsAdapter(activity: SimpleActivity, var listItems: MutableLis .load(itemToLoad) .transition(DrawableTransitionOptions.withCrossFade()) .apply(options) - .into(item_icon) + .into(itemIcon) } } } diff --git a/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/adapters/ItemsAdapter.kt b/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/adapters/ItemsAdapter.kt index 440efb08..0c0932e1 100644 --- a/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/adapters/ItemsAdapter.kt +++ b/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/adapters/ItemsAdapter.kt @@ -10,10 +10,15 @@ import android.graphics.drawable.Icon import android.graphics.drawable.LayerDrawable import android.net.Uri import android.util.TypedValue +import android.view.LayoutInflater import android.view.Menu import android.view.View import android.view.ViewGroup +import android.widget.FrameLayout +import android.widget.ImageView +import android.widget.TextView import androidx.swiperefreshlayout.widget.SwipeRefreshLayout +import androidx.viewbinding.ViewBinding import com.bumptech.glide.Glide import com.bumptech.glide.load.DecodeFormat import com.bumptech.glide.load.engine.DiskCacheStrategy @@ -32,18 +37,13 @@ import com.simplemobiletools.commons.views.MyRecyclerView import com.simplemobiletools.filemanager.pro.R import com.simplemobiletools.filemanager.pro.activities.SimpleActivity import com.simplemobiletools.filemanager.pro.activities.SplashActivity +import com.simplemobiletools.filemanager.pro.databinding.* import com.simplemobiletools.filemanager.pro.dialogs.CompressAsDialog import com.simplemobiletools.filemanager.pro.extensions.* import com.simplemobiletools.filemanager.pro.helpers.* import com.simplemobiletools.filemanager.pro.interfaces.ItemOperationsListener import com.simplemobiletools.filemanager.pro.models.ListItem import com.stericson.RootTools.RootTools -import kotlinx.android.synthetic.main.item_file_dir_list.view.* -import kotlinx.android.synthetic.main.item_file_dir_list.view.item_frame -import kotlinx.android.synthetic.main.item_file_dir_list.view.item_icon -import kotlinx.android.synthetic.main.item_file_dir_list.view.item_name -import kotlinx.android.synthetic.main.item_file_grid.view.* -import kotlinx.android.synthetic.main.item_section.view.* import net.lingala.zip4j.exception.ZipException import net.lingala.zip4j.io.inputstream.ZipInputStream import net.lingala.zip4j.io.outputstream.ZipOutputStream @@ -60,10 +60,6 @@ class ItemsAdapter( val isPickMultipleIntent: Boolean, val swipeRefreshLayout: SwipeRefreshLayout?, canHaveIndividualViewType: Boolean = true, itemClick: (Any) -> Unit ) : MyRecyclerViewAdapter(activity, recyclerView, itemClick), RecyclerViewFastScroller.OnPopupTextUpdate { - private val TYPE_FILE = 1 - private val TYPE_DIR = 2 - private val TYPE_SECTION = 3 - private val TYPE_GRID_TYPE_DIVIDER = 4 private lateinit var fileDrawable: Drawable private lateinit var folderDrawable: Drawable private var fileDrawables = HashMap() @@ -84,6 +80,13 @@ class ItemsAdapter( private val isListViewType = viewType == VIEW_TYPE_LIST private var displayFilenamesInGrid = config.displayFilenames + companion object { + private const val TYPE_FILE = 1 + private const val TYPE_DIR = 2 + private const val TYPE_SECTION = 3 + private const val TYPE_GRID_TYPE_DIVIDER = 4 + } + init { setupDragListener(true) initDrawables() @@ -161,28 +164,16 @@ class ItemsAdapter( } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { - val layout = if (viewType == TYPE_SECTION) { - R.layout.item_section - } else if (viewType == TYPE_GRID_TYPE_DIVIDER) { - R.layout.item_empty - } else { - if (isListViewType) { - R.layout.item_file_dir_list - } else { - if (viewType == TYPE_DIR) { - R.layout.item_dir_grid - } else { - R.layout.item_file_grid - } - } - } - return createViewHolder(layout, parent) + val binding = Binding.getByItemViewType(viewType, isListViewType).inflate(layoutInflater, parent, false) + + return createViewHolder(binding.root) } override fun onBindViewHolder(holder: MyRecyclerViewAdapter.ViewHolder, position: Int) { val fileDirItem = listItems[position] holder.bindView(fileDirItem, true, !fileDirItem.isSectionTitle) { itemView, layoutPosition -> - setupView(itemView, fileDirItem) + val viewType = getItemViewType(position) + setupView(Binding.getByItemViewType(viewType, isListViewType).bind(itemView), fileDirItem) } bindViewHolder(holder) } @@ -831,55 +822,55 @@ class ItemsAdapter( override fun onViewRecycled(holder: ViewHolder) { super.onViewRecycled(holder) if (!activity.isDestroyed && !activity.isFinishing) { - val icon = holder.itemView.item_icon + val icon = Binding.getByItemViewType(holder.itemViewType, isListViewType).bind(holder.itemView).itemIcon if (icon != null) { Glide.with(activity).clear(icon) } } } - private fun setupView(view: View, listItem: ListItem) { + private fun setupView(binding: ItemViewBinding, listItem: ListItem) { val isSelected = selectedKeys.contains(listItem.path.hashCode()) - view.apply { + binding.apply { if (listItem.isSectionTitle) { - item_icon.setImageDrawable(folderDrawable) - item_section.text = if (textToHighlight.isEmpty()) listItem.mName else listItem.mName.highlightTextPart(textToHighlight, properPrimaryColor) - item_section.setTextColor(textColor) - item_section.setTextSize(TypedValue.COMPLEX_UNIT_PX, fontSize) + itemIcon?.setImageDrawable(folderDrawable) + itemSection?.text = if (textToHighlight.isEmpty()) listItem.mName else listItem.mName.highlightTextPart(textToHighlight, properPrimaryColor) + itemSection?.setTextColor(textColor) + itemSection?.setTextSize(TypedValue.COMPLEX_UNIT_PX, fontSize) } else if (!listItem.isGridTypeDivider) { - setupViewBackground(activity) - item_frame.isSelected = isSelected + root.setupViewBackground(activity) + itemFrame.isSelected = isSelected val fileName = listItem.name - item_name.text = if (textToHighlight.isEmpty()) fileName else fileName.highlightTextPart(textToHighlight, properPrimaryColor) - item_name.setTextColor(textColor) - item_name.setTextSize(TypedValue.COMPLEX_UNIT_PX, if (isListViewType) fontSize else smallerFontSize) + itemName?.text = if (textToHighlight.isEmpty()) fileName else fileName.highlightTextPart(textToHighlight, properPrimaryColor) + itemName?.setTextColor(textColor) + itemName?.setTextSize(TypedValue.COMPLEX_UNIT_PX, if (isListViewType) fontSize else smallerFontSize) - item_details?.setTextColor(textColor) - item_details?.setTextSize(TypedValue.COMPLEX_UNIT_PX, fontSize) + itemDetails?.setTextColor(textColor) + itemDetails?.setTextSize(TypedValue.COMPLEX_UNIT_PX, fontSize) - item_date?.setTextColor(textColor) - item_date?.setTextSize(TypedValue.COMPLEX_UNIT_PX, smallerFontSize) + itemDate?.setTextColor(textColor) + itemDate?.setTextSize(TypedValue.COMPLEX_UNIT_PX, smallerFontSize) - item_check?.beVisibleIf(isSelected) + itemCheck?.beVisibleIf(isSelected) if (isSelected) { - item_check?.background?.applyColorFilter(properPrimaryColor) - item_check?.applyColorFilter(contrastColor) + itemCheck?.background?.applyColorFilter(properPrimaryColor) + itemCheck?.applyColorFilter(contrastColor) } if (!isListViewType && !listItem.isDirectory) { - item_name.beVisibleIf(displayFilenamesInGrid) + itemName?.beVisibleIf(displayFilenamesInGrid) } else { - item_name.beVisible() + itemName?.beVisible() } if (listItem.isDirectory) { - item_icon.setImageDrawable(folderDrawable) - item_details?.text = getChildrenCnt(listItem) - item_date?.beGone() + itemIcon?.setImageDrawable(folderDrawable) + itemDetails?.text = getChildrenCnt(listItem) + itemDate?.beGone() } else { - item_details?.text = listItem.size.formatSize() - item_date?.beVisible() - item_date?.text = listItem.modified.formatDate(activity, dateFormat, timeFormat) + itemDetails?.text = listItem.size.formatSize() + itemDate?.beVisible() + itemDate?.text = listItem.modified.formatDate(activity, dateFormat, timeFormat) val drawable = fileDrawables.getOrElse(fileName.substringAfterLast(".").toLowerCase(), { fileDrawable }) val options = RequestOptions() @@ -889,12 +880,12 @@ class ItemsAdapter( .transform(CenterCrop(), RoundedCorners(10)) val itemToLoad = getImagePathToLoad(listItem.path) - if (!activity.isDestroyed) { + if (!activity.isDestroyed && itemIcon != null) { Glide.with(activity) .load(itemToLoad) .transition(DrawableTransitionOptions.withCrossFade()) .apply(options) - .into(item_icon) + .into(itemIcon!!) } } } @@ -941,4 +932,146 @@ class ItemsAdapter( } override fun onChange(position: Int) = listItems.getOrNull(position)?.getBubbleText(activity, dateFormat, timeFormat) ?: "" + + private sealed interface Binding { + companion object { + fun getByItemViewType(viewType: Int, isListViewType: Boolean): Binding { + return when (viewType) { + TYPE_SECTION -> ItemSection + TYPE_GRID_TYPE_DIVIDER -> ItemEmpty + else -> { + if (isListViewType) { + ItemFileDirList + } else if (viewType == TYPE_DIR) { + ItemDirGrid + } else { + ItemFileGrid + } + } + } + } + } + + fun inflate(layoutInflater: LayoutInflater, viewGroup: ViewGroup, attachToRoot: Boolean): ItemViewBinding + fun bind(view: View): ItemViewBinding + + data object ItemSection : Binding { + override fun inflate(layoutInflater: LayoutInflater, viewGroup: ViewGroup, attachToRoot: Boolean): ItemViewBinding { + return ItemSectionBindingAdapter(ItemSectionBinding.inflate(layoutInflater, viewGroup, attachToRoot)) + } + + override fun bind(view: View): ItemViewBinding { + return ItemSectionBindingAdapter(ItemSectionBinding.bind(view)) + } + } + + data object ItemEmpty : Binding { + override fun inflate(layoutInflater: LayoutInflater, viewGroup: ViewGroup, attachToRoot: Boolean): ItemViewBinding { + return ItemEmptyBindingAdapter(ItemEmptyBinding.inflate(layoutInflater, viewGroup, attachToRoot)) + } + + override fun bind(view: View): ItemViewBinding { + return ItemEmptyBindingAdapter(ItemEmptyBinding.bind(view)) + } + } + + data object ItemFileDirList : Binding { + override fun inflate(layoutInflater: LayoutInflater, viewGroup: ViewGroup, attachToRoot: Boolean): ItemViewBinding { + return ItemFileDirListBindingAdapter(ItemFileDirListBinding.inflate(layoutInflater, viewGroup, attachToRoot)) + } + + override fun bind(view: View): ItemViewBinding { + return ItemFileDirListBindingAdapter(ItemFileDirListBinding.bind(view)) + } + } + + data object ItemDirGrid : Binding { + override fun inflate(layoutInflater: LayoutInflater, viewGroup: ViewGroup, attachToRoot: Boolean): ItemViewBinding { + return ItemDirGridBindingAdapter(ItemDirGridBinding.inflate(layoutInflater, viewGroup, attachToRoot)) + } + + override fun bind(view: View): ItemViewBinding { + return ItemDirGridBindingAdapter(ItemDirGridBinding.bind(view)) + } + } + + data object ItemFileGrid : Binding { + override fun inflate(layoutInflater: LayoutInflater, viewGroup: ViewGroup, attachToRoot: Boolean): ItemViewBinding { + return ItemFileGridBindingAdapter(ItemFileGridBinding.inflate(layoutInflater, viewGroup, attachToRoot)) + } + + override fun bind(view: View): ItemViewBinding { + return ItemFileGridBindingAdapter(ItemFileGridBinding.bind(view)) + } + } + } + + private interface ItemViewBinding : ViewBinding { + val itemFrame: FrameLayout + val itemName: TextView? + val itemIcon: ImageView? + val itemCheck: ImageView? + val itemDetails: TextView? + val itemDate: TextView? + val itemSection: TextView? + } + + private class ItemSectionBindingAdapter(val binding: ItemSectionBinding) : ItemViewBinding { + override val itemFrame: FrameLayout = binding.itemFrame + override val itemName: TextView? = null + override val itemIcon: ImageView = binding.itemIcon + override val itemDetails: TextView? = null + override val itemDate: TextView? = null + override val itemCheck: ImageView? = null + override val itemSection: TextView = binding.itemSection + override fun getRoot(): View = binding.root + } + + private class ItemEmptyBindingAdapter(val binding: ItemEmptyBinding) : ItemViewBinding { + override val itemFrame: FrameLayout = binding.itemFrame + override val itemName: TextView? = null + override val itemIcon: ImageView? = null + override val itemDetails: TextView? = null + override val itemDate: TextView? = null + override val itemCheck: ImageView? = null + override val itemSection: TextView? = null + + override fun getRoot(): View = binding.root + } + + private class ItemFileDirListBindingAdapter(val binding: ItemFileDirListBinding) : ItemViewBinding { + override val itemFrame: FrameLayout = binding.itemFrame + override val itemName: TextView = binding.itemName + override val itemIcon: ImageView = binding.itemIcon + override val itemDetails: TextView = binding.itemDetails + override val itemDate: TextView = binding.itemDate + override val itemCheck: ImageView? = null + override val itemSection: TextView? = null + + override fun getRoot(): View = binding.root + } + + private class ItemDirGridBindingAdapter(val binding: ItemDirGridBinding) : ItemViewBinding { + override val itemFrame: FrameLayout = binding.itemFrame + override val itemName: TextView = binding.itemName + override val itemIcon: ImageView = binding.itemIcon + override val itemDetails: TextView? = null + override val itemDate: TextView? = null + override val itemCheck: ImageView = binding.itemCheck + override val itemSection: TextView? = null + + override fun getRoot(): View = binding.root + } + + private class ItemFileGridBindingAdapter(val binding: ItemFileGridBinding) : ItemViewBinding { + override val itemFrame: FrameLayout = binding.itemFrame + override val itemName: TextView = binding.itemName + override val itemIcon: ImageView = binding.itemIcon + override val itemDetails: TextView? = null + override val itemDate: TextView? = null + override val itemCheck: ImageView? = null + override val itemSection: TextView? = null + + override fun getRoot(): View = binding.root + } } diff --git a/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/adapters/ManageFavoritesAdapter.kt b/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/adapters/ManageFavoritesAdapter.kt index dac8f0e8..804f31d7 100644 --- a/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/adapters/ManageFavoritesAdapter.kt +++ b/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/adapters/ManageFavoritesAdapter.kt @@ -10,8 +10,8 @@ import com.simplemobiletools.commons.extensions.setupViewBackground import com.simplemobiletools.commons.interfaces.RefreshRecyclerViewListener import com.simplemobiletools.commons.views.MyRecyclerView import com.simplemobiletools.filemanager.pro.R +import com.simplemobiletools.filemanager.pro.databinding.ItemManageFavoriteBinding import com.simplemobiletools.filemanager.pro.extensions.config -import kotlinx.android.synthetic.main.item_manage_favorite.view.* class ManageFavoritesAdapter( activity: BaseSimpleActivity, var favorites: ArrayList, val listener: RefreshRecyclerViewListener?, @@ -46,7 +46,9 @@ class ManageFavoritesAdapter( override fun prepareActionMode(menu: Menu) {} - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = createViewHolder(R.layout.item_manage_favorite, parent) + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { + return createViewHolder(ItemManageFavoriteBinding.inflate(layoutInflater, parent, false).root) + } override fun onBindViewHolder(holder: ViewHolder, position: Int) { val favorite = favorites[position] @@ -59,22 +61,22 @@ class ManageFavoritesAdapter( override fun getItemCount() = favorites.size private fun setupView(view: View, favorite: String, isSelected: Boolean) { - view.apply { - setupViewBackground(activity) - manage_favorite_title.apply { + ItemManageFavoriteBinding.bind(view).apply { + root.setupViewBackground(activity) + manageFavoriteTitle.apply { text = favorite setTextColor(activity.getProperTextColor()) } - manage_favorite_holder?.isSelected = isSelected + manageFavoriteHolder?.isSelected = isSelected - overflow_menu_icon.drawable.apply { + overflowMenuIcon.drawable.apply { mutate() setTint(activity.getProperTextColor()) } - overflow_menu_icon.setOnClickListener { - showPopupMenu(overflow_menu_anchor, favorite) + overflowMenuIcon.setOnClickListener { + showPopupMenu(overflowMenuAnchor, favorite) } } } diff --git a/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/adapters/ViewPagerAdapter.kt b/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/adapters/ViewPagerAdapter.kt index dab82eb4..2d9d8042 100644 --- a/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/adapters/ViewPagerAdapter.kt +++ b/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/adapters/ViewPagerAdapter.kt @@ -20,7 +20,7 @@ class ViewPagerAdapter(val activity: SimpleActivity, val tabsToShow: ArrayList).apply { val isPickRingtoneIntent = activity.intent.action == RingtoneManager.ACTION_RINGTONE_PICKER val isGetContentIntent = activity.intent.action == Intent.ACTION_GET_CONTENT || activity.intent.action == Intent.ACTION_PICK val isCreateDocumentIntent = activity.intent.action == Intent.ACTION_CREATE_DOCUMENT diff --git a/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/dialogs/ChangeSortingDialog.kt b/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/dialogs/ChangeSortingDialog.kt index 9f188f36..1475a4e1 100644 --- a/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/dialogs/ChangeSortingDialog.kt +++ b/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/dialogs/ChangeSortingDialog.kt @@ -1,34 +1,33 @@ package com.simplemobiletools.filemanager.pro.dialogs -import android.view.View import com.simplemobiletools.commons.activities.BaseSimpleActivity import com.simplemobiletools.commons.extensions.beVisibleIf import com.simplemobiletools.commons.extensions.getAlertDialogBuilder import com.simplemobiletools.commons.extensions.setupDialogStuff import com.simplemobiletools.commons.helpers.* import com.simplemobiletools.filemanager.pro.R +import com.simplemobiletools.filemanager.pro.databinding.DialogChangeSortingBinding import com.simplemobiletools.filemanager.pro.extensions.config -import kotlinx.android.synthetic.main.dialog_change_sorting.view.* class ChangeSortingDialog(val activity: BaseSimpleActivity, val path: String = "", val callback: () -> Unit) { private var currSorting = 0 private var config = activity.config - private var view: View + private val binding: DialogChangeSortingBinding init { currSorting = config.getFolderSorting(path) - view = activity.layoutInflater.inflate(R.layout.dialog_change_sorting, null).apply { - sorting_dialog_use_for_this_folder.isChecked = config.hasCustomSorting(path) + binding = DialogChangeSortingBinding.inflate(activity.layoutInflater).apply { + sortingDialogUseForThisFolder.isChecked = config.hasCustomSorting(path) - sorting_dialog_numeric_sorting.beVisibleIf(currSorting and SORT_BY_NAME != 0) - sorting_dialog_numeric_sorting.isChecked = currSorting and SORT_USE_NUMERIC_VALUE != 0 + sortingDialogNumericSorting.beVisibleIf(currSorting and SORT_BY_NAME != 0) + sortingDialogNumericSorting.isChecked = currSorting and SORT_USE_NUMERIC_VALUE != 0 } activity.getAlertDialogBuilder() .setPositiveButton(R.string.ok) { dialog, which -> dialogConfirmed() } .setNegativeButton(R.string.cancel, null) .apply { - activity.setupDialogStuff(view, this, R.string.sort_by) + activity.setupDialogStuff(binding.root, this, R.string.sort_by) } setupSortRadio() @@ -36,34 +35,33 @@ class ChangeSortingDialog(val activity: BaseSimpleActivity, val path: String = " } private fun setupSortRadio() { - val sortingRadio = view.sorting_dialog_radio_sorting + binding.apply { + sortingDialogRadioSorting.setOnCheckedChangeListener { group, checkedId -> + val isSortingByName = checkedId == sortingDialogRadioName.id + binding.sortingDialogNumericSorting.beVisibleIf(isSortingByName) + } - sortingRadio.setOnCheckedChangeListener { group, checkedId -> - val isSortingByName = checkedId == sortingRadio.sorting_dialog_radio_name.id - view.sorting_dialog_numeric_sorting.beVisibleIf(isSortingByName) + val sortBtn = when { + currSorting and SORT_BY_SIZE != 0 -> sortingDialogRadioSize + currSorting and SORT_BY_DATE_MODIFIED != 0 -> sortingDialogRadioLastModified + currSorting and SORT_BY_EXTENSION != 0 -> sortingDialogRadioExtension + else -> sortingDialogRadioName + } + sortBtn.isChecked = true } - - val sortBtn = when { - currSorting and SORT_BY_SIZE != 0 -> sortingRadio.sorting_dialog_radio_size - currSorting and SORT_BY_DATE_MODIFIED != 0 -> sortingRadio.sorting_dialog_radio_last_modified - currSorting and SORT_BY_EXTENSION != 0 -> sortingRadio.sorting_dialog_radio_extension - else -> sortingRadio.sorting_dialog_radio_name - } - sortBtn.isChecked = true } private fun setupOrderRadio() { - val orderRadio = view.sorting_dialog_radio_order - var orderBtn = orderRadio.sorting_dialog_radio_ascending + var orderBtn = binding.sortingDialogRadioAscending if (currSorting and SORT_DESCENDING != 0) { - orderBtn = orderRadio.sorting_dialog_radio_descending + orderBtn = binding.sortingDialogRadioDescending } orderBtn.isChecked = true } private fun dialogConfirmed() { - val sortingRadio = view.sorting_dialog_radio_sorting + val sortingRadio = binding.sortingDialogRadioSorting var sorting = when (sortingRadio.checkedRadioButtonId) { R.id.sorting_dialog_radio_name -> SORT_BY_NAME R.id.sorting_dialog_radio_size -> SORT_BY_SIZE @@ -71,15 +69,15 @@ class ChangeSortingDialog(val activity: BaseSimpleActivity, val path: String = " else -> SORT_BY_EXTENSION } - if (view.sorting_dialog_radio_order.checkedRadioButtonId == R.id.sorting_dialog_radio_descending) { + if (binding.sortingDialogRadioOrder.checkedRadioButtonId == R.id.sorting_dialog_radio_descending) { sorting = sorting or SORT_DESCENDING } - if (view.sorting_dialog_numeric_sorting.isChecked) { + if (binding.sortingDialogNumericSorting.isChecked) { sorting = sorting or SORT_USE_NUMERIC_VALUE } - if (view.sorting_dialog_use_for_this_folder.isChecked) { + if (binding.sortingDialogUseForThisFolder.isChecked) { config.saveCustomSorting(path, sorting) } else { config.removeCustomSorting(path) diff --git a/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/dialogs/ChangeViewTypeDialog.kt b/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/dialogs/ChangeViewTypeDialog.kt index f27de77a..ecc1414e 100644 --- a/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/dialogs/ChangeViewTypeDialog.kt +++ b/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/dialogs/ChangeViewTypeDialog.kt @@ -1,6 +1,5 @@ package com.simplemobiletools.filemanager.pro.dialogs -import android.view.View import com.simplemobiletools.commons.activities.BaseSimpleActivity import com.simplemobiletools.commons.extensions.beGone import com.simplemobiletools.commons.extensions.getAlertDialogBuilder @@ -8,29 +7,29 @@ import com.simplemobiletools.commons.extensions.setupDialogStuff import com.simplemobiletools.commons.helpers.VIEW_TYPE_GRID import com.simplemobiletools.commons.helpers.VIEW_TYPE_LIST import com.simplemobiletools.filemanager.pro.R +import com.simplemobiletools.filemanager.pro.databinding.DialogChangeViewTypeBinding import com.simplemobiletools.filemanager.pro.extensions.config -import kotlinx.android.synthetic.main.dialog_change_view_type.view.* class ChangeViewTypeDialog(val activity: BaseSimpleActivity, val path: String = "", showFolderCheck: Boolean = true, val callback: () -> Unit) { - private var view: View + private var binding: DialogChangeViewTypeBinding private var config = activity.config init { - view = activity.layoutInflater.inflate(R.layout.dialog_change_view_type, null).apply { + binding = DialogChangeViewTypeBinding.inflate(activity.layoutInflater).apply { val currViewType = config.getFolderViewType(this@ChangeViewTypeDialog.path) val viewToCheck = if (currViewType == VIEW_TYPE_GRID) { - change_view_type_dialog_radio_grid.id + changeViewTypeDialogRadioGrid.id } else { - change_view_type_dialog_radio_list.id + changeViewTypeDialogRadioList.id } - change_view_type_dialog_radio.check(viewToCheck) + changeViewTypeDialogRadio.check(viewToCheck) if (!showFolderCheck) { - use_for_this_folder_divider.beGone() - change_view_type_dialog_use_for_this_folder.beGone() + useForThisFolderDivider.beGone() + changeViewTypeDialogUseForThisFolder.beGone() } - change_view_type_dialog_use_for_this_folder.apply { + changeViewTypeDialogUseForThisFolder.apply { isChecked = config.hasCustomViewType(this@ChangeViewTypeDialog.path) } } @@ -39,18 +38,18 @@ class ChangeViewTypeDialog(val activity: BaseSimpleActivity, val path: String = .setPositiveButton(R.string.ok) { dialog, which -> dialogConfirmed() } .setNegativeButton(R.string.cancel, null) .apply { - activity.setupDialogStuff(view, this) + activity.setupDialogStuff(binding.root, this) } } private fun dialogConfirmed() { - val viewType = if (view.change_view_type_dialog_radio.checkedRadioButtonId == view.change_view_type_dialog_radio_grid.id) { + val viewType = if (binding.changeViewTypeDialogRadio.checkedRadioButtonId == binding.changeViewTypeDialogRadioGrid.id) { VIEW_TYPE_GRID } else { VIEW_TYPE_LIST } - if (view.change_view_type_dialog_use_for_this_folder.isChecked) { + if (binding.changeViewTypeDialogUseForThisFolder.isChecked) { config.saveFolderViewType(this.path, viewType) } else { config.removeFolderViewType(this.path) diff --git a/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/dialogs/CompressAsDialog.kt b/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/dialogs/CompressAsDialog.kt index e56aaca6..ce2c6972 100644 --- a/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/dialogs/CompressAsDialog.kt +++ b/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/dialogs/CompressAsDialog.kt @@ -6,11 +6,11 @@ import com.simplemobiletools.commons.activities.BaseSimpleActivity import com.simplemobiletools.commons.dialogs.FilePickerDialog import com.simplemobiletools.commons.extensions.* import com.simplemobiletools.filemanager.pro.R +import com.simplemobiletools.filemanager.pro.databinding.DialogCompressAsBinding import com.simplemobiletools.filemanager.pro.extensions.config -import kotlinx.android.synthetic.main.dialog_compress_as.view.* class CompressAsDialog(val activity: BaseSimpleActivity, val path: String, val callback: (destination: String, password: String?) -> Unit) { - private val view = activity.layoutInflater.inflate(R.layout.dialog_compress_as, null) + private val binding = DialogCompressAsBinding.inflate(activity.layoutInflater) init { val filename = path.getFilenameFromPath() @@ -18,8 +18,8 @@ class CompressAsDialog(val activity: BaseSimpleActivity, val path: String, val c val baseFilename = filename.substring(0, indexOfDot) var realPath = path.getParentPath() - view.apply { - filename_value.setText(baseFilename) + binding.apply { + filenameValue.setText(baseFilename) folder.setText(activity.humanizePath(realPath)) folder.setOnClickListener { @@ -29,8 +29,8 @@ class CompressAsDialog(val activity: BaseSimpleActivity, val path: String, val c } } - password_protect.setOnCheckedChangeListener { _, _ -> - enter_password_hint.beVisibleIf(password_protect.isChecked) + passwordProtect.setOnCheckedChangeListener { _, _ -> + enterPasswordHint.beVisibleIf(passwordProtect.isChecked) } } @@ -38,13 +38,13 @@ class CompressAsDialog(val activity: BaseSimpleActivity, val path: String, val c .setPositiveButton(R.string.ok, null) .setNegativeButton(R.string.cancel, null) .apply { - activity.setupDialogStuff(view, this, R.string.compress_as) { alertDialog -> - alertDialog.showKeyboard(view.filename_value) + activity.setupDialogStuff(binding.root, this, R.string.compress_as) { alertDialog -> + alertDialog.showKeyboard(binding.filenameValue) alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(View.OnClickListener { - val name = view.filename_value.value + val name = binding.filenameValue.value var password: String? = null - if (view.password_protect.isChecked) { - password = view.password.value + if (binding.passwordProtect.isChecked) { + password = binding.password.value if (password.isEmpty()) { activity.toast(R.string.empty_password_new) return@OnClickListener diff --git a/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/dialogs/CreateNewItemDialog.kt b/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/dialogs/CreateNewItemDialog.kt index c0e3da5d..821e3d4b 100644 --- a/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/dialogs/CreateNewItemDialog.kt +++ b/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/dialogs/CreateNewItemDialog.kt @@ -6,23 +6,23 @@ import com.simplemobiletools.commons.extensions.* import com.simplemobiletools.commons.helpers.isRPlus import com.simplemobiletools.filemanager.pro.R import com.simplemobiletools.filemanager.pro.activities.SimpleActivity +import com.simplemobiletools.filemanager.pro.databinding.DialogCreateNewBinding import com.simplemobiletools.filemanager.pro.helpers.RootHelpers -import kotlinx.android.synthetic.main.dialog_create_new.view.* import java.io.File import java.io.IOException class CreateNewItemDialog(val activity: SimpleActivity, val path: String, val callback: (success: Boolean) -> Unit) { - private val view = activity.layoutInflater.inflate(R.layout.dialog_create_new, null) + private val binding = DialogCreateNewBinding.inflate(activity.layoutInflater) init { activity.getAlertDialogBuilder() .setPositiveButton(R.string.ok, null) .setNegativeButton(R.string.cancel, null) .apply { - activity.setupDialogStuff(view, this, R.string.create_new) { alertDialog -> - alertDialog.showKeyboard(view.item_title) + activity.setupDialogStuff(binding.root, this, R.string.create_new) { alertDialog -> + alertDialog.showKeyboard(binding.itemTitle) alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(View.OnClickListener { - val name = view.item_title.value + val name = binding.itemTitle.value if (name.isEmpty()) { activity.toast(R.string.empty_name) } else if (name.isAValidFilename()) { @@ -32,7 +32,7 @@ class CreateNewItemDialog(val activity: SimpleActivity, val path: String, val ca return@OnClickListener } - if (view.dialog_radio_group.checkedRadioButtonId == R.id.dialog_radio_directory) { + if (binding.dialogRadioGroup.checkedRadioButtonId == R.id.dialog_radio_directory) { createDirectory(newPath, alertDialog) { callback(it) } diff --git a/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/dialogs/InsertFilenameDialog.kt b/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/dialogs/InsertFilenameDialog.kt index 0b858ed9..42879c21 100644 --- a/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/dialogs/InsertFilenameDialog.kt +++ b/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/dialogs/InsertFilenameDialog.kt @@ -4,23 +4,23 @@ import androidx.appcompat.app.AlertDialog import com.simplemobiletools.commons.activities.BaseSimpleActivity import com.simplemobiletools.commons.extensions.* import com.simplemobiletools.filemanager.pro.R -import kotlinx.android.synthetic.main.dialog_insert_filename.view.* +import com.simplemobiletools.filemanager.pro.databinding.DialogInsertFilenameBinding class InsertFilenameDialog( val activity: BaseSimpleActivity, var path: String, val callback: (filename: String) -> Unit ) { init { - val view = activity.layoutInflater.inflate(R.layout.dialog_insert_filename, null) + val binding = DialogInsertFilenameBinding.inflate(activity.layoutInflater) activity.getAlertDialogBuilder() .setPositiveButton(R.string.ok, null) .setNegativeButton(R.string.cancel, null) .apply { - activity.setupDialogStuff(view, this, R.string.filename) { alertDialog -> - alertDialog.showKeyboard(view.insert_filename_title) + activity.setupDialogStuff(binding.root, this, R.string.filename) { alertDialog -> + alertDialog.showKeyboard(binding.insertFilenameTitle) alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener { - val filename = view.insert_filename_title.value - val extension = view.insert_filename_extension_title.value + val filename = binding.insertFilenameTitle.value + val extension = binding.insertFilenameExtensionTitle.value if (filename.isEmpty()) { activity.toast(R.string.filename_cannot_be_empty) diff --git a/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/dialogs/ManageVisibleTabsDialog.kt b/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/dialogs/ManageVisibleTabsDialog.kt index f7d4c21c..7f37ff7b 100644 --- a/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/dialogs/ManageVisibleTabsDialog.kt +++ b/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/dialogs/ManageVisibleTabsDialog.kt @@ -10,12 +10,12 @@ import com.simplemobiletools.commons.helpers.TAB_STORAGE_ANALYSIS import com.simplemobiletools.commons.helpers.isOreoPlus import com.simplemobiletools.commons.views.MyAppCompatCheckbox import com.simplemobiletools.filemanager.pro.R +import com.simplemobiletools.filemanager.pro.databinding.DialogManageVisibleTabsBinding import com.simplemobiletools.filemanager.pro.extensions.config import com.simplemobiletools.filemanager.pro.helpers.ALL_TABS_MASK -import kotlinx.android.synthetic.main.dialog_manage_visible_tabs.view.* class ManageVisibleTabsDialog(val activity: BaseSimpleActivity) { - private var view = activity.layoutInflater.inflate(R.layout.dialog_manage_visible_tabs, null) + private val binding = DialogManageVisibleTabsBinding.inflate(activity.layoutInflater) private val tabs = LinkedHashMap() init { @@ -26,26 +26,26 @@ class ManageVisibleTabsDialog(val activity: BaseSimpleActivity) { } if (!isOreoPlus()) { - view.manage_visible_tabs_storage_analysis.beGone() + binding.manageVisibleTabsStorageAnalysis.beGone() } val showTabs = activity.config.showTabs for ((key, value) in tabs) { - view.findViewById(value).isChecked = showTabs and key != 0 + binding.root.findViewById(value).isChecked = showTabs and key != 0 } activity.getAlertDialogBuilder() .setPositiveButton(R.string.ok) { dialog, which -> dialogConfirmed() } .setNegativeButton(R.string.cancel, null) .apply { - activity.setupDialogStuff(view, this) + activity.setupDialogStuff(binding.root, this) } } private fun dialogConfirmed() { var result = 0 for ((key, value) in tabs) { - if (view.findViewById(value).isChecked) { + if (binding.root.findViewById(value).isChecked) { result += key } } diff --git a/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/dialogs/SaveAsDialog.kt b/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/dialogs/SaveAsDialog.kt index 13ca4d09..e733b387 100644 --- a/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/dialogs/SaveAsDialog.kt +++ b/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/dialogs/SaveAsDialog.kt @@ -6,7 +6,7 @@ import com.simplemobiletools.commons.dialogs.ConfirmationDialog import com.simplemobiletools.commons.dialogs.FilePickerDialog import com.simplemobiletools.commons.extensions.* import com.simplemobiletools.filemanager.pro.R -import kotlinx.android.synthetic.main.dialog_save_as.view.* +import com.simplemobiletools.filemanager.pro.databinding.DialogSaveAsBinding class SaveAsDialog( val activity: BaseSimpleActivity, var path: String, val hidePath: Boolean, @@ -19,8 +19,8 @@ class SaveAsDialog( } var realPath = path.getParentPath() - val view = activity.layoutInflater.inflate(R.layout.dialog_save_as, null).apply { - folder_value.setText(activity.humanizePath(realPath)) + val binding = DialogSaveAsBinding.inflate(activity.layoutInflater).apply { + folderValue.setText(activity.humanizePath(realPath)) val fullName = path.getFilenameFromPath() val dotAt = fullName.lastIndexOf(".") @@ -29,17 +29,17 @@ class SaveAsDialog( if (dotAt > 0) { name = fullName.substring(0, dotAt) val extension = fullName.substring(dotAt + 1) - extension_value.setText(extension) + extensionValue.setText(extension) } - filename_value.setText(name) + filenameValue.setText(name) if (hidePath) { - folder_hint.beGone() + folderHint.beGone() } else { - folder_value.setOnClickListener { + folderValue.setOnClickListener { FilePickerDialog(activity, realPath, false, false, true, true, showFavoritesButton = true) { - folder_value.setText(activity.humanizePath(it)) + folderValue.setText(activity.humanizePath(it)) realPath = it } } @@ -50,11 +50,11 @@ class SaveAsDialog( .setPositiveButton(R.string.ok, null) .setNegativeButton(R.string.cancel, null) .apply { - activity.setupDialogStuff(view, this, R.string.save_as) { alertDialog -> - alertDialog.showKeyboard(view.filename_value) + activity.setupDialogStuff(binding.root, this, R.string.save_as) { alertDialog -> + alertDialog.showKeyboard(binding.filenameValue) alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener { - val filename = view.filename_value.value - val extension = view.extension_value.value + val filename = binding.filenameValue.value + val extension = binding.extensionValue.value if (filename.isEmpty()) { activity.toast(R.string.filename_cannot_be_empty) diff --git a/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/fragments/ItemsFragment.kt b/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/fragments/ItemsFragment.kt index caa8492b..0aa811f0 100644 --- a/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/fragments/ItemsFragment.kt +++ b/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/fragments/ItemsFragment.kt @@ -17,6 +17,7 @@ import com.simplemobiletools.filemanager.pro.R import com.simplemobiletools.filemanager.pro.activities.MainActivity import com.simplemobiletools.filemanager.pro.activities.SimpleActivity import com.simplemobiletools.filemanager.pro.adapters.ItemsAdapter +import com.simplemobiletools.filemanager.pro.databinding.ItemsFragmentBinding import com.simplemobiletools.filemanager.pro.dialogs.CreateNewItemDialog import com.simplemobiletools.filemanager.pro.extensions.config import com.simplemobiletools.filemanager.pro.extensions.isPathOnRoot @@ -24,10 +25,10 @@ import com.simplemobiletools.filemanager.pro.helpers.MAX_COLUMN_COUNT import com.simplemobiletools.filemanager.pro.helpers.RootHelpers import com.simplemobiletools.filemanager.pro.interfaces.ItemOperationsListener import com.simplemobiletools.filemanager.pro.models.ListItem -import kotlinx.android.synthetic.main.items_fragment.view.* import java.io.File -class ItemsFragment(context: Context, attributeSet: AttributeSet) : MyViewPagerFragment(context, attributeSet), ItemOperationsListener, +class ItemsFragment(context: Context, attributeSet: AttributeSet) : MyViewPagerFragment(context, attributeSet), + ItemOperationsListener, Breadcrumbs.BreadcrumbsListener { private var showHidden = false private var lastSearchedText = "" @@ -36,17 +37,26 @@ class ItemsFragment(context: Context, attributeSet: AttributeSet) : MyViewPagerF private var storedItems = ArrayList() private var itemsIgnoringSearch = ArrayList() + private lateinit var binding: ItemsFragmentBinding + + override fun onFinishInflate() { + super.onFinishInflate() + binding = ItemsFragmentBinding.bind(this) + innerBinding = ItemsInnerBinding(binding) + } override fun setupFragment(activity: SimpleActivity) { if (this.activity == null) { this.activity = activity - breadcrumbs.listener = this@ItemsFragment - items_swipe_refresh.setOnRefreshListener { refreshFragment() } - items_fab.setOnClickListener { - if (isCreateDocumentIntent) { - (activity as MainActivity).createDocumentConfirmed(currentPath) - } else { - createNewItem() + binding.apply { + breadcrumbs.listener = this@ItemsFragment + itemsSwipeRefresh.setOnRefreshListener { refreshFragment() } + itemsFab.setOnClickListener { + if (isCreateDocumentIntent) { + (activity as MainActivity).createDocumentConfirmed(currentPath) + } else { + createNewItem() + } } } } @@ -60,22 +70,24 @@ class ItemsFragment(context: Context, attributeSet: AttributeSet) : MyViewPagerF initDrawables() } - val properPrimaryColor = context!!.getProperPrimaryColor() - items_fastscroller.updateColors(properPrimaryColor) - progress_bar.setIndicatorColor(properPrimaryColor) - progress_bar.trackColor = properPrimaryColor.adjustAlpha(LOWER_ALPHA) + binding.apply { + val properPrimaryColor = context!!.getProperPrimaryColor() + itemsFastscroller.updateColors(properPrimaryColor) + progressBar.setIndicatorColor(properPrimaryColor) + progressBar.trackColor = properPrimaryColor.adjustAlpha(LOWER_ALPHA) - if (currentPath != "") { - breadcrumbs.updateColor(textColor) + if (currentPath != "") { + breadcrumbs.updateColor(textColor) + } + + itemsSwipeRefresh.isEnabled = lastSearchedText.isEmpty() && activity?.config?.enablePullToRefresh != false } - - items_swipe_refresh.isEnabled = lastSearchedText.isEmpty() && activity?.config?.enablePullToRefresh != false } override fun setupFontSize() { getRecyclerAdapter()?.updateFontSizes() if (currentPath != "") { - breadcrumbs.updateFontSize(context!!.getTextSize(), false) + binding.breadcrumbs.updateFontSize(context!!.getTextSize(), false) } } @@ -133,18 +145,18 @@ class ItemsFragment(context: Context, attributeSet: AttributeSet) : MyViewPagerF private fun addItems(items: ArrayList, forceRefresh: Boolean = false) { activity?.runOnUiThread { - items_swipe_refresh?.isRefreshing = false - breadcrumbs.setBreadcrumb(currentPath) + binding.itemsSwipeRefresh?.isRefreshing = false + binding.breadcrumbs.setBreadcrumb(currentPath) if (!forceRefresh && items.hashCode() == storedItems.hashCode()) { return@runOnUiThread } storedItems = items - if (items_list.adapter == null) { - breadcrumbs.updateFontSize(context!!.getTextSize(), true) + if (binding.itemsList.adapter == null) { + binding.breadcrumbs.updateFontSize(context!!.getTextSize(), true) } - ItemsAdapter(activity as SimpleActivity, storedItems, this, items_list, isPickMultipleIntent, items_swipe_refresh) { + ItemsAdapter(activity as SimpleActivity, storedItems, this, binding.itemsList, isPickMultipleIntent, binding.itemsSwipeRefresh) { if ((it as? ListItem)?.isSectionTitle == true) { openDirectory(it.mPath) searchClosed() @@ -153,11 +165,11 @@ class ItemsFragment(context: Context, attributeSet: AttributeSet) : MyViewPagerF } }.apply { setupZoomListener(zoomListener) - items_list.adapter = this + binding.itemsList.adapter = this } if (context.areSystemAnimationsEnabled) { - items_list.scheduleLayoutAnimation() + binding.itemsList.scheduleLayoutAnimation() } getRecyclerLayoutManager().onRestoreInstanceState(scrollStates[currentPath]) @@ -166,7 +178,7 @@ class ItemsFragment(context: Context, attributeSet: AttributeSet) : MyViewPagerF private fun getScrollState() = getRecyclerLayoutManager().onSaveInstanceState() - private fun getRecyclerLayoutManager() = (items_list.layoutManager as MyGridLayoutManager) + private fun getRecyclerLayoutManager() = (binding.itemsList.layoutManager as MyGridLayoutManager) @SuppressLint("NewApi") private fun getItems(path: String, callback: (originalPath: String, items: ArrayList) -> Unit) { @@ -295,60 +307,64 @@ class ItemsFragment(context: Context, attributeSet: AttributeSet) : MyViewPagerF return } - items_swipe_refresh.isEnabled = text.isEmpty() && activity?.config?.enablePullToRefresh != false - when { - text.isEmpty() -> { - items_fastscroller.beVisible() - getRecyclerAdapter()?.updateItems(itemsIgnoringSearch) - items_placeholder.beGone() - items_placeholder_2.beGone() - hideProgressBar() - } - text.length == 1 -> { - items_fastscroller.beGone() - items_placeholder.beVisible() - items_placeholder_2.beVisible() - hideProgressBar() - } - else -> { - showProgressBar() - ensureBackgroundThread { - val files = searchFiles(text, currentPath) - files.sortBy { it.getParentPath() } + binding.apply { + itemsSwipeRefresh.isEnabled = text.isEmpty() && activity?.config?.enablePullToRefresh != false + when { + text.isEmpty() -> { + itemsFastscroller.beVisible() + getRecyclerAdapter()?.updateItems(itemsIgnoringSearch) + itemsPlaceholder.beGone() + itemsPlaceholder2.beGone() + hideProgressBar() + } - if (lastSearchedText != text) { - return@ensureBackgroundThread - } + text.length == 1 -> { + itemsFastscroller.beGone() + itemsPlaceholder.beVisible() + itemsPlaceholder2.beVisible() + hideProgressBar() + } - val listItems = ArrayList() + else -> { + showProgressBar() + ensureBackgroundThread { + val files = searchFiles(text, currentPath) + files.sortBy { it.getParentPath() } - var previousParent = "" - files.forEach { - val parent = it.mPath.getParentPath() - if (!it.isDirectory && parent != previousParent && context != null) { - val sectionTitle = ListItem(parent, context!!.humanizePath(parent), false, 0, 0, 0, true, false) - listItems.add(sectionTitle) - previousParent = parent + if (lastSearchedText != text) { + return@ensureBackgroundThread } - if (it.isDirectory) { - val sectionTitle = ListItem(it.path, context!!.humanizePath(it.path), true, 0, 0, 0, true, false) - listItems.add(sectionTitle) - previousParent = parent + val listItems = ArrayList() + + var previousParent = "" + files.forEach { + val parent = it.mPath.getParentPath() + if (!it.isDirectory && parent != previousParent && context != null) { + val sectionTitle = ListItem(parent, context!!.humanizePath(parent), false, 0, 0, 0, true, false) + listItems.add(sectionTitle) + previousParent = parent + } + + if (it.isDirectory) { + val sectionTitle = ListItem(it.path, context!!.humanizePath(it.path), true, 0, 0, 0, true, false) + listItems.add(sectionTitle) + previousParent = parent + } + + if (!it.isDirectory) { + listItems.add(it) + } } - if (!it.isDirectory) { - listItems.add(it) + activity?.runOnUiThread { + getRecyclerAdapter()?.updateItems(listItems, text) + itemsFastscroller.beVisibleIf(listItems.isNotEmpty()) + itemsPlaceholder.beVisibleIf(listItems.isEmpty()) + itemsPlaceholder2.beGone() + hideProgressBar() } } - - activity?.runOnUiThread { - getRecyclerAdapter()?.updateItems(listItems, text) - items_fastscroller.beVisibleIf(listItems.isNotEmpty()) - items_placeholder.beVisibleIf(listItems.isEmpty()) - items_placeholder_2.beGone() - hideProgressBar() - } } } } @@ -390,12 +406,14 @@ class ItemsFragment(context: Context, attributeSet: AttributeSet) : MyViewPagerF } private fun searchClosed() { - lastSearchedText = "" - items_swipe_refresh.isEnabled = activity?.config?.enablePullToRefresh != false - items_fastscroller.beVisible() - items_placeholder.beGone() - items_placeholder_2.beGone() - hideProgressBar() + binding.apply { + lastSearchedText = "" + itemsSwipeRefresh.isEnabled = activity?.config?.enablePullToRefresh != false + itemsFastscroller.beVisible() + itemsPlaceholder.beGone() + itemsPlaceholder2.beGone() + hideProgressBar() + } } private fun createNewItem() { @@ -408,7 +426,7 @@ class ItemsFragment(context: Context, attributeSet: AttributeSet) : MyViewPagerF } } - private fun getRecyclerAdapter() = items_list.adapter as? ItemsAdapter + private fun getRecyclerAdapter() = binding.itemsList.adapter as? ItemsAdapter private fun setupLayoutManager() { if (context!!.config.getFolderViewType(currentPath) == VIEW_TYPE_GRID) { @@ -419,13 +437,13 @@ class ItemsFragment(context: Context, attributeSet: AttributeSet) : MyViewPagerF setupListLayoutManager() } - items_list.adapter = null + binding.itemsList.adapter = null initZoomListener() addItems(storedItems, true) } private fun setupGridLayoutManager() { - val layoutManager = items_list.layoutManager as MyGridLayoutManager + val layoutManager = binding.itemsList.layoutManager as MyGridLayoutManager layoutManager.spanCount = context?.config?.fileColumnCnt ?: 3 layoutManager.spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() { @@ -440,14 +458,14 @@ class ItemsFragment(context: Context, attributeSet: AttributeSet) : MyViewPagerF } private fun setupListLayoutManager() { - val layoutManager = items_list.layoutManager as MyGridLayoutManager + val layoutManager = binding.itemsList.layoutManager as MyGridLayoutManager layoutManager.spanCount = 1 zoomListener = null } private fun initZoomListener() { if (context?.config?.getFolderViewType(currentPath) == VIEW_TYPE_GRID) { - val layoutManager = items_list.layoutManager as MyGridLayoutManager + val layoutManager = binding.itemsList.layoutManager as MyGridLayoutManager zoomListener = object : MyRecyclerView.MyZoomListener { override fun zoomIn() { if (layoutManager.spanCount > 1) { @@ -483,21 +501,23 @@ class ItemsFragment(context: Context, attributeSet: AttributeSet) : MyViewPagerF } override fun columnCountChanged() { - (items_list.layoutManager as MyGridLayoutManager).spanCount = context!!.config.fileColumnCnt + (binding.itemsList.layoutManager as MyGridLayoutManager).spanCount = context!!.config.fileColumnCnt (activity as? MainActivity)?.refreshMenuItems() getRecyclerAdapter()?.apply { notifyItemRangeChanged(0, listItems.size) } } - private fun showProgressBar() { - progress_bar.show() + fun showProgressBar() { + binding.progressBar.show() } private fun hideProgressBar() { - progress_bar.hide() + binding.progressBar.hide() } + fun getBreadcrumbs() = binding.breadcrumbs + override fun toggleFilenameVisibility() { getRecyclerAdapter()?.updateDisplayFilenamesInGrid() } @@ -509,7 +529,7 @@ class ItemsFragment(context: Context, attributeSet: AttributeSet) : MyViewPagerF openPath(it) } } else { - val item = breadcrumbs.getItem(id) + val item = binding.breadcrumbs.getItem(id) openPath(item.path) } } diff --git a/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/fragments/MyViewPagerFragment.kt b/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/fragments/MyViewPagerFragment.kt index f5510223..115f58dd 100644 --- a/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/fragments/MyViewPagerFragment.kt +++ b/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/fragments/MyViewPagerFragment.kt @@ -6,15 +6,19 @@ import android.widget.RelativeLayout import com.simplemobiletools.commons.extensions.* import com.simplemobiletools.commons.helpers.VIEW_TYPE_LIST import com.simplemobiletools.commons.models.FileDirItem +import com.simplemobiletools.commons.views.MyFloatingActionButton import com.simplemobiletools.filemanager.pro.R import com.simplemobiletools.filemanager.pro.activities.MainActivity import com.simplemobiletools.filemanager.pro.activities.SimpleActivity +import com.simplemobiletools.filemanager.pro.databinding.ItemsFragmentBinding +import com.simplemobiletools.filemanager.pro.databinding.RecentsFragmentBinding +import com.simplemobiletools.filemanager.pro.databinding.StorageFragmentBinding import com.simplemobiletools.filemanager.pro.extensions.isPathOnRoot import com.simplemobiletools.filemanager.pro.extensions.tryOpenPathIntent import com.simplemobiletools.filemanager.pro.helpers.RootHelpers -import kotlinx.android.synthetic.main.items_fragment.view.* -abstract class MyViewPagerFragment(context: Context, attributeSet: AttributeSet) : RelativeLayout(context, attributeSet) { +abstract class MyViewPagerFragment(context: Context, attributeSet: AttributeSet) : + RelativeLayout(context, attributeSet) { protected var activity: SimpleActivity? = null protected var currentViewType = VIEW_TYPE_LIST @@ -24,6 +28,7 @@ abstract class MyViewPagerFragment(context: Context, attributeSet: AttributeSet) var isPickMultipleIntent = false var wantedMimeType = "" protected var isCreateDocumentIntent = false + protected lateinit var innerBinding: BINDING protected fun clickedPath(path: String) { if (isGetContentIntent || isCreateDocumentIntent) { @@ -48,7 +53,7 @@ abstract class MyViewPagerFragment(context: Context, attributeSet: AttributeSet) this.isCreateDocumentIntent = isCreateDocumentIntent val fabIcon = context.resources.getColoredDrawableWithColor(iconId, context.getProperPrimaryColor().getContrastColor()) - items_fab?.setImageDrawable(fabIcon) + innerBinding.itemsFab?.setImageDrawable(fabIcon) } fun handleFileDeleting(files: ArrayList, hasFolder: Boolean) { @@ -90,4 +95,20 @@ abstract class MyViewPagerFragment(context: Context, attributeSet: AttributeSet) abstract fun refreshFragment() abstract fun searchQueryChanged(text: String) + + interface InnerBinding { + val itemsFab: MyFloatingActionButton? + } + + class ItemsInnerBinding(val binding: ItemsFragmentBinding) : InnerBinding { + override val itemsFab: MyFloatingActionButton = binding.itemsFab + } + + class RecentsInnerBinding(val binding: RecentsFragmentBinding) : InnerBinding { + override val itemsFab: MyFloatingActionButton? = null + } + + class StorageInnerBinding(val binding: StorageFragmentBinding) : InnerBinding { + override val itemsFab: MyFloatingActionButton? = null + } } diff --git a/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/fragments/RecentsFragment.kt b/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/fragments/RecentsFragment.kt index 5b9778fb..ee7f5cff 100644 --- a/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/fragments/RecentsFragment.kt +++ b/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/fragments/RecentsFragment.kt @@ -17,25 +17,31 @@ import com.simplemobiletools.commons.views.MyRecyclerView import com.simplemobiletools.filemanager.pro.activities.MainActivity import com.simplemobiletools.filemanager.pro.activities.SimpleActivity import com.simplemobiletools.filemanager.pro.adapters.ItemsAdapter +import com.simplemobiletools.filemanager.pro.databinding.RecentsFragmentBinding import com.simplemobiletools.filemanager.pro.extensions.config import com.simplemobiletools.filemanager.pro.helpers.MAX_COLUMN_COUNT import com.simplemobiletools.filemanager.pro.interfaces.ItemOperationsListener import com.simplemobiletools.filemanager.pro.models.ListItem -import kotlinx.android.synthetic.main.recents_fragment.view.recents_list -import kotlinx.android.synthetic.main.recents_fragment.view.recents_placeholder -import kotlinx.android.synthetic.main.recents_fragment.view.recents_swipe_refresh import java.io.File -class RecentsFragment(context: Context, attributeSet: AttributeSet) : MyViewPagerFragment(context, attributeSet), ItemOperationsListener { +class RecentsFragment(context: Context, attributeSet: AttributeSet) : MyViewPagerFragment(context, attributeSet), + ItemOperationsListener { private val RECENTS_LIMIT = 50 private var filesIgnoringSearch = ArrayList() private var lastSearchedText = "" private var zoomListener: MyRecyclerView.MyZoomListener? = null + private lateinit var binding: RecentsFragmentBinding + + override fun onFinishInflate() { + super.onFinishInflate() + binding = RecentsFragmentBinding.bind(this) + innerBinding = RecentsInnerBinding(binding) + } override fun setupFragment(activity: SimpleActivity) { if (this.activity == null) { this.activity = activity - recents_swipe_refresh.setOnRefreshListener { refreshFragment() } + binding.recentsSwipeRefresh.setOnRefreshListener { refreshFragment() } } refreshFragment() @@ -44,9 +50,11 @@ class RecentsFragment(context: Context, attributeSet: AttributeSet) : MyViewPage override fun refreshFragment() { ensureBackgroundThread { getRecents { recents -> - recents_swipe_refresh?.isRefreshing = false - recents_list.beVisibleIf(recents.isNotEmpty()) - recents_placeholder.beVisibleIf(recents.isEmpty()) + binding.apply { + recentsSwipeRefresh?.isRefreshing = false + recentsList.beVisibleIf(recents.isNotEmpty()) + recentsPlaceholder.beVisibleIf(recents.isEmpty()) + } filesIgnoringSearch = recents addItems(recents, false) @@ -58,24 +66,24 @@ class RecentsFragment(context: Context, attributeSet: AttributeSet) : MyViewPage } private fun addItems(recents: ArrayList, forceRefresh: Boolean) { - if (!forceRefresh && recents.hashCode() == (recents_list.adapter as? ItemsAdapter)?.listItems.hashCode()) { + if (!forceRefresh && recents.hashCode() == (binding.recentsList.adapter as? ItemsAdapter)?.listItems.hashCode()) { return } - ItemsAdapter(activity as SimpleActivity, recents, this, recents_list, isPickMultipleIntent, recents_swipe_refresh, false) { + ItemsAdapter(activity as SimpleActivity, recents, this, binding.recentsList, isPickMultipleIntent, binding.recentsSwipeRefresh, false) { clickedPath((it as FileDirItem).path) }.apply { setupZoomListener(zoomListener) - recents_list.adapter = this + binding.recentsList.adapter = this } if (context.areSystemAnimationsEnabled) { - recents_list.scheduleLayoutAnimation() + binding.recentsList.scheduleLayoutAnimation() } } override fun onResume(textColor: Int) { - recents_placeholder.setTextColor(textColor) + binding.recentsPlaceholder.setTextColor(textColor) getRecyclerAdapter()?.apply { updatePrimaryColor() @@ -83,7 +91,7 @@ class RecentsFragment(context: Context, attributeSet: AttributeSet) : MyViewPage initDrawables() } - recents_swipe_refresh.isEnabled = lastSearchedText.isEmpty() && activity?.config?.enablePullToRefresh != false + binding.recentsSwipeRefresh.isEnabled = lastSearchedText.isEmpty() && activity?.config?.enablePullToRefresh != false } private fun setupLayoutManager() { @@ -95,26 +103,26 @@ class RecentsFragment(context: Context, attributeSet: AttributeSet) : MyViewPage setupListLayoutManager() } - val oldItems = (recents_list.adapter as? ItemsAdapter)?.listItems?.toMutableList() as ArrayList - recents_list.adapter = null + val oldItems = (binding.recentsList.adapter as? ItemsAdapter)?.listItems?.toMutableList() as ArrayList + binding.recentsList.adapter = null initZoomListener() addItems(oldItems, true) } private fun setupGridLayoutManager() { - val layoutManager = recents_list.layoutManager as MyGridLayoutManager + val layoutManager = binding.recentsList.layoutManager as MyGridLayoutManager layoutManager.spanCount = context?.config?.fileColumnCnt ?: 3 } private fun setupListLayoutManager() { - val layoutManager = recents_list.layoutManager as MyGridLayoutManager + val layoutManager = binding.recentsList.layoutManager as MyGridLayoutManager layoutManager.spanCount = 1 zoomListener = null } private fun initZoomListener() { if (context?.config?.getFolderViewType("") == VIEW_TYPE_GRID) { - val layoutManager = recents_list.layoutManager as MyGridLayoutManager + val layoutManager = binding.recentsList.layoutManager as MyGridLayoutManager zoomListener = object : MyRecyclerView.MyZoomListener { override fun zoomIn() { if (layoutManager.spanCount > 1) { @@ -187,7 +195,7 @@ class RecentsFragment(context: Context, attributeSet: AttributeSet) : MyViewPage } } - private fun getRecyclerAdapter() = recents_list.adapter as? ItemsAdapter + private fun getRecyclerAdapter() = binding.recentsList.adapter as? ItemsAdapter override fun toggleFilenameVisibility() { getRecyclerAdapter()?.updateDisplayFilenamesInGrid() @@ -208,7 +216,7 @@ class RecentsFragment(context: Context, attributeSet: AttributeSet) : MyViewPage } override fun columnCountChanged() { - (recents_list.layoutManager as MyGridLayoutManager).spanCount = context!!.config.fileColumnCnt + (binding.recentsList.layoutManager as MyGridLayoutManager).spanCount = context!!.config.fileColumnCnt (activity as? MainActivity)?.refreshMenuItems() getRecyclerAdapter()?.apply { notifyItemRangeChanged(0, listItems.size) @@ -234,9 +242,11 @@ class RecentsFragment(context: Context, attributeSet: AttributeSet) : MyViewPage override fun searchQueryChanged(text: String) { lastSearchedText = text val filtered = filesIgnoringSearch.filter { it.mName.contains(text, true) }.toMutableList() as ArrayList - (recents_list.adapter as? ItemsAdapter)?.updateItems(filtered, text) - recents_placeholder.beVisibleIf(filtered.isEmpty()) - recents_swipe_refresh.isEnabled = lastSearchedText.isEmpty() && activity?.config?.enablePullToRefresh != false + binding.apply { + (recentsList.adapter as? ItemsAdapter)?.updateItems(filtered, text) + recentsPlaceholder.beVisibleIf(filtered.isEmpty()) + recentsSwipeRefresh.isEnabled = lastSearchedText.isEmpty() && activity?.config?.enablePullToRefresh != false + } } override fun finishActMode() { diff --git a/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/fragments/StorageFragment.kt b/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/fragments/StorageFragment.kt index 7ef6187b..6db802c8 100644 --- a/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/fragments/StorageFragment.kt +++ b/app/src/main/kotlin/com/simplemobiletools/filemanager/pro/fragments/StorageFragment.kt @@ -21,28 +21,36 @@ import com.simplemobiletools.filemanager.pro.R import com.simplemobiletools.filemanager.pro.activities.MimeTypesActivity import com.simplemobiletools.filemanager.pro.activities.SimpleActivity import com.simplemobiletools.filemanager.pro.adapters.ItemsAdapter +import com.simplemobiletools.filemanager.pro.databinding.StorageFragmentBinding import com.simplemobiletools.filemanager.pro.extensions.config import com.simplemobiletools.filemanager.pro.extensions.formatSizeThousand import com.simplemobiletools.filemanager.pro.helpers.* import com.simplemobiletools.filemanager.pro.interfaces.ItemOperationsListener import com.simplemobiletools.filemanager.pro.models.ListItem -import kotlinx.android.synthetic.main.storage_fragment.view.* import java.util.* -class StorageFragment(context: Context, attributeSet: AttributeSet) : MyViewPagerFragment(context, attributeSet), ItemOperationsListener { +class StorageFragment(context: Context, attributeSet: AttributeSet) : MyViewPagerFragment(context, attributeSet), + ItemOperationsListener { private val SIZE_DIVIDER = 100000 private var allDeviceListItems = ArrayList() private var lastSearchedText = "" + private lateinit var binding: StorageFragmentBinding + + override fun onFinishInflate() { + super.onFinishInflate() + binding = StorageFragmentBinding.bind(this) + innerBinding = StorageInnerBinding(binding) + } override fun setupFragment(activity: SimpleActivity) { if (this.activity == null) { this.activity = activity } - total_space.text = String.format(context.getString(R.string.total_storage), "…") + binding.totalSpace.text = String.format(context.getString(R.string.total_storage), "…") getSizes() - free_space_holder.setOnClickListener { + binding.freeSpaceHolder.setOnClickListener { try { val storageSettingsIntent = Intent(Settings.ACTION_INTERNAL_STORAGE_SETTINGS) activity.startActivity(storageSettingsIntent) @@ -51,12 +59,14 @@ class StorageFragment(context: Context, attributeSet: AttributeSet) : MyViewPage } } - images_holder.setOnClickListener { launchMimetypeActivity(IMAGES) } - videos_holder.setOnClickListener { launchMimetypeActivity(VIDEOS) } - audio_holder.setOnClickListener { launchMimetypeActivity(AUDIO) } - documents_holder.setOnClickListener { launchMimetypeActivity(DOCUMENTS) } - archives_holder.setOnClickListener { launchMimetypeActivity(ARCHIVES) } - others_holder.setOnClickListener { launchMimetypeActivity(OTHERS) } + binding.apply { + imagesHolder.setOnClickListener { launchMimetypeActivity(IMAGES) } + videosHolder.setOnClickListener { launchMimetypeActivity(VIDEOS) } + audioHolder.setOnClickListener { launchMimetypeActivity(AUDIO) } + documentsHolder.setOnClickListener { launchMimetypeActivity(DOCUMENTS) } + archivesHolder.setOnClickListener { launchMimetypeActivity(ARCHIVES) } + othersHolder.setOnClickListener { launchMimetypeActivity(OTHERS) } + } Handler().postDelayed({ refreshFragment() @@ -65,39 +75,42 @@ class StorageFragment(context: Context, attributeSet: AttributeSet) : MyViewPage override fun onResume(textColor: Int) { getSizes() - context.updateTextColors(storage_fragment) + context.updateTextColors(binding.root) - val properPrimaryColor = context.getProperPrimaryColor() - main_storage_usage_progressbar.setIndicatorColor(properPrimaryColor) - main_storage_usage_progressbar.trackColor = properPrimaryColor.adjustAlpha(LOWER_ALPHA) + binding.apply { + val properPrimaryColor = context.getProperPrimaryColor() + mainStorageUsageProgressbar.setIndicatorColor(properPrimaryColor) + mainStorageUsageProgressbar.trackColor = properPrimaryColor.adjustAlpha(LOWER_ALPHA) - val redColor = context.resources.getColor(R.color.md_red_700) - images_progressbar.setIndicatorColor(redColor) - images_progressbar.trackColor = redColor.adjustAlpha(LOWER_ALPHA) + val redColor = context.resources.getColor(R.color.md_red_700) + imagesProgressbar.setIndicatorColor(redColor) + imagesProgressbar.trackColor = redColor.adjustAlpha(LOWER_ALPHA) - val greenColor = context.resources.getColor(R.color.md_green_700) - videos_progressbar.setIndicatorColor(greenColor) - videos_progressbar.trackColor = greenColor.adjustAlpha(LOWER_ALPHA) + val greenColor = context.resources.getColor(R.color.md_green_700) + videosProgressbar.setIndicatorColor(greenColor) + videosProgressbar.trackColor = greenColor.adjustAlpha(LOWER_ALPHA) - val lightBlueColor = context.resources.getColor(R.color.md_light_blue_700) - audio_progressbar.setIndicatorColor(lightBlueColor) - audio_progressbar.trackColor = lightBlueColor.adjustAlpha(LOWER_ALPHA) + val lightBlueColor = context.resources.getColor(R.color.md_light_blue_700) + audioProgressbar.setIndicatorColor(lightBlueColor) + audioProgressbar.trackColor = lightBlueColor.adjustAlpha(LOWER_ALPHA) - val yellowColor = context.resources.getColor(R.color.md_yellow_700) - documents_progressbar.setIndicatorColor(yellowColor) - documents_progressbar.trackColor = yellowColor.adjustAlpha(LOWER_ALPHA) + val yellowColor = context.resources.getColor(R.color.md_yellow_700) + documentsProgressbar.setIndicatorColor(yellowColor) + documentsProgressbar.trackColor = yellowColor.adjustAlpha(LOWER_ALPHA) - val tealColor = context.resources.getColor(R.color.md_teal_700) - archives_progressbar.setIndicatorColor(tealColor) - archives_progressbar.trackColor = tealColor.adjustAlpha(LOWER_ALPHA) + val tealColor = context.resources.getColor(R.color.md_teal_700) + archivesProgressbar.setIndicatorColor(tealColor) + archivesProgressbar.trackColor = tealColor.adjustAlpha(LOWER_ALPHA) - val pinkColor = context.resources.getColor(R.color.md_pink_700) - others_progressbar.setIndicatorColor(pinkColor) - others_progressbar.trackColor = pinkColor.adjustAlpha(LOWER_ALPHA) + val pinkColor = context.resources.getColor(R.color.md_pink_700) + othersProgressbar.setIndicatorColor(pinkColor) + othersProgressbar.trackColor = pinkColor.adjustAlpha(LOWER_ALPHA) + + searchHolder.setBackgroundColor(context.getProperBackgroundColor()) + progressBar.setIndicatorColor(properPrimaryColor) + progressBar.trackColor = properPrimaryColor.adjustAlpha(LOWER_ALPHA) + } - search_holder.setBackgroundColor(context.getProperBackgroundColor()) - progress_bar.setIndicatorColor(properPrimaryColor) - progress_bar.trackColor = properPrimaryColor.adjustAlpha(LOWER_ALPHA) } private fun launchMimetypeActivity(mimetype: String) { @@ -116,31 +129,33 @@ class StorageFragment(context: Context, attributeSet: AttributeSet) : MyViewPage getMainStorageStats(context) val filesSize = getSizesByMimeType() - val imagesSize = filesSize[IMAGES]!! - val videosSize = filesSize[VIDEOS]!! - val audioSize = filesSize[AUDIO]!! - val documentsSize = filesSize[DOCUMENTS]!! - val archivesSize = filesSize[ARCHIVES]!! - val othersSize = filesSize[OTHERS]!! + val fileSizeImages = filesSize[IMAGES]!! + val fileSizeVideos = filesSize[VIDEOS]!! + val fileSizeAudios = filesSize[AUDIO]!! + val fileSizeDocuments = filesSize[DOCUMENTS]!! + val fileSizeArchives = filesSize[ARCHIVES]!! + val fileSizeOthers = filesSize[OTHERS]!! post { - images_size.text = imagesSize.formatSize() - images_progressbar.progress = (imagesSize / SIZE_DIVIDER).toInt() + binding.apply { + imagesSize.text = fileSizeImages.formatSize() + imagesProgressbar.progress = (fileSizeImages / SIZE_DIVIDER).toInt() - videos_size.text = videosSize.formatSize() - videos_progressbar.progress = (videosSize / SIZE_DIVIDER).toInt() + videosSize.text = fileSizeVideos.formatSize() + videosProgressbar.progress = (fileSizeVideos / SIZE_DIVIDER).toInt() - audio_size.text = audioSize.formatSize() - audio_progressbar.progress = (audioSize / SIZE_DIVIDER).toInt() + audioSize.text = fileSizeAudios.formatSize() + audioProgressbar.progress = (fileSizeAudios / SIZE_DIVIDER).toInt() - documents_size.text = documentsSize.formatSize() - documents_progressbar.progress = (documentsSize / SIZE_DIVIDER).toInt() + documentsSize.text = fileSizeDocuments.formatSize() + documentsProgressbar.progress = (fileSizeDocuments / SIZE_DIVIDER).toInt() - archives_size.text = archivesSize.formatSize() - archives_progressbar.progress = (archivesSize / SIZE_DIVIDER).toInt() + archivesSize.text = fileSizeArchives.formatSize() + archivesProgressbar.progress = (fileSizeArchives / SIZE_DIVIDER).toInt() - others_size.text = othersSize.formatSize() - others_progressbar.progress = (othersSize / SIZE_DIVIDER).toInt() + othersSize.text = fileSizeOthers.formatSize() + othersProgressbar.progress = (fileSizeOthers / SIZE_DIVIDER).toInt() + } } } } @@ -217,23 +232,25 @@ class StorageFragment(context: Context, attributeSet: AttributeSet) : MyViewPage // internal storage val storageStatsManager = context.getSystemService(AppCompatActivity.STORAGE_STATS_SERVICE) as StorageStatsManager val uuid = StorageManager.UUID_DEFAULT - val totalSpace = storageStatsManager.getTotalBytes(uuid) - val freeSpace = storageStatsManager.getFreeBytes(uuid) + val totalStorageSpace = storageStatsManager.getTotalBytes(uuid) + val freeStorageSpace = storageStatsManager.getFreeBytes(uuid) post { - arrayOf( - main_storage_usage_progressbar, images_progressbar, videos_progressbar, audio_progressbar, documents_progressbar, - archives_progressbar, others_progressbar - ).forEach { - it.max = (totalSpace / SIZE_DIVIDER).toInt() + binding.apply { + arrayOf( + mainStorageUsageProgressbar, imagesProgressbar, videosProgressbar, audioProgressbar, documentsProgressbar, + archivesProgressbar, othersProgressbar + ).forEach { + it.max = (totalStorageSpace / SIZE_DIVIDER).toInt() + } + + mainStorageUsageProgressbar.progress = ((totalStorageSpace - freeStorageSpace) / SIZE_DIVIDER).toInt() + + mainStorageUsageProgressbar.beVisible() + freeSpaceValue.text = freeStorageSpace.formatSizeThousand() + totalSpace.text = String.format(context.getString(R.string.total_storage), totalStorageSpace.formatSizeThousand()) + freeSpaceLabel.beVisible() } - - main_storage_usage_progressbar.progress = ((totalSpace - freeSpace) / SIZE_DIVIDER).toInt() - - main_storage_usage_progressbar.beVisible() - free_space_value.text = freeSpace.formatSizeThousand() - total_space.text = String.format(context.getString(R.string.total_storage), totalSpace.formatSizeThousand()) - free_space_label.beVisible() } } else { // sd card @@ -245,41 +262,42 @@ class StorageFragment(context: Context, attributeSet: AttributeSet) : MyViewPage override fun searchQueryChanged(text: String) { lastSearchedText = text - - if (text.isNotEmpty()) { - if (search_holder.alpha < 1f) { - search_holder.fadeIn() - } - } else { - search_holder.animate().alpha(0f).setDuration(SHORT_ANIMATION_DURATION).withEndAction { - search_holder.beGone() - (search_results_list.adapter as? ItemsAdapter)?.updateItems(allDeviceListItems, text) - }.start() - } - - if (text.length == 1) { - search_results_list.beGone() - search_placeholder.beVisible() - search_placeholder_2.beVisible() - hideProgressBar() - } else if (text.isEmpty()) { - search_results_list.beGone() - hideProgressBar() - } else { - showProgressBar() - ensureBackgroundThread { - val start = System.currentTimeMillis() - val filtered = allDeviceListItems.filter { it.mName.contains(text, true) }.toMutableList() as ArrayList - if (lastSearchedText != text) { - return@ensureBackgroundThread + binding.apply { + if (text.isNotEmpty()) { + if (searchHolder.alpha < 1f) { + searchHolder.fadeIn() } + } else { + searchHolder.animate().alpha(0f).setDuration(SHORT_ANIMATION_DURATION).withEndAction { + searchHolder.beGone() + (searchResultsList.adapter as? ItemsAdapter)?.updateItems(allDeviceListItems, text) + }.start() + } - (context as? Activity)?.runOnUiThread { - (search_results_list.adapter as? ItemsAdapter)?.updateItems(filtered, text) - search_results_list.beVisible() - search_placeholder.beVisibleIf(filtered.isEmpty()) - search_placeholder_2.beGone() - hideProgressBar() + if (text.length == 1) { + searchResultsList.beGone() + searchPlaceholder.beVisible() + searchPlaceholder2.beVisible() + hideProgressBar() + } else if (text.isEmpty()) { + searchResultsList.beGone() + hideProgressBar() + } else { + showProgressBar() + ensureBackgroundThread { + val start = System.currentTimeMillis() + val filtered = allDeviceListItems.filter { it.mName.contains(text, true) }.toMutableList() as ArrayList + if (lastSearchedText != text) { + return@ensureBackgroundThread + } + + (context as? Activity)?.runOnUiThread { + (searchResultsList.adapter as? ItemsAdapter)?.updateItems(filtered, text) + searchResultsList.beVisible() + searchPlaceholder.beVisibleIf(filtered.isEmpty()) + searchPlaceholder2.beGone() + hideProgressBar() + } } } } @@ -294,25 +312,25 @@ class StorageFragment(context: Context, attributeSet: AttributeSet) : MyViewPage setupListLayoutManager() } - search_results_list.adapter = null + binding.searchResultsList.adapter = null addItems() } private fun setupGridLayoutManager() { - val layoutManager = search_results_list.layoutManager as MyGridLayoutManager + val layoutManager = binding.searchResultsList.layoutManager as MyGridLayoutManager layoutManager.spanCount = context?.config?.fileColumnCnt ?: 3 } private fun setupListLayoutManager() { - val layoutManager = search_results_list.layoutManager as MyGridLayoutManager + val layoutManager = binding.searchResultsList.layoutManager as MyGridLayoutManager layoutManager.spanCount = 1 } private fun addItems() { - ItemsAdapter(context as SimpleActivity, ArrayList(), this, search_results_list, false, null, false) { + ItemsAdapter(context as SimpleActivity, ArrayList(), this, binding.searchResultsList, false, null, false) { clickedPath((it as FileDirItem).path) }.apply { - search_results_list.adapter = this + binding.searchResultsList.adapter = this } } @@ -367,14 +385,14 @@ class StorageFragment(context: Context, attributeSet: AttributeSet) : MyViewPage } private fun showProgressBar() { - progress_bar.show() + binding.progressBar.show() } private fun hideProgressBar() { - progress_bar.hide() + binding.progressBar.hide() } - private fun getRecyclerAdapter() = search_results_list.adapter as? ItemsAdapter + private fun getRecyclerAdapter() = binding.searchResultsList.adapter as? ItemsAdapter override fun refreshFragment() { ensureBackgroundThread { @@ -403,7 +421,7 @@ class StorageFragment(context: Context, attributeSet: AttributeSet) : MyViewPage } override fun columnCountChanged() { - (search_results_list.layoutManager as MyGridLayoutManager).spanCount = context!!.config.fileColumnCnt + (binding.searchResultsList.layoutManager as MyGridLayoutManager).spanCount = context!!.config.fileColumnCnt getRecyclerAdapter()?.apply { notifyItemRangeChanged(0, listItems.size) } diff --git a/build.gradle b/build.gradle index 5dc760b4..36758110 100644 --- a/build.gradle +++ b/build.gradle @@ -1,7 +1,7 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { - ext.kotlin_version = '1.7.10' + ext.kotlin_version = '1.9.0' repositories { google() @@ -9,7 +9,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:7.3.1' + classpath 'com.android.tools.build:gradle:8.1.0' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" // NOTE: Do not place your application dependencies here; they belong diff --git a/gradle.properties b/gradle.properties index 9e6fce10..28d72319 100644 --- a/gradle.properties +++ b/gradle.properties @@ -10,8 +10,9 @@ # Specifies the JVM arguments used for the daemon process. # The setting is particularly useful for tweaking memory settings. android.enableJetifier=true +android.nonTransitiveRClass=false android.useAndroidX=true -org.gradle.jvmargs=-Xmx1536m +org.gradle.jvmargs=-Xmx4g # When configured, Gradle will run in incubating parallel mode. # This option should only be used with decoupled projects. More details, visit diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 4dd85735..2f785356 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.2.1-bin.zip