Reputation: 34529
I want to display some text in an EditText
and do some work right away after the text is displayed. I have the following code in my onCreate()
method:
this.editor.setText(text, TextView.BufferType.EDITABLE);
new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
@Override
public void run() {
// Work that needs to be done right after the text is displayed
}
}, 1000);
This works OK, but I want to minimize the delay between setText()
rendering and the work being done-- a 1s delay is unacceptable. However, if I change the delay to 0ms or 1ms, then the work is done before the text gets rendered.
I could keep typing in numbers to search for the perfect delay time that would execute my code just after the text was rendered, but that seems very tedious/imprecise. Is there a better way to tell Android to run a callback right after that happens? Thanks.
edit: Here are two things I've tried that didn't work. For bonus points, it would be very helpful if you could explain to me why these didn't work.
Using Handler.post
new Handler(Looper.getMainLooper()).post(r)
also runs r
before the text finishes rendering. I thought setText
adds rendering code to the queue, so shouldn't post(r)
being called after that add r
after the rendering code?
Using View.post
this.editor.post(r)
didn't work either, r
is still called before the text is rendered.
Upvotes: 2
Views: 1077
Reputation: 34529
I initially wanted to delay the work because it was CPU-intensive. I realized the solution was to spin up a new thread for the work, rather than post it to the UI thread.
Upvotes: 0
Reputation: 8190
You can use ViewTreeObserver
as below:
yourView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
// do your work here. This call back will be called after view is rendered.
yourView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
// or below API 16: yourView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
}
});
Upvotes: 1
Reputation: 1360
You can assign a TextWatcher
to your EditText
.
A TextWatcher
is basically a listener that listens for changes to the text (before, during and after) in the EditText
.
It can be implemented as follows:
EditText et;
et.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) {
// Work that needs to be done right after the text is displayed
}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
public void onTextChanged(CharSequence s, int start, int before, int count) {}
}
So when you set the text explicitly, this listener should be called and after the text is changed, the // Work that needs to be done right after the text is displayed
code will be run.
Upvotes: 1
Reputation: 1915
Use this it would hlp
mSongNameTextView.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
}
});
Upvotes: 1