android-fragments 文本视图,文本更改,但其在片段上的显示不更新

lsmd5eda  于 2022-11-14  发布在  Android
关注(0)|答案(2)|浏览(161)

我有一个工作的应用程序,它做一些算术功能,这是超出了问题的范围,然后我想添加更多的功能,所以我把布局分为活动和片段,以便稍后添加其他片段,将做额外的功能。
然而,当我将带有一些按钮的布局与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)
    }
}
1mrurvl1

1mrurvl11#

onCreateViewonViewCreated方法中添加binding.lifecycleOwner = viewLifecycleOwner

0g0grzrc

0g0grzrc2#

回复者:@Mike M评论:在CalculatorFragment中,他指示我将return inflater.inflate(R.layout.fragment_calculator, container, false)更改为return binding.root
因为问题是这个函数膨胀了片段计算器布局的两个示例,并返回后者,而它使用前者作为观察者。
到qoute @迈克-M:inflater.inflate()调用创建了一个新的布局示例,它与FragmentCalculatorBinding创建和使用的布局完全不同。FragmentCalculatorBinding在内部膨胀视图,这就是为什么在inflate()调用中传递inflater的原因。

相关问题