B3nedikt / reword

Reword is a android library to update the texts of views when the apps texts have changed due to a language change or an update of the apps string resources.
Apache License 2.0
32 stars 7 forks source link

It will restore to the string set in xml after modifying it programmatically #28

Closed adherencegoo closed 2 years ago

adherencegoo commented 2 years ago

Since the id R.string.XXX is cached in tags of a view when inflating it, https://github.com/B3nedikt/reword/blob/9fcc0286b69ea40bf4d50ff36119e6091bc41c6d/reword/src/main/java/dev/b3nedikt/reword/ViewTransformerManager.kt#L63 every time I invoke Reword.reword(view), it will be restored to the string set by xml

For example:

  1. In xml, I use android:text="@string/first"
  2. In kotlin code, I change the text by view.setText("hardcoded second") or view.setText(R.string.second) programmatically
  3. After invoking Reword.reword(view), it changes back to "first" again

I think there should be a way to modify/delete the view_tag if user invokes setText programmatically

B3nedikt commented 2 years ago

Hi again ;) You cannot modify setText directly, as it is final. However a method like you describe it should be simple to implement, just add a extension function to TextView, Toolbar etc. which modifies the view_tag. It could be called e.g. setTextRes, which you can just call instead of setText, this method could then just modify the view_tag as needed. Doing this for all views supported by Reword is a lot of work though, and I don`t have the time for it right now. If you want you can create a fork of this project though and create a PR if your implementation is somewhat generic. Doesn't need to cover everything, as long as you think it would be useful to other users of this library as well ;)

adherencegoo commented 2 years ago

oh... I just realized that setText is final 🥲 I also think of using extension function to clear/update the view_tag, but it's necessary to replace all existing usage of setText with setTextRes. Just thinking if there are other ways that can do it "implicitly"

Doing this for all views supported by Reword is a lot of work though

Can't agree any more. So I wanna find a more generic way instead of case by case, but have no idea currently 🤦‍♂️

B3nedikt commented 2 years ago

One thing I could add is the possibility to add a interceptor to the Reword.reword(...) method which allows to stop reword translating strings that have been changed programmatically. Something like this:

Reword.reword(rootView,  { view ->
        return false // This view should not get "reworded"
})

This might be useful in some cases. However I think something less implicit like just calling whatever method changed the string programmatically again is probably easier. Especially if you use something like a ViewModel or so... If this helps you or you have another idea feel free to reopen this issue :)