我有一个工作的应用程序,它做一些算术功能,这是超出了问题的范围,然后我想添加更多的功能,所以我把布局分为活动和片段,以便稍后添加其他片段,将做额外的功能。
然而,当我将带有一些按钮的布局与TextView(R.id.Result)沿着分离到新片段时,TextView的text属性仍按预期更新,但显示保持不变,始终显示在创建时最初分配给它的初始化值。
我确认对象与我预期的相同,在运行时期间通过logcat验证,我需要OFC的是在我更改TextView显示的text属性时更新TextView显示,从按钮正确调用numberInsertAction并发送正确的数据。
- 重要提示:下面只是代码的相关部分,它要大得多,我知道您在下面看到的内容可以简化,但它是这样构建的,因为下面没有显示其他类和功能,如果您需要查看或询问下面代码以外的内容,请进行,但我再次只包括相关部分,并删除了业务功能。*
先谢谢你。
只是重申一下:数字插入操作(查看:View)是由片段上的按钮调用的入口点/函数。
MainActivity.kt
class MainActivity : AppCompatActivity(), AddObserverToActivity {
private lateinit var binding: ActivityMainBinding
private lateinit var stateManager: StateManager
override fun onCreate(savedInstanceState: Bundle?) {
//initialize layout
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
val activityRoot = binding.root
setContentView(activityRoot)
stateManager = StateManager()
}
override fun addResultObserver(observer: Observer) {
Log.d(TAG, "addObserver! ${observer.toString()} ${observer::class.toString()}")
StateManager.addDisplayObserver(observer)
}
fun numberInsertAction(view: View) {
if (view is Button) {
StateManager.enterDigit(view.text.toString())
}
}
}
CalculatorFragment.kt
class CalculatorFragment : Fragment() {
companion object {
fun newInstance() = CalculatorFragment()
}
private lateinit var binding: FragmentCalculatorBinding
private lateinit var mainActivityHandle: AddObserverToActivity
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
Log.d(TAG, "onCreateView")
binding = FragmentCalculatorBinding.inflate(inflater, container, false)
return inflater.inflate(R.layout.fragment_calculator, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
Log.d(TAG, "using on view created")
mainActivityHandle = context as AddObserverToActivity
Log.d(TAG, "${binding.Result} ${(binding.Result)::class.simpleName.toString()}")
Log.d(TAG, mainActivityHandle::class.toString())
mainActivityHandle.addResultObserver(DisplayPanel(binding.Result))
}
}
StateManager.kt
class StateManager : Observable() {
private val displayBuffer = DisplayBuffer(DecimalVariable("0"))
fun enterDigit(digit: String) {
Log.d(TAG, "enterDigit: $digit, $currentState")
displayBuffer.insertDigit(digit)
}
fun addDisplayObserver(observer: Observer) {
Log.d(TAG, "addDisplayObserver: $observer")
displayBuffer.addObserver(observer)
}
private fun doNotify(Notified: Any) {
Log.d(TAG, "doNotify: $Notified")
setChanged()
notifyObservers(Notified)
}
}
DisplayBuffer.kt
class DisplayBuffer(initializationValue: SomeClass) : Observable() {
private var initialValue = initializationValue
private var resultString = "0"
var value = initialValue
set(value) {
Log.d(TAG, "setter: $value")
field = value
doNotify()
}
fun set(value: String) {
Log.d(TAG, "set: $value")
this.value = value as Int
}
private fun doNotify() {
Log.d(TAG, "doNotify")
setChanged()
notifyObservers(value.toString())
}
fun insertDigit(digit: String) {
Log.d(TAG, "insertDigit: $digit result: $resultString")
resultString = resultString + digit
Log.d(TAG, "new value: $resultString")
setChanged()
notifyObservers(resultString)
}
}
DisplayPanel.kt
class DisplayPanel(calculationTextView: TextView) : Observer {
private val displayField: TextView = calculationTextView
private val maxDigits = 16
private fun setDisplay(text: String) {
Log.d(TAG, "setDisplay: $text")
if (text.length <= maxDigits) {
displayField.text = text
//displayField.invalidate()
}
}
override fun update(observable: Observable?, targetObjects: Any?) {
Log.d(TAG, "update: $this $observable, $targetObjects")
setDisplay(targetObjects as String)
}
}
2条答案
按热度按时间1mrurvl11#
在
onCreateView
或onViewCreated
方法中添加binding.lifecycleOwner = viewLifecycleOwner
。0g0grzrc2#
回复者:@Mike M评论:在CalculatorFragment中,他指示我将
return inflater.inflate(R.layout.fragment_calculator, container, false)
更改为return binding.root
。因为问题是这个函数膨胀了片段计算器布局的两个示例,并返回后者,而它使用前者作为观察者。
到qoute @迈克-M:inflater.inflate()调用创建了一个新的布局示例,它与FragmentCalculatorBinding创建和使用的布局完全不同。FragmentCalculatorBinding在内部膨胀视图,这就是为什么在inflate()调用中传递inflater的原因。