Actually I met a problem with dynamically adjusting the textview gravity which depends on its line count.
I read this article , but I just don't really understand the difference about threading techniques, just like textview.post()
, runOnUiThread{}
, GlobalScope.launch(Dispatchers.Main)
, Thead{}.start()
.
TLDR, short question is " Why the codes below should be run in the post
scope? "
private fun setText(text : String) {
textView.text = text
textView.post {
if (textView.lineCount > 1) {
textView.gravity = Gravity.START
}else {
textView.gravity = Gravity.CENTER
}
}
}
and another short question is " Why it doesn't work in the GlobalScope.launch(Dispatchers.Main)? "
This is my try:
private fun setText(text : String) {
textView.text = text
GlobalScope.launch(Dispatchers.Main) {
if (textView.lineCount > 1) {
textView.gravity = Gravity.START
}else {
textView.gravity = Gravity.CENTER
}
}
}
I tried to put it into GlobalScope.launch(Dispatchers.Main), but it sometimes works and sometimes doesn't work. Also, I tried to make it without textView.post()
, and it just doesn't work. The source code of getLineCount()
doesn't seem to be async operation?
Any suggestion is welcome, thanks for everything.
The "post" methods ( View.post(...)
, View.postDelayed(...)
, etc.) put the Runnable
to queue which is processed by UI/Main thread. The point here is to do all UI updates from a single thread.
What GlobalScope.launch(Dispatchers.Main)
does is that (in addition to aforementioned post methods) it allows you to use all the features provided by Coroutines : for example you can suspend
the code execution without blocking the Main/UI thread. That means that you can code in imperative style which comes handy for more complicated scenarios, like updating UI in loop each few milliseconds . You just suspend
the loop for as long as you need. With post methods you would have to call View.post(...)
with new Runnable
every few ms to update the UI. For more details read the whole Guide to UI programming with coroutines .
I believe, that the reason why your implementation "sometimes works and sometimes doesn't" might be, that you need to call all UI manipulation methods from within the UI (aka Main) thread; meaning that your textView.text = text
should also be part of your post block.
private fun setText(text : String) {
textView.post {
textView.text = text
if (textView.lineCount > 1) {
textView.gravity = Gravity.START
}else {
textView.gravity = Gravity.CENTER
}
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.