mirror of
https://github.com/android-password-store/Android-Password-Store
synced 2025-09-04 00:05:08 +00:00
Introduce and switch to FragmentViewBindingDelegate (#797)
Signed-off-by: Harsh Shandilya <me@msfjarvis.dev>
This commit is contained in:
@@ -80,6 +80,7 @@ dependencies {
|
|||||||
implementation deps.androidx.core_ktx
|
implementation deps.androidx.core_ktx
|
||||||
implementation deps.androidx.documentfile
|
implementation deps.androidx.documentfile
|
||||||
implementation deps.androidx.fragment_ktx
|
implementation deps.androidx.fragment_ktx
|
||||||
|
implementation deps.androidx.lifecycle_common
|
||||||
implementation deps.androidx.lifecycle_livedata_ktx
|
implementation deps.androidx.lifecycle_livedata_ktx
|
||||||
implementation deps.androidx.lifecycle_viewmodel_ktx
|
implementation deps.androidx.lifecycle_viewmodel_ktx
|
||||||
implementation deps.androidx.local_broadcast_manager
|
implementation deps.androidx.local_broadcast_manager
|
||||||
|
@@ -33,6 +33,7 @@ import com.zeapo.pwdstore.ui.adapters.PasswordItemRecyclerAdapter
|
|||||||
import com.zeapo.pwdstore.ui.dialogs.ItemCreationBottomSheet
|
import com.zeapo.pwdstore.ui.dialogs.ItemCreationBottomSheet
|
||||||
import com.zeapo.pwdstore.utils.PasswordItem
|
import com.zeapo.pwdstore.utils.PasswordItem
|
||||||
import com.zeapo.pwdstore.utils.PasswordRepository
|
import com.zeapo.pwdstore.utils.PasswordRepository
|
||||||
|
import com.zeapo.pwdstore.utils.viewBinding
|
||||||
import me.zhanghai.android.fastscroll.FastScrollerBuilder
|
import me.zhanghai.android.fastscroll.FastScrollerBuilder
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.util.Stack
|
import java.util.Stack
|
||||||
@@ -44,10 +45,9 @@ class PasswordFragment : Fragment() {
|
|||||||
|
|
||||||
private var recyclerViewStateToRestore: Parcelable? = null
|
private var recyclerViewStateToRestore: Parcelable? = null
|
||||||
private var actionMode: ActionMode? = null
|
private var actionMode: ActionMode? = null
|
||||||
private var _binding: PasswordRecyclerViewBinding? = null
|
|
||||||
|
|
||||||
private val model: SearchableRepositoryViewModel by activityViewModels()
|
private val model: SearchableRepositoryViewModel by activityViewModels()
|
||||||
private val binding get() = _binding!!
|
private val binding by viewBinding(PasswordRecyclerViewBinding::bind)
|
||||||
|
|
||||||
private fun requireStore() = requireActivity() as PasswordStore
|
private fun requireStore() = requireActivity() as PasswordStore
|
||||||
|
|
||||||
@@ -56,7 +56,6 @@ class PasswordFragment : Fragment() {
|
|||||||
container: ViewGroup?,
|
container: ViewGroup?,
|
||||||
savedInstanceState: Bundle?
|
savedInstanceState: Bundle?
|
||||||
): View? {
|
): View? {
|
||||||
_binding = PasswordRecyclerViewBinding.inflate(inflater, container, false)
|
|
||||||
settings = PreferenceManager.getDefaultSharedPreferences(requireContext())
|
settings = PreferenceManager.getDefaultSharedPreferences(requireContext())
|
||||||
initializePasswordList()
|
initializePasswordList()
|
||||||
binding.fab.setOnClickListener {
|
binding.fab.setOnClickListener {
|
||||||
@@ -149,11 +148,6 @@ class PasswordFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroyView() {
|
|
||||||
_binding = null
|
|
||||||
super.onDestroyView()
|
|
||||||
}
|
|
||||||
|
|
||||||
private val actionModeCallback = object : ActionMode.Callback {
|
private val actionModeCallback = object : ActionMode.Callback {
|
||||||
// Called when the action mode is created; startActionMode() was called
|
// Called when the action mode is created; startActionMode() was called
|
||||||
override fun onCreateActionMode(mode: ActionMode, menu: Menu): Boolean {
|
override fun onCreateActionMode(mode: ActionMode, menu: Menu): Boolean {
|
||||||
|
@@ -10,25 +10,19 @@ import android.view.LayoutInflater
|
|||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import kotlinx.android.synthetic.main.fragment_to_clone_or_not.clone_from_server_button
|
import com.zeapo.pwdstore.databinding.FragmentToCloneOrNotBinding
|
||||||
import kotlinx.android.synthetic.main.fragment_to_clone_or_not.local_directory_button
|
import com.zeapo.pwdstore.utils.viewBinding
|
||||||
import kotlinx.android.synthetic.main.fragment_to_clone_or_not.settings_button
|
|
||||||
|
|
||||||
class ToCloneOrNot : Fragment() {
|
class ToCloneOrNot : Fragment() {
|
||||||
|
|
||||||
override fun onCreateView(
|
private val binding by viewBinding(FragmentToCloneOrNotBinding::bind)
|
||||||
inflater: LayoutInflater,
|
|
||||||
container: ViewGroup?,
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? = binding.root
|
||||||
savedInstanceState: Bundle?
|
|
||||||
): View? {
|
|
||||||
// Inflate the layout for this fragment
|
|
||||||
return inflater.inflate(R.layout.fragment_to_clone_or_not, container, false)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
settings_button.setOnClickListener { startActivity(Intent(requireContext(), UserPreference::class.java)) }
|
binding.settingsButton.setOnClickListener { startActivity(Intent(requireContext(), UserPreference::class.java)) }
|
||||||
local_directory_button.setOnClickListener { (requireActivity() as PasswordStore).initRepository(PasswordStore.NEW_REPO_BUTTON) }
|
binding.localDirectoryButton.setOnClickListener { (requireActivity() as PasswordStore).initRepository(PasswordStore.NEW_REPO_BUTTON) }
|
||||||
clone_from_server_button.setOnClickListener { (requireActivity() as PasswordStore).initRepository(PasswordStore.CLONE_REPO_BUTTON) }
|
binding.cloneFromServerButton.setOnClickListener { (requireActivity() as PasswordStore).initRepository(PasswordStore.CLONE_REPO_BUTTON) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -36,6 +36,7 @@ import com.zeapo.pwdstore.autofill.oreo.DirectoryStructure
|
|||||||
import com.zeapo.pwdstore.autofill.oreo.FormOrigin
|
import com.zeapo.pwdstore.autofill.oreo.FormOrigin
|
||||||
import com.zeapo.pwdstore.databinding.ActivityOreoAutofillFilterBinding
|
import com.zeapo.pwdstore.databinding.ActivityOreoAutofillFilterBinding
|
||||||
import com.zeapo.pwdstore.utils.PasswordItem
|
import com.zeapo.pwdstore.utils.PasswordItem
|
||||||
|
import com.zeapo.pwdstore.utils.viewBinding
|
||||||
|
|
||||||
@TargetApi(Build.VERSION_CODES.O)
|
@TargetApi(Build.VERSION_CODES.O)
|
||||||
class AutofillFilterView : AppCompatActivity() {
|
class AutofillFilterView : AppCompatActivity() {
|
||||||
@@ -72,7 +73,7 @@ class AutofillFilterView : AppCompatActivity() {
|
|||||||
|
|
||||||
private lateinit var formOrigin: FormOrigin
|
private lateinit var formOrigin: FormOrigin
|
||||||
private lateinit var directoryStructure: DirectoryStructure
|
private lateinit var directoryStructure: DirectoryStructure
|
||||||
private lateinit var binding: ActivityOreoAutofillFilterBinding
|
private val binding by viewBinding(ActivityOreoAutofillFilterBinding::inflate)
|
||||||
|
|
||||||
private val model: SearchableRepositoryViewModel by viewModels {
|
private val model: SearchableRepositoryViewModel by viewModels {
|
||||||
ViewModelProvider.AndroidViewModelFactory(application)
|
ViewModelProvider.AndroidViewModelFactory(application)
|
||||||
@@ -80,7 +81,6 @@ class AutofillFilterView : AppCompatActivity() {
|
|||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
binding = ActivityOreoAutofillFilterBinding.inflate(layoutInflater)
|
|
||||||
setContentView(binding.root)
|
setContentView(binding.root)
|
||||||
setFinishOnTouchOutside(true)
|
setFinishOnTouchOutside(true)
|
||||||
|
|
||||||
|
@@ -22,6 +22,7 @@ import com.zeapo.pwdstore.autofill.oreo.AutofillPublisherChangedException
|
|||||||
import com.zeapo.pwdstore.autofill.oreo.FormOrigin
|
import com.zeapo.pwdstore.autofill.oreo.FormOrigin
|
||||||
import com.zeapo.pwdstore.autofill.oreo.computeCertificatesHash
|
import com.zeapo.pwdstore.autofill.oreo.computeCertificatesHash
|
||||||
import com.zeapo.pwdstore.databinding.ActivityOreoAutofillPublisherChangedBinding
|
import com.zeapo.pwdstore.databinding.ActivityOreoAutofillPublisherChangedBinding
|
||||||
|
import com.zeapo.pwdstore.utils.viewBinding
|
||||||
|
|
||||||
@TargetApi(Build.VERSION_CODES.O)
|
@TargetApi(Build.VERSION_CODES.O)
|
||||||
class AutofillPublisherChangedActivity : AppCompatActivity() {
|
class AutofillPublisherChangedActivity : AppCompatActivity() {
|
||||||
@@ -45,11 +46,10 @@ class AutofillPublisherChangedActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private lateinit var appPackage: String
|
private lateinit var appPackage: String
|
||||||
private lateinit var binding: ActivityOreoAutofillPublisherChangedBinding
|
private val binding by viewBinding(ActivityOreoAutofillPublisherChangedBinding::inflate)
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
binding = ActivityOreoAutofillPublisherChangedBinding.inflate(layoutInflater)
|
|
||||||
setContentView(binding.root)
|
setContentView(binding.root)
|
||||||
setFinishOnTouchOutside(true)
|
setFinishOnTouchOutside(true)
|
||||||
|
|
||||||
|
@@ -14,15 +14,15 @@ import com.google.android.material.snackbar.Snackbar
|
|||||||
import com.zeapo.pwdstore.R
|
import com.zeapo.pwdstore.R
|
||||||
import com.zeapo.pwdstore.databinding.ActivityGitConfigBinding
|
import com.zeapo.pwdstore.databinding.ActivityGitConfigBinding
|
||||||
import com.zeapo.pwdstore.utils.PasswordRepository
|
import com.zeapo.pwdstore.utils.PasswordRepository
|
||||||
|
import com.zeapo.pwdstore.utils.viewBinding
|
||||||
import org.eclipse.jgit.lib.Constants
|
import org.eclipse.jgit.lib.Constants
|
||||||
|
|
||||||
class GitConfigActivity : BaseGitActivity() {
|
class GitConfigActivity : BaseGitActivity() {
|
||||||
|
|
||||||
private lateinit var binding: ActivityGitConfigBinding
|
private val binding by viewBinding(ActivityGitConfigBinding::inflate)
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
binding = ActivityGitConfigBinding.inflate(layoutInflater)
|
|
||||||
setContentView(binding.root)
|
setContentView(binding.root)
|
||||||
supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
||||||
|
|
||||||
|
@@ -17,6 +17,7 @@ import com.zeapo.pwdstore.databinding.ActivityGitCloneBinding
|
|||||||
import com.zeapo.pwdstore.git.config.ConnectionMode
|
import com.zeapo.pwdstore.git.config.ConnectionMode
|
||||||
import com.zeapo.pwdstore.git.config.Protocol
|
import com.zeapo.pwdstore.git.config.Protocol
|
||||||
import com.zeapo.pwdstore.utils.PasswordRepository
|
import com.zeapo.pwdstore.utils.PasswordRepository
|
||||||
|
import com.zeapo.pwdstore.utils.viewBinding
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -25,11 +26,10 @@ import java.io.IOException
|
|||||||
*/
|
*/
|
||||||
class GitServerConfigActivity : BaseGitActivity() {
|
class GitServerConfigActivity : BaseGitActivity() {
|
||||||
|
|
||||||
private lateinit var binding: ActivityGitCloneBinding
|
private val binding by viewBinding(ActivityGitCloneBinding::inflate)
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
binding = ActivityGitCloneBinding.inflate(layoutInflater)
|
|
||||||
val isClone = intent?.extras?.getInt(REQUEST_ARG_OP) ?: -1 == REQUEST_CLONE
|
val isClone = intent?.extras?.getInt(REQUEST_ARG_OP) ?: -1 == REQUEST_CLONE
|
||||||
if (isClone) {
|
if (isClone) {
|
||||||
binding.saveButton.text = getString(R.string.clone_button)
|
binding.saveButton.text = getString(R.string.clone_button)
|
||||||
|
@@ -19,6 +19,7 @@ import com.jcraft.jsch.JSch
|
|||||||
import com.jcraft.jsch.KeyPair
|
import com.jcraft.jsch.KeyPair
|
||||||
import com.zeapo.pwdstore.R
|
import com.zeapo.pwdstore.R
|
||||||
import com.zeapo.pwdstore.databinding.FragmentSshKeygenBinding
|
import com.zeapo.pwdstore.databinding.FragmentSshKeygenBinding
|
||||||
|
import com.zeapo.pwdstore.utils.viewBinding
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
@@ -28,17 +29,9 @@ import java.io.FileOutputStream
|
|||||||
class SshKeyGenFragment : Fragment() {
|
class SshKeyGenFragment : Fragment() {
|
||||||
|
|
||||||
private var keyLength = 4096
|
private var keyLength = 4096
|
||||||
private var _binding: FragmentSshKeygenBinding? = null
|
private val binding by viewBinding(FragmentSshKeygenBinding::bind)
|
||||||
private val binding get() = _binding!!
|
|
||||||
|
|
||||||
override fun onCreateView(
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?) = binding.root
|
||||||
inflater: LayoutInflater,
|
|
||||||
container: ViewGroup?,
|
|
||||||
savedInstanceState: Bundle?
|
|
||||||
): View? {
|
|
||||||
_binding = FragmentSshKeygenBinding.inflate(inflater, container, false)
|
|
||||||
return binding.root
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
@@ -60,7 +53,6 @@ class SshKeyGenFragment : Fragment() {
|
|||||||
|
|
||||||
override fun onDestroyView() {
|
override fun onDestroyView() {
|
||||||
super.onDestroyView()
|
super.onDestroyView()
|
||||||
_binding = null
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Invoked when 'Generate' button of SshKeyGenFragment clicked. Generates a
|
// Invoked when 'Generate' button of SshKeyGenFragment clicked. Generates a
|
||||||
|
@@ -0,0 +1,66 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2014-2020 The Android Password Store Authors. All Rights Reserved.
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-only
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.zeapo.pwdstore.utils
|
||||||
|
|
||||||
|
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
|
import androidx.lifecycle.DefaultLifecycleObserver
|
||||||
|
import androidx.lifecycle.Lifecycle
|
||||||
|
import androidx.lifecycle.LifecycleOwner
|
||||||
|
import androidx.lifecycle.observe
|
||||||
|
import androidx.viewbinding.ViewBinding
|
||||||
|
import kotlin.properties.ReadOnlyProperty
|
||||||
|
import kotlin.reflect.KProperty
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Imported from https://medium.com/@Zhuinden/simple-one-liner-viewbinding-in-fragments-and-activities-with-kotlin-961430c6c07c
|
||||||
|
*/
|
||||||
|
class FragmentViewBindingDelegate<T : ViewBinding>(
|
||||||
|
val fragment: Fragment,
|
||||||
|
val viewBindingFactory: (View) -> T
|
||||||
|
) : ReadOnlyProperty<Fragment, T> {
|
||||||
|
|
||||||
|
private var binding: T? = null
|
||||||
|
|
||||||
|
init {
|
||||||
|
fragment.lifecycle.addObserver(object : DefaultLifecycleObserver {
|
||||||
|
override fun onCreate(owner: LifecycleOwner) {
|
||||||
|
fragment.viewLifecycleOwnerLiveData.observe(fragment) { viewLifecycleOwner ->
|
||||||
|
viewLifecycleOwner.lifecycle.addObserver(object : DefaultLifecycleObserver {
|
||||||
|
override fun onDestroy(owner: LifecycleOwner) {
|
||||||
|
binding = null
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getValue(thisRef: Fragment, property: KProperty<*>): T {
|
||||||
|
val binding = binding
|
||||||
|
if (binding != null) {
|
||||||
|
return binding
|
||||||
|
}
|
||||||
|
|
||||||
|
val lifecycle = fragment.viewLifecycleOwner.lifecycle
|
||||||
|
if (!lifecycle.currentState.isAtLeast(Lifecycle.State.INITIALIZED)) {
|
||||||
|
throw IllegalStateException("Should not attempt to get bindings when Fragment views are destroyed.")
|
||||||
|
}
|
||||||
|
|
||||||
|
return viewBindingFactory(thisRef.requireView()).also { this.binding = it }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <T : ViewBinding> Fragment.viewBinding(viewBindingFactory: (View) -> T) =
|
||||||
|
FragmentViewBindingDelegate(this, viewBindingFactory)
|
||||||
|
|
||||||
|
inline fun <T : ViewBinding> AppCompatActivity.viewBinding(crossinline bindingInflater: (LayoutInflater) -> T) =
|
||||||
|
lazy(LazyThreadSafetyMode.NONE) {
|
||||||
|
bindingInflater.invoke(layoutInflater)
|
||||||
|
}
|
@@ -32,6 +32,7 @@ ext.deps = [
|
|||||||
core_ktx: 'androidx.core:core-ktx:1.3.0-rc01',
|
core_ktx: 'androidx.core:core-ktx:1.3.0-rc01',
|
||||||
documentfile: 'androidx.documentfile:documentfile:1.0.1',
|
documentfile: 'androidx.documentfile:documentfile:1.0.1',
|
||||||
fragment_ktx: 'androidx.fragment:fragment-ktx:1.3.0-alpha03',
|
fragment_ktx: 'androidx.fragment:fragment-ktx:1.3.0-alpha03',
|
||||||
|
lifecycle_common: 'androidx.lifecycle:lifecycle-common-java8:2.3.0-alpha01',
|
||||||
lifecycle_livedata_ktx: 'androidx.lifecycle:lifecycle-livedata-ktx:2.3.0-alpha01',
|
lifecycle_livedata_ktx: 'androidx.lifecycle:lifecycle-livedata-ktx:2.3.0-alpha01',
|
||||||
lifecycle_viewmodel_ktx: 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.0-alpha01',
|
lifecycle_viewmodel_ktx: 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.0-alpha01',
|
||||||
local_broadcast_manager: 'androidx.localbroadcastmanager:localbroadcastmanager:1.1.0-alpha01',
|
local_broadcast_manager: 'androidx.localbroadcastmanager:localbroadcastmanager:1.1.0-alpha01',
|
||||||
|
Reference in New Issue
Block a user