我有3个片段:用户在前2个信息中输入信息,即A和B,输入的信息用C汇总。我正在使用捆绑软件收集信息以及向后堆叠以帮助用户导航。
但是,主要问题是,一旦用户离开片段A和B,输入的信息就不会保存。因此,如果用户返回到片段A或B,我将使用捆绑软件中的数据来预先填充所有预先输入的信息。
这真的很痛苦,因为我有各种各样的看法。 TextViews和TimePickers很好,但是RadioButtons和CheckBoxes确实具有挑战性。
我刚接触Android,现在已经编码了大约4个月。是否有一种简单的方法来保存和恢复可以持久保存用户输入信息的片段(也许使用片段标签)?如果是这样,请进行描述。预先感谢。
答案 0 :(得分:0)
但是,主要问题是,一旦用户离开片段A和B,输入的信息就不会保存。
简便的方法是使用SharedPreferences
,将片段A和片段B中输入的信息保存为SharedPref作为键值,然后在片段c中检索它们并进行计算。
RadioButtons和CheckBoxs确实具有挑战性。
还将每个RadioButtons
和CheckBoxes
的状态保存到SharedPref中,然后检索它们并在那里设置状态。
答案 1 :(得分:0)
假设这3个片段由同一活动保存,则可以使用共享的ViewModel实例,该实例表示与这3个片段相关的数据。
看看此链接https://developer.android.com/topic/libraries/architecture/viewmodel
其中有一个关于片段之间共享数据的部分,并显示了两个片段之间共享的自定义ViewModel的示例。关键是
override func viewDidLoad() {
super.viewDidLoad()
configureNotificationObserver()
setupView()
configureAnimationView()
}
// MARK: VIEW CONTROLLER INITIALIZATIONS
private lazy var roleViewController: RoleViewController = {
let storyboard = UIStoryboard(name: "Main", bundle: Bundle.main)
let viewController = storyboard.instantiateViewController(withIdentifier: "RoleViewController") as! RoleViewController
self.add(asChildViewController: viewController)
return viewController
}()
private lazy var firstCredentialViewController: FirstCredentialViewController = {
let storyboard = UIStoryboard(name: "Main", bundle: Bundle.main)
let viewController = storyboard.instantiateViewController(withIdentifier: "FirstCredentialViewController") as! FirstCredentialViewController
self.add(asChildViewController: viewController)
return viewController
}()
private lazy var birthdateViewController: BirthdateViewController = {
let storyboard = UIStoryboard(name: "Main", bundle: Bundle.main)
let viewController = storyboard.instantiateViewController(withIdentifier: "BirthdateViewController") as! BirthdateViewController
self.add(asChildViewController: viewController)
return viewController
}()
private lazy var emailViewController: EmailViewController = {
let storyboard = UIStoryboard(name: "Main", bundle: Bundle.main)
let viewController = storyboard.instantiateViewController(withIdentifier: "EmailViewController") as! EmailViewController
self.add(asChildViewController: viewController)
return viewController
}()
private lazy var passwordViewController: PasswordViewController = {
let storyboard = UIStoryboard(name: "Main", bundle: Bundle.main)
let viewController = storyboard.instantiateViewController(withIdentifier: "PasswordViewController") as! PasswordViewController
self.add(asChildViewController: viewController)
return viewController
}()
private lazy var confirmPasswordViewController: ConfirmPasswordViewController = {
let storyboard = UIStoryboard(name: "Main", bundle: Bundle.main)
let viewController = storyboard.instantiateViewController(withIdentifier: "ConfirmPasswordViewController") as! ConfirmPasswordViewController
self.add(asChildViewController: viewController)
return viewController
}()
private lazy var termsAndConditionsViewController: TermsAndConditionsViewController = {
let storyboard = UIStoryboard(name: "Main", bundle: Bundle.main)
let viewController = storyboard.instantiateViewController(withIdentifier: "TermsAndConditionsViewController") as! TermsAndConditionsViewController
self.add(asChildViewController: viewController)
return viewController
}()
private lazy var doneViewController: DoneViewController = {
let storyboard = UIStoryboard(name: "Main", bundle: Bundle.main)
let viewController = storyboard.instantiateViewController(withIdentifier: "DoneViewController") as! DoneViewController
self.add(asChildViewController: viewController)
return viewController
}()
// MARK: FUNCTIONS
private func add(asChildViewController viewController: UIViewController) {
addChildViewController(viewController)
containerView.addSubview(viewController.view)
viewController.view.frame = view.bounds
viewController.view.autoresizingMask = [.flexibleWidth, .flexibleHeight]
viewController.didMove(toParentViewController: self)
}
private func remove(asChildViewController viewController: UIViewController) {
viewController.willMove(toParentViewController: nil)
viewController.view.removeFromSuperview()
viewController.removeFromParentViewController()
}
private func configureAnimationView() {
gearsAnimationView.frame = CGRect(x: 350, y: 160, width: 300, height: 200)
gearsAnimationView.contentMode = .scaleAspectFit
gearsAnimationView.loopAnimation = true
loadingContainerView.addSubview(gearsAnimationView)
}
private func setupSteppedProgressBar() {
progressBar.numberOfPoints = Page.titles.count
progressBar.lineHeight = 8
progressBar.radius = 15
progressBar.progressRadius = 20
progressBar.progressLineHeight = 3
progressBar.delegate = self
progressBar.stepTextColor = UIColor.lightGray
progressBar.stepTextFont = UIFont.init(name: "HelveticaNeue", size: 15.0)
progressBar.selectedBackgoundColor = UIColor(red: 82/255, green: 177/255, blue: 108/255, alpha: 1.0)
// CURRENT SELECTED
progressBar.currentSelectedCenterColor = UIColor(red: 244/255, green: 69/255, blue: 93/255, alpha: 1.0)
progressBar.selectedOuterCircleStrokeColor = UIColor(red: 244/255, green: 69/255, blue: 93/255, alpha: 1.0)
progressBar.currentSelectedTextColor = UIColor(red: 56/255, green: 56/255, blue: 56/255, alpha: 1.0)
}
func updateView() {
let currentIndex = progressBar.currentIndex
switch currentIndex {
case 0:
remove(asChildViewController: firstCredentialViewController)
add(asChildViewController: roleViewController)
case 1:
remove(asChildViewController: roleViewController)
add(asChildViewController: firstCredentialViewController)
case 2:
remove(asChildViewController: firstCredentialViewController)
add(asChildViewController: birthdateViewController)
case 3:
remove(asChildViewController: birthdateViewController)
add(asChildViewController: emailViewController)
case 4:
remove(asChildViewController: emailViewController)
add(asChildViewController: passwordViewController)
case 5:
remove(asChildViewController: passwordViewController)
add(asChildViewController: confirmPasswordViewController)
case 6:
remove(asChildViewController: confirmPasswordViewController)
// add(asChildViewController: termsAndConditionsViewController)
case 7:
// remove(asChildViewController: termsAndConditionsViewController)
add(asChildViewController: doneViewController)
default: break
}
}
private func setupView() {
setupSteppedProgressBar()
updateView()
}
private func configureNotificationObserver() {
NotificationCenter.default.addObserver(self, selector: #selector(self.nextStep), name: NSNotification.Name(rawValue: "nextStep"), object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(self.previousStep), name: NSNotification.Name(rawValue: "previousStep"), object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(self.showLoading), name: NSNotification.Name(rawValue: "showLoading"), object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(self.hideLoading), name: NSNotification.Name(rawValue: "hideLoading"), object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(self.successfulUserCreated), name: NSNotification.Name(rawValue: "UserCreated"), object: nil)
}
//sample typing
@objc func nextStep() {
let currentIndex = progressBar.currentIndex
let totalNumberOfPoints = progressBar.numberOfPoints
switch currentIndex {
case 0:
firstCredentialViewController.userRole = roleViewController.userRole
case 1:
birthdateViewController.userRole = firstCredentialViewController.userRole
birthdateViewController.firstCredential = firstCredentialViewController.firstCredential
case 4:
confirmPasswordViewController.userRole = birthdateViewController.userRole
confirmPasswordViewController.firstCredential = birthdateViewController.firstCredential
confirmPasswordViewController.emailString = emailViewController.emailString
confirmPasswordViewController.passwordString = passwordViewController.passwordString
// case 5:
// termsAndConditionsViewController.userRole = confirmPasswordViewController.userRole
// termsAndConditionsViewController.firstCredential = confirmPasswordViewController.firstCredential
// termsAndConditionsViewController.emailString = confirmPasswordViewController.emailString
// termsAndConditionsViewController.confirmPasswordString = confirmPasswordViewController.passwordString
default: break
}
if currentIndex < (totalNumberOfPoints - 1) {
progressBar.currentIndex = currentIndex + 1
updateView()
}
}
@objc func previousStep() {
let currentIndex = progressBar.currentIndex
progressBar.currentIndex = currentIndex - 1
updateView()
@objc func showLoading() {
isLoading(on: true)
}
@objc func hideLoading() {
isLoading(on: false)
}
@objc func successfulUserCreated() {
clearAllData()
progressBar.currentIndex = 0
updateView()
}
private func clearAllData() {
// RoleViewController
roleViewController.userRole = nil
// FirstCredentialViewController
firstCredentialViewController.userRole = nil
firstCredentialViewController.firstCredential = nil
firstCredentialViewController.titleLabel.text = ""
firstCredentialViewController.credentialTextField.text = ""
// BirthdateViewController
birthdateViewController.userRole = nil
birthdateViewController.firstCredential = nil
birthdateViewController.birthdate = nil
// EmailViewController
emailViewController.emailString = nil
emailViewController.emailAddressTextField.text = ""
// PasswordViewController
passwordViewController.passwordString = nil
passwordViewController.passwordTextField.text = ""
// ConfirmPasswordViewController
confirmPasswordViewController.userRole = nil
confirmPasswordViewController.firstCredential = nil
confirmPasswordViewController.passwordString = nil
confirmPasswordViewController.confirmPasswordTextField.text = ""
//TermsAndConditionsViewController
termsAndConditionsViewController.proceedButton.isEnabled = false
termsAndConditionsViewController.checkButton.isSelected = false
}
}
extension MasterViewController {
func progressBar(_ progressBar: FlexibleSteppedProgressBar, canSelectItemAtIndex index: Int) -> Bool {
return false
}
func progressBar(_ progressBar: FlexibleSteppedProgressBar, textAtIndex index: Int, position: FlexibleSteppedProgressBarTextLocation) -> String {
if position == FlexibleSteppedProgressBarTextLocation.bottom {
return Page.titles[index]
}
return ""
}
}
请注意,它将封闭的Activity用作该SharedViewModel实例的“所有者”。因此,由同一Activity容纳的两个片段将获取该SharedViewModel的实例,并且能够共享数据。如果需要保留这些数据,则可以将该逻辑封装在ViewModel中,或者让该ViewModel将其委托给某些DAO / Repository类。