diff --git a/build.gradle b/build.gradle index 47c960af..37f34db0 100644 --- a/build.gradle +++ b/build.gradle @@ -77,6 +77,9 @@ android { } def keystorePropertiesFile = rootProject.file('keystore.properties') + buildFeatures { + viewBinding true + } if (keystorePropertiesFile.exists()) { def keystoreProperties = new Properties() keystoreProperties.load(keystorePropertiesFile.newDataInputStream()) @@ -129,7 +132,7 @@ dependencies { implementation 'com.fasterxml.jackson.core:jackson-core:2.13.0' implementation 'com.squareup.okhttp3:okhttp:5.0.0-alpha.2' implementation 'com.github.topjohnwu.libsu:core:3.1.2' - implementation "androidx.room:room-runtime:2.3.0" - implementation "androidx.room:room-ktx:2.3.0" - kapt "androidx.room:room-compiler:2.3.0" + implementation 'androidx.room:room-runtime:2.3.0' + implementation 'androidx.room:room-ktx:2.3.0' + kapt 'androidx.room:room-compiler:2.3.0' } diff --git a/src/main/kotlin/com/looker/droidify/screen/EditRepositoryFragment.kt b/src/main/kotlin/com/looker/droidify/screen/EditRepositoryFragment.kt index 5e15f3e0..99bec4f3 100644 --- a/src/main/kotlin/com/looker/droidify/screen/EditRepositoryFragment.kt +++ b/src/main/kotlin/com/looker/droidify/screen/EditRepositoryFragment.kt @@ -15,11 +15,10 @@ import android.view.View import android.view.ViewGroup import androidx.appcompat.app.AlertDialog import androidx.fragment.app.DialogFragment -import com.google.android.material.circularreveal.CircularRevealFrameLayout import com.google.android.material.dialog.MaterialAlertDialogBuilder -import com.google.android.material.textfield.TextInputEditText import com.looker.droidify.R import com.looker.droidify.database.Database +import com.looker.droidify.databinding.EditRepositoryBinding import com.looker.droidify.entity.Repository import com.looker.droidify.network.Downloader import com.looker.droidify.service.Connection @@ -27,7 +26,6 @@ import com.looker.droidify.service.SyncService import com.looker.droidify.utility.RxUtils import com.looker.droidify.utility.Utils import com.looker.droidify.utility.extension.resources.getColorFromAttr -import com.looker.droidify.utility.extension.resources.inflate import com.looker.droidify.utility.extension.text.nullIfEmpty import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers import io.reactivex.rxjava3.core.Observable @@ -44,6 +42,9 @@ import kotlin.collections.ArrayList import kotlin.math.min class EditRepositoryFragment() : ScreenFragment() { + + private lateinit var editRepositoryBinding: EditRepositoryBinding + companion object { private const val EXTRA_REPOSITORY_ID = "repositoryId" @@ -56,14 +57,14 @@ class EditRepositoryFragment() : ScreenFragment() { } } - private class Layout(view: View) { - val address = view.findViewById(R.id.address)!! - val addressMirror = view.findViewById(R.id.address_mirror)!! - val fingerprint = view.findViewById(R.id.fingerprint)!! - val username = view.findViewById(R.id.username)!! - val password = view.findViewById(R.id.password)!! - val overlay = view.findViewById(R.id.overlay)!! - val skip = view.findViewById(R.id.skip)!! + private class Layout(view: EditRepositoryBinding) { + val address = view.address + val addressMirror = view.addressMirror + val fingerprint = view.fingerprint + val username = view.username + val password = view.password + val overlay = view.overlay + val skip = view.skip } private val repositoryId: Long? @@ -85,6 +86,9 @@ class EditRepositoryFragment() : ScreenFragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) + + editRepositoryBinding = EditRepositoryBinding.inflate(layoutInflater) + syncConnection.bind(requireContext()) screenActivity.onToolbarCreated(toolbar) @@ -99,14 +103,14 @@ class EditRepositoryFragment() : ScreenFragment() { true } - val content = view.findViewById(R.id.fragment_content)!! + val content = fragmentBinding.fragmentContent errorColorFilter = PorterDuffColorFilter( content.context .getColorFromAttr(R.attr.colorError).defaultColor, PorterDuff.Mode.SRC_IN ) - content.addView(content.inflate(R.layout.edit_repository)) - val layout = Layout(content) + content.addView(editRepositoryBinding.root) + val layout = Layout(editRepositoryBinding) this.layout = layout layout.fingerprint.hint = generateSequence { "FF" }.take(32).joinToString(separator = " ") diff --git a/src/main/kotlin/com/looker/droidify/screen/ProductFragment.kt b/src/main/kotlin/com/looker/droidify/screen/ProductFragment.kt index 19840369..97cadc8e 100644 --- a/src/main/kotlin/com/looker/droidify/screen/ProductFragment.kt +++ b/src/main/kotlin/com/looker/droidify/screen/ProductFragment.kt @@ -15,7 +15,6 @@ import androidx.lifecycle.lifecycleScope import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView -import com.google.android.material.circularreveal.CircularRevealFrameLayout import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.looker.droidify.R import com.looker.droidify.content.ProductPreferences @@ -108,7 +107,7 @@ class ProductFragment() : ScreenFragment(), ProductAdapter.Callbacks { } } - val content = view.findViewById(R.id.fragment_content)!! + val content = fragmentBinding.fragmentContent content.addView(RecyclerView(content.context).apply { id = android.R.id.list val columns = (resources.configuration.screenWidthDp / 120).coerceIn(3, 5) diff --git a/src/main/kotlin/com/looker/droidify/screen/RepositoriesFragment.kt b/src/main/kotlin/com/looker/droidify/screen/RepositoriesFragment.kt index e2077156..8054893a 100644 --- a/src/main/kotlin/com/looker/droidify/screen/RepositoriesFragment.kt +++ b/src/main/kotlin/com/looker/droidify/screen/RepositoriesFragment.kt @@ -8,7 +8,6 @@ import android.view.View import android.view.ViewGroup import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView -import com.google.android.material.circularreveal.CircularRevealFrameLayout import com.looker.droidify.R import com.looker.droidify.database.CursorOwner import com.looker.droidify.service.Connection @@ -25,8 +24,8 @@ class RepositoriesFragment : ScreenFragment(), CursorOwner.Callback { container: ViewGroup?, savedInstanceState: Bundle? ): View { - val view = inflater.inflate(R.layout.fragment, container, false).apply { - val content = findViewById(R.id.fragment_content)!! + val view = fragmentBinding.root.apply { + val content = fragmentBinding.fragmentContent content.addView(RecyclerView(content.context).apply { id = android.R.id.list layoutManager = LinearLayoutManager(context) @@ -40,7 +39,7 @@ class RepositoriesFragment : ScreenFragment(), CursorOwner.Callback { recyclerView = this }) } - this.toolbar = view.findViewById(R.id.toolbar) + this.toolbar = fragmentBinding.toolbar return view } diff --git a/src/main/kotlin/com/looker/droidify/screen/RepositoryFragment.kt b/src/main/kotlin/com/looker/droidify/screen/RepositoryFragment.kt index 19d06b75..cc555336 100644 --- a/src/main/kotlin/com/looker/droidify/screen/RepositoryFragment.kt +++ b/src/main/kotlin/com/looker/droidify/screen/RepositoryFragment.kt @@ -10,10 +10,10 @@ import android.view.View import android.view.ViewGroup import androidx.appcompat.widget.LinearLayoutCompat import androidx.core.widget.NestedScrollView -import com.google.android.material.circularreveal.CircularRevealFrameLayout import com.google.android.material.textview.MaterialTextView import com.looker.droidify.R import com.looker.droidify.database.Database +import com.looker.droidify.databinding.TitleTextItemBinding import com.looker.droidify.service.Connection import com.looker.droidify.service.SyncService import com.looker.droidify.utility.Utils @@ -26,6 +26,9 @@ import io.reactivex.rxjava3.disposables.Disposable import java.util.* class RepositoryFragment() : ScreenFragment() { + + private lateinit var titleBinding: TitleTextItemBinding + companion object { private const val EXTRA_REPOSITORY_ID = "repositoryId" } @@ -46,6 +49,7 @@ class RepositoryFragment() : ScreenFragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) + titleBinding = TitleTextItemBinding.inflate(layoutInflater) syncConnection.bind(requireContext()) repositoryDisposable = Observable.just(Unit) @@ -76,7 +80,7 @@ class RepositoryFragment() : ScreenFragment() { } } - val content = view.findViewById(R.id.fragment_content)!! + val content = fragmentBinding.fragmentContent val scroll = NestedScrollView(content.context) scroll.id = android.R.id.list scroll.isFillViewport = true diff --git a/src/main/kotlin/com/looker/droidify/screen/ScreenFragment.kt b/src/main/kotlin/com/looker/droidify/screen/ScreenFragment.kt index d9365b53..e73583eb 100644 --- a/src/main/kotlin/com/looker/droidify/screen/ScreenFragment.kt +++ b/src/main/kotlin/com/looker/droidify/screen/ScreenFragment.kt @@ -7,22 +7,28 @@ import android.view.ViewGroup import androidx.appcompat.widget.Toolbar import com.google.android.material.appbar.AppBarLayout import com.google.android.material.appbar.CollapsingToolbarLayout -import com.looker.droidify.R +import com.looker.droidify.databinding.FragmentBinding open class ScreenFragment : BaseFragment() { + lateinit var fragmentBinding: FragmentBinding + lateinit var toolbar: Toolbar lateinit var collapsingToolbar: CollapsingToolbarLayout lateinit var appBar: AppBarLayout + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + fragmentBinding = FragmentBinding.inflate(layoutInflater) + } + override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { - val view = inflater.inflate(R.layout.fragment, container, false) - this.toolbar = view.findViewById(R.id.toolbar) - this.collapsingToolbar = view.findViewById(R.id.collapsing_toolbar) - this.appBar = view.findViewById(R.id.appbar_layout) - return view + this.toolbar = fragmentBinding.toolbar + this.collapsingToolbar = fragmentBinding.collapsingToolbar + this.appBar = fragmentBinding.appbarLayout + return fragmentBinding.root } } diff --git a/src/main/kotlin/com/looker/droidify/screen/SettingsFragment.kt b/src/main/kotlin/com/looker/droidify/screen/SettingsFragment.kt index 7b9c83e7..8305e181 100644 --- a/src/main/kotlin/com/looker/droidify/screen/SettingsFragment.kt +++ b/src/main/kotlin/com/looker/droidify/screen/SettingsFragment.kt @@ -23,21 +23,24 @@ import com.google.android.material.textview.MaterialTextView import com.looker.droidify.BuildConfig import com.looker.droidify.R import com.looker.droidify.content.Preferences +import com.looker.droidify.databinding.PreferenceItemBinding import com.looker.droidify.utility.extension.resources.* import com.topjohnwu.superuser.Shell import io.reactivex.rxjava3.disposables.Disposable class SettingsFragment : ScreenFragment() { + + private lateinit var preferenceBinding: PreferenceItemBinding private val preferences = mutableMapOf, Preference<*>>() private var disposable: Disposable? = null override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - + preferenceBinding = PreferenceItemBinding.inflate(layoutInflater) screenActivity.onToolbarCreated(toolbar) toolbar.setTitle(R.string.settings) - val content = view.findViewById(R.id.fragment_content)!! + val content = fragmentBinding.fragmentContent val scroll = NestedScrollView(content.context) scroll.id = R.id.preferences_list scroll.isFillViewport = true diff --git a/src/main/kotlin/com/looker/droidify/screen/TabsFragment.kt b/src/main/kotlin/com/looker/droidify/screen/TabsFragment.kt index d8a48aa2..2612ce84 100644 --- a/src/main/kotlin/com/looker/droidify/screen/TabsFragment.kt +++ b/src/main/kotlin/com/looker/droidify/screen/TabsFragment.kt @@ -12,14 +12,12 @@ import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import androidx.viewpager2.adapter.FragmentStateAdapter import androidx.viewpager2.widget.ViewPager2 -import com.google.android.material.circularreveal.CircularRevealFrameLayout -import com.google.android.material.imageview.ShapeableImageView -import com.google.android.material.tabs.TabLayout import com.google.android.material.tabs.TabLayoutMediator import com.google.android.material.textview.MaterialTextView import com.looker.droidify.R import com.looker.droidify.content.Preferences import com.looker.droidify.database.Database +import com.looker.droidify.databinding.TabsToolbarBinding import com.looker.droidify.entity.ProductItem import com.looker.droidify.service.Connection import com.looker.droidify.service.SyncService @@ -37,6 +35,9 @@ import io.reactivex.rxjava3.schedulers.Schedulers import kotlin.math.* class TabsFragment : ScreenFragment() { + + private lateinit var tabsBinding: TabsToolbarBinding + companion object { private const val STATE_SEARCH_FOCUSED = "searchFocused" private const val STATE_SEARCH_QUERY = "searchQuery" @@ -45,12 +46,12 @@ class TabsFragment : ScreenFragment() { private const val STATE_SECTION = "section" } - private class Layout(view: View) { - val tabs = view.findViewById(R.id.tabs)!! - val sectionLayout = view.findViewById(R.id.section_layout)!! - val sectionChange = view.findViewById(R.id.section_change)!! - val sectionName = view.findViewById(R.id.section_name)!! - val sectionIcon = view.findViewById(R.id.section_icon)!! + private class Layout(view: TabsToolbarBinding) { + val tabs = view.tabs + val sectionLayout = view.sectionLayout + val sectionChange = view.sectionChange + val sectionName = view.sectionName + val sectionIcon = view.sectionIcon } private var searchMenuItem: MenuItem? = null @@ -98,6 +99,11 @@ class TabsFragment : ScreenFragment() { get() = if (host == null) emptySequence() else childFragmentManager.fragments.asSequence().mapNotNull { it as? ProductsFragment } + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + tabsBinding = TabsToolbarBinding.inflate(layoutInflater) + } + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) syncConnection.bind(requireContext()) @@ -177,9 +183,9 @@ class TabsFragment : ScreenFragment() { searchQuery = savedInstanceState?.getString(STATE_SEARCH_QUERY).orEmpty() productFragments.forEach { it.setSearchQuery(searchQuery) } - val toolbarExtra = view.findViewById(R.id.toolbar_extra)!! - toolbarExtra.addView(toolbarExtra.inflate(R.layout.tabs_toolbar)) - val layout = Layout(view) + val toolbarExtra = fragmentBinding.toolbarExtra + toolbarExtra.addView(tabsBinding.root) + val layout = Layout(tabsBinding) this.layout = layout showSections = savedInstanceState?.getByte(STATE_SHOW_SECTIONS)?.toInt() ?: 0 != 0 @@ -198,7 +204,7 @@ class TabsFragment : ScreenFragment() { } } - val content = view.findViewById(R.id.fragment_content)!! + val content = fragmentBinding.fragmentContent viewPager = ViewPager2(content.context).apply { id = R.id.fragment_pager