textView.Text会更改,但在片段上显示其显示

发布于 2025-02-01 07:51:12 字数 4533 浏览 1 评论 0原文

我有一个有效的应用程序,该应用程序执行了一些问题范围的算术功能,然后我想向其添加更多功能,因此我将布局分离为活动和片段,以便稍后添加其他片段,这些片段会添加额外的片段功能。

然而,当我将布局以及将某些按钮以及文本视图(r.id.result)一起分开到新片段时,文本视图的文本属性仍按预期更新,但是显示屏保持不变,始终显示最初分配的初始化值在其创建时间上。

我确认对象与我期望的在通过logcat验证的运行时相同,我需要的OFC是在更改其文本属性时要更新的文本视图显示,numberSInserTaction从按钮正确调用并发送正确的数据。

重要说明:下面只是代码的相关部分,它更大,我知道您在下面看到的内容可以简化,但由于其他类别和功能,如果您没有显示下面的其他类和功能,则需要查看或询问以下代码之外的内容,请执行此操作,再次我仅包括相关部分并删除了业务功能。

提前。

重申:NumberInsertaction(视图:视图)是片段上的按钮调用的入口点/函数。

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)
    }
}

I had a working app that does some arithmetic functionality that is out of the scope of the question, then I wanted to add more functionality to it, so i separated the layout into activity and fragment in order to later add other fragments that will do extra functions.

yet when I separated the layout taking some buttons along with a TextView (R.id.Result) to the new fragment, the text property of the TextView still updates as expected, but the display stays the same, always showing the initialization value initially assigned to it on its creation time.

I confirmed that the objects are the same as I expected them to be during runtime verified through logcat, what I need OFC is for the TextView display to update when I change its text property, numberInsertAction is called from the buttons properly and send proper data.

Important Note: below is only the relevant parts of code, it is much larger and I know what you see below can be simplified but it is built this way because of other classes and functionality that aren't shown below, if you need to see or ask about something outside the below code please do, yet again I only included the related part only and removed the business functionality.

Thanks in advance.

just to reiterate: numberInsertAction(view: View) is the entry point/function called by the buttons on the fragment.

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)
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

为你鎻心 2025-02-08 07:51:12

添加binding.lifecycleowner = view lifecycleowner in increateviewonviewCreated方法。

Add binding.lifecycleOwner = viewLifecycleOwner in onCreateView or onViewCreated method.

若水般的淡然安静女子 2025-02-08 07:51:12

@mike M在评论中回答:
在计算范围内,
他指示我改变
返回forter.inflate(r.layout.fragment_calculator,Container,false) 返回binding.root

由于问题是,该函数膨胀了片段计算器布局的两个实例,并在以前的观察者使用后返回。

到Qoute @Mike-M:
Afferater.inflate()调用正在创建该布局的新实例,该实例与FragmentCalculatorBinding正在创建和使用自身的布局完全分开。
片段刻度堆积在内部充气,这就是为什么它在膨胀()呼叫中都通过膨胀者的原因。

was answered by @Mike M in Comments:
In CalculatorFragment,
He instructed me to change
return inflater.inflate(R.layout.fragment_calculator, container, false) to return binding.root.

as the problem was that this function inflated two instances of the fragment calculator layout and returned the later while it used the former as observer.

to qoute @Mike-M:
The inflater.inflate() call is creating a new instance of that layout that is completely separate from the one that FragmentCalculatorBinding is creating and using itself.
FragmentCalculatorBinding is inflating the view internally, which is why it is passed the inflater in its inflate() call.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文