I have a layout containing a WebView, and a ProgressBar centred on top of it. The progress bar needs to be shown and hid programatticaly (as web content loads). However, setting the ProgressBar to be visible using loading.setVisibility(View.VISIBLE);, causes a force close. If the ProgressBar is visible by default it works fine. I will paste all appropriate code if needed, but I suspect I'm doing something fundamentally and simply wrong.
(should have force-close tag but neither it nor forceclose exists and I can't create it.)
Okay, code. The setVisibility is simply:
public void nowLoading() {
loading.setVisibility(View.VISIBLE);
}
nowLoading is called... via javascript, with addJavascriptInterface on the WebView. Ahh... I imagine the WevView is in a different Thread. How do I solve that?
You are probably changing the visibility from the wrong thread. Are you doing the visibility change in a new Thread you started with Thread.start()?
EDIT: use a Handler (see http://developer.android.com/reference/android/os/Handler.html). Send a Message to the Handler and then do the visibility change from the Handler. Or use View.post (see http://developer.android.com/reference/android/view/View.html#post%28java.lang.Runnable%29).
try this :
YourActivity.runOnUIThread(new Runnable(){
#Override
public void run(){
loading.setVisibility(View.VISIBLE);
}
});
Related
I am creating an activity that as a dialog format: it does not cover the whole screen, but only part of it. What I did was in the onCreate() method of this activity, after calling setContentView(), I call:
window.setLayout(windowWidthInDp, LayoutParams.WRAP_CONTENT);
And it does not work. I need to do the following instead to make it work:
window.getDecorView().post(new Runnable() {
#Override
public void run() {
window.setLayout(windowWidthInDp, LayoutParams.WRAP_CONTENT);
}
});
Again, this is AFTER setContentView() is called.
Why do I have to pose it into the message queue instead of calling it directly?
Thanks!
Setting the content view just gives the layout to the Android framework. The layout hasn't yet been fully configured. This doesn't happen until the Android framework gets control back (ie: in the next event loop). This won't happen until the onCreate() method ends.
By posting your code to a Handler, you delay the execution of that code until after the Android framework has fully configured the layout.
I have a progress bar that I change from View.GONE to View.VISIBLE, just before I call a method writeFile().
Something like this:
onButtonPress(){
mProgressBar.setVisibility(View.VISIBLE);
writeFile();
}
The method writeFile() can take a few seconds (lots of data parsing), but requires additional actions taken by the user afterwards, and thus is not performed on a background thread. This is to avoid the user navigating elsewhere within the app, and then being presented with a pop-up, or redirected, for something they thought they were done with.
My problem is that the Progress Bar does not display until the writeFile() method is complete, and then briefly pops up for a split second before the user is redirected elsewhere.
If I comment-out the method call, then the ProgressBar appears immediately and spins indefinitely, so I know the bar is working properly.
How can I ensure the progress bar pops up FIRST, and then the writeFile() method is called after?
Thanks in advance.
Additionally:
I don't have a lot of experience (exactly none!) with asynctasks, and so am not sure if this is the route I need to take. The behaviour I am looking for is the progress bar to pop up when the user presses the button, and remain on the screen until the method is complete. I don't want the user to navigate around the app during this time.
You can try the below code to check if the progressBar will be visible
new Thread(new Runnable() {
public void run() {
writeFile();
}
}).start();
I have a fragment using pull-to-refresh to refresh my listview, I know when user pull by hand, OnRefreshListener triggered, But i want this:
When users open this fragment, they don't have to pull by hand, fragment itself pull to refresh and show loading animation. Please tell me what to do.
Thanks.
It might be a bit late but for reference i had the same issue and this is how i solved it:
When you call:
mPullToRefreshLayout.setRefreshing(true);
It wont trigger the circle to animate automatically. To show the loading circle you need to use a runnable, this adds a delay in the UI thread so that it shows the circle animation inside the ui thread. You do this by using the below code in place of the above:
mPullToRefreshLayout.post(new Runnable() {
#Override public void run() {
mPullToRefreshLayout.setRefreshing(true);
}
});
Hope it helps.
try using youPullToRefreshList.setRefreshing()
In my main activity, I would like to have it set up, so that I first get met by a contentView just showing a background and some text. After X seconds, I want to change to my other view (GLSurfaceView).
This is obviously something I am doing completely wrong.
This is how I've imagined it could've been done (it's all in the onCreate method):
setContentView(R.layout.main);
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
}
viewer = new Viewer(this);
setContentView(viewer);
Where layout Main is what I want to show at the beginning and Viewer is my GLSurfaceView class.
What happens is that it just goes black for 10 seconds and then it starts loading the objects I've got that is shown through OpenGLES.
There's nothing wrong with the layout Main, since it works if I just erase the lines under where the Thread.sleep takes action. Though, nothing happens before the Thread.sleep is over...
With that said, my questions are following:
Why is the contentView not changing until after Thread.sleep is done?
What would be an appropiate solution to what I want to achieve?
I'm assuming this in your onCreate() and thats why you are seeing nothing.
The way I would implement this is to start a thread using AsyncTask sleep in the doInBackground and in the onPostExecute set up the new view.
Don't make sleep the main thread(UI thread).Use a threads,AsynkTask or TimerTask for that type of works instead.
You're not sleeping the UI thread in the way you think you are.
The simplest thing for what you're looking to achieve is to separate the views into separate activities and let Android handle the transition between the views. It adds another file to your codebase, but it's fairly straightforward. Let's say your initial, plain view (R.layout.main) is for a SplashActivity activity, and your post-splash view goes into PostSplashActivity. Then you could do something like this:
public class SplashActivity extends Activity {
private static long DELAY = 10000; //milliseconds;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
new Handler().postDelayed(
new Runnable() {
#Override
public void run() {
Intent postSplash = new Intent(SplashActivity.this, PostSplashActivity.class);
SplashActivity.this.startActivity(postSplash);
SplashActivity.this.finish();
}
}, DELAY);
}
}
This will draw your R.layout.main layout, and then puts a startActivity call for your PostSplashActivity on the message queue and tells the queue to wait DELAY milliseconds to execute it.
It seems like you are making the main thread sleep. This may be why the code is running tell after.
It sounds like you want something like a splash screen. I like to think of these as separate to the following screen, so always use a separate activity rather than calling setContentView twice. You'd still need to sleep in a thread.
Just personal preference though...
This is the first time I ask something, so if there is something wrong just tell me and I´ll try to fix it ASAP.
We have a customer that wants us to login in their servers with a native Android app, but without giving us a custom way to do this. They want us to use the current website they have to log and, after authentication takes place, retrieve within the browser a XML which contains the data we need. After that, use the data in the native app. All of this with the user not knowing/seeing that a browser is being used. A total mess IMHO.
Of course, I have never tried this approach in the past and my first tests make me feel like this is impossible (or extremely difficult) to achieve. Whenever I try to load the URL in a hidden WebView the default browser pops up showing the website.
My main question is, is it possible to load a webview and work with it (invoke javascript, etc...) in the background?
Thank you.
You could set the WebView to hidden by default with the attribute android:visibility="gone", interact with it at runtime then when you need to show it to the user after you've loaded data, just call setVisibility(View.VISIBLE)
Hope this helps!
Ofc, you must to use a Thread :
protected void getPage(){
Thread th = new Thread(){
public void run(){
//Download and make things
mActivity.runOnUiThread(new Runnable() {
#Override
public void run() {
//print int the activity
}
});
}
};
th.start();
Remember, and thats is VERY important, you CANT draw from thread to the main activity. The only who can draw in the screen is the main activity. You can draw with 2 methods:
One , with the method _mActivity.runOnUiThread(new Runnable() {_ like the example i put.
Two, use a Handler to send messages from thread to main activity with the information that you want to draw.
*Main activity is the activity that its in the screen in that moment, not the first activity of the app