Android progress spinner, able to display but not to hide programmatically - android

I am trying to specify a progress spinner as I have done in my testLayout.xml file, and then programmatically display and hide it as I have done in my activity code below. Whats happening however is that the progress wheel will display, but it never goes away even though I have setProgressBarVisibility(false); at the end. Any ideas? Thanks for input
layout/testLayout.xml
<Button android:layout_width="fill_parent"
android:layout_height="wrap_content" android:id="#+id/ButtonNew"
android:text="New" android:layout_alignParentBottom="true" />
<ListView android:layout_width="fill_parent"
android:layout_height="fill_parent" android:id="#+id/list"
android:layout_alignParentTop="true" android:layout_above="#id/ButtonNew" />
<ProgressBar style="?android:attr/progressBarStyleLarge" android:layout_width="wrap_content" android:id="#+id/progressBar1" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:layout_centerHorizontal="true"></ProgressBar>
</RelativeLayout>
TestActivity.java
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().requestFeature(Window.FEATURE_PROGRESS);
setContentView(R.layout.testLayout);
setProgressBarVisibility(true);
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
setProgressBarVisibility(false);
}

Well there is a problem in your code because your Thread.sleep call will cause the onCreate to wait 5 seconds before continuing. You should never perform a Thread.sleep call on the main UI thread as it will cause the application to not respond for that amount of time. Now with regards to the ProgressBar, it seems that you are not correctly using the setProgressBarVisibility with your xml file. Those functions should be used for ProgressBar's that are contained in the title bar. You should just use findViewById(R.id.progressBar1).setVisibility(View.Gone) to hide or View.Visible to show. But if both of these calls are done inside of the onCreate you will only see the one that was called last. This is because no ui is actually shown to the user until the activity has returned from onResume and onCreate.

Related

How can I run code slightly later than the onCreate() and onStart() events?

I have a list view that is populated through a string-array in the xml, not run time and I'm trying to set the background color of specific items in the list using:
listView.getChildAt(x).setBackgroundColor(Color.BLACK);
I need this to happen before it's visible, but it gives an error when I use it in onCreate() or onStart(), but works if I run it on a button press. I've tried searching for an answer but can't seem to find any event that happens late enough for it to work.
getView() would be the best place to do this, but you don't have access with the way you are doing this with android:entries=.... Instead, you can post a runnable to the message queue to change the color after layout occurs like the following:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.layout).post(new Runnable() {
#Override
public void run() {
findViewById(R.id.view).setBackgroundResource(android.R.color.holo_red_dark);
}
});
}
Here I have used a simple View for demonstration but the same technique should work for your ListView.
Here is the XML I used if you want to work with it:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<View
android:id="#+id/view"
android:layout_width="100dp"
android:layout_height="100dp"
android:background="#android:color/holo_blue_light" />
</LinearLayout>
Here's a link to post. The runnable kicks off before onStart(). So, if that's a requirement, then this way may not work for you.

How to implement indeterminate loading screen

I am building an app that uses a REST interface to fetch data. Usually, I would call setProgressBarIndeterminateVisibility(true); to let the user know the app is waiting for data. However, this seems to be deprecated:
Progress bars are no longer provided in AppCompat.
When looking at the GMail app, I see there is an indeterminate progressbar (loading icon) full screen, where the data is going to come.
How would I implement that correctly? Some of activities are extended from ListViewActivity and use the setEmptyView to show a simple TextView when no data is available. Some are more elaborate layouts.
I could think of using setVisibility(View.GONE), but wondering if this is the "right" way to do it.
Yes. That is the right way. Just layout everything where they should be on the XML and call setVisibility on your progressBar when necessary.
There're usually two ways of kwnoing "when" to call.
on your REST callbacks (e.g. onSuccess(), onStartLoading())
using a DataSetObserver on your adapter (which is exactly what the ListView does). Like the following code:
.
#Override
protected void onStart(){
super.onStart()
observer.onChanged();
adapter.registerDataSetObserver(observer);
}
#Override
protected void onStop(){
super.onStop()
adapter.unregisterDataSetObserver(observer);
}
private DataSetObserver observer = new DataSetObserver(){
#Override
public void onChanged() {
progress.setVisibility(adapter.getCount()==0?View.VISIBLE:View.GONE);
}
}
Wrap your content layout into FrameLayout. Add to FrameLayout something like this:
<LinearLayout
android:id="#+id/loading_progress"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
android:visibility="invisible">
<ProgressBar
android:layout_width="50dp"
android:layout_height="50dp"
android:indeterminate="true"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="Loading data..."/>
</LinearLayout>
And then switch content / progress layers in code using .setVisibility(View.VISIBLE) / .setVisibility(View.INVISIBLE)

how to stop PullToRefresh animation of ListView

I used Android-PullToRefresh from chrisbanes to show refresh progress in my app.
I load data in AsyncTask, so I start refreshing by calling mPullRefreshListView.setRefreshing();
in onPreExecute method
and stop refreshing by
calling mPullRefreshListView.onRefreshComplete();
in onPostExecute method.
That works fine. But the problem happens when network down. Because I won`t use AsyncTask when network down any more, instead I load local cache.
I don`t want to show the PullToRefresh animations when refreshing if network down, but since it registered the setOnRefreshListener, every time when user pull down the ListView, it shows the refreshing animations, and never got disappear.
I tried to disable the animation by calling mPullRefreshListView.onRefreshComplete();, but it does`t help.
if (!Utils.isNetworkOn()) {
if (mPullRefreshListView.isRefreshing())
mPullRefreshListView.onRefreshComplete();
}
I feel very confused about this, anyone knows how to handle this?
Thanks in advance.
It is better to use SwipeRefreshLayout since Chris Bane's project is no longer maintained:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<android.support.v4.widget.SwipeRefreshLayout
android:id="#+id/srl_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<ListView
android:id="#+id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</android.support.v4.widget.SwipeRefreshLayout>
</LinearLayout>
In fragment:
private void pullToRefreshForConfiguredList(View view) {
mConfiguredSwipeRefreshLayout = (SwipeRefreshLayout) view
.findViewById(R.id.srl_layout);
mConfiguredSwipeRefreshLayout
.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
// call Method to be refreshed
if (mConfiguredSwipeRefreshLayout.isRefreshing())
mConfiguredSwipeRefreshLayout.setRefreshing(false);
}
});
mConfiguredSwipeRefreshLayout.setColorScheme(android.R.color.black,
R.color.red, android.R.color.black, R.color.red);
}

Splash Screen With ProgessBar [duplicate]

This question already has an answer here:
Closed 10 years ago.
Possible Duplicate:
Android Activity Life Cycle
I am able to create a simple Splash Screen for my app using Themes and it works just fine. However, there may be times that the app needs to refresh a large amount of data and I want to display a ProgressBar to the user letting them know what's going on while they wait. So I ditched the Theme and created a layout resource and set that as the ContentView for my Splash Activity, but nothing displays. Not only does none of my content display (completely black screen) but the title bar continues to show up despite trying to hide it every way possible.
Splash.axml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="15dp"
android:src="#drawable/logo" />
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center">
<ProgressBar
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="10dp" />
<TextView
android:id="#+id/progressText"
android:text="Loading..."
android:textSize="20dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dp" />
</LinearLayout>
Splash.cs
[Activity(MainLauncher=true, NoHistory = true)]
public class Splash : Activity
{
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
RequestWindowFeature(WindowFeatures.NoTitle);
Window.SetFlags(WindowManagerFlags.Fullscreen, WindowManagerFlags.Fullscreen);
SetContentView(Resource.Layout.Splash);
string lastUpdated = PreferenceManager.GetDefaultSharedPreferences(this).GetString("LastInventoryUpdate", null);
DateTime lastUpdateDate = Convert.ToDateTime(lastUpdated);
TimeSpan span = DateTime.Today - lastUpdateDate;
if (string.IsNullOrEmpty(lastUpdated) || span.Days > 30)
{
TextView progressText = (TextView)FindViewById(Resource.Id.progressText);
progressText.Text = "Updating parts database. May take several minutes...";
InventoryRepository repository = ((MyApp)Application).Inventory;
repository.Execute();
}
StartActivity(typeof(Login));
}
}
Still shows logo and title in the title bar and absolutely nothing for content. Even tried taking all the AsyncTask and StartActivity stuff out and just tried loading the Activity with the splash layout. It does eventually show up, but it shows as the black screen for a long while first. Can't imagine why as this is my main launcher and there is literally nothing going on but setting the content of the activity.
And as far as the TitleBar showing up, I've also tried adding this to my manifest (which I currently have working in another activity just fine)
<activity android:name="app.MyApp.Splash" android:theme="#android:style/Theme.NoTitleBar.Fullscreen"></activity>
If I include a Theme for the activity, the TitleBar goes away, but my layout resource never displays.
Wouldn't you know after struggling all day I figured out a large part of the problem minutes after posting. In short, I put the Theme back on the Splash Activity which now shows while everything is initially loading and usually redirects to Login before the content is ever set, which is perfect. But I changed my OnCreate as follows:
[Activity(MainLauncher=true, NoHistory = true, ScreenOrientation = Android.Content.PM.ScreenOrientation.Landscape, Theme = "#style/Theme.Splash")]
public class Splash : Activity
{
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
RequestWindowFeature(WindowFeatures.NoTitle);
Window.SetFlags(WindowManagerFlags.Fullscreen, WindowManagerFlags.Fullscreen);
SetContentView(Resource.Layout.Splash);
string lastUpdated = PreferenceManager.GetDefaultSharedPreferences(this).GetString("LastInventoryUpdate", null);
DateTime lastUpdateDate = Convert.ToDateTime(lastUpdated);
TimeSpan span = DateTime.Today - lastUpdateDate;
if (string.IsNullOrEmpty(lastUpdated) || span.Days > 30)
{
SetTheme(Resource.Drawable.bg_black);
TextView progressText = (TextView) FindViewById(Resource.Id.progressText);
progressText.Text = "Updating parts database. May take several minutes...";
InventoryRepository repository = ((MyApp) Application).Inventory;
repository.Execute();
}
else
StartActivity(typeof (Login));
}
}
Main difference is that I only call StartActivity if I'm not running my AsyncTask. Otherwise, I call StartActivity from OnPostExecute of my AsyncTask. Also, be sure to set the background property of all your views in the splash layout. Since I left the theme on the activity, if you don't do this, your theme will show up as the background for EVERY view.

NullPointerException in onCreate() when using findViewById - setContentView is used before?

Hello I'm writing a little Android app (Version 2.3.3). Now i get this strange NullPointer Exception in this very basic code:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.mainmenu);
newDeck = (Button) findViewById(R.id.newDeckB);
loadDeck = (Button) findViewById(R.id.loadDeckB);
viewEdition = (Button) findViewById(R.id.viewEditionB);
newDeck.setOnClickListener(this);
loadDeck.setOnClickListener(this);
viewEdition.setOnClickListener(this);
}
Im using this simple layout at the moment in main menu.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<Button android:id="#+id/newDeckB"
android:text="New Deck"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
<Button android:id="#+id/loadDeckB"
android:text="Load Deck"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
<Button android:id="#+id/viewEditionB"
android:text="View Edition"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
<TextView android:id="#+id/currentDeckTextView"
android:text="Default Deck"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
Now my problem is a nullpointexception in line 25, which is the line where i set the first clickListener
newDeck.setOnClickListener(this);
Using the debugger i figured out that the button newDeck is null. I searched a lot in the web but the only answer to such kind of problem was to check that the setContentView is set before the findViewById. This is obviously the case here.
I would be very glad for any kind of advice.
Thx in Before!
Get your views and set the listeners in onPostCreate() method.
There are two events that the App expects, onCreate(), and onStart()
Which one you put this function in, matters.
I had to move "findViewByID" from onCreate() to onStart()
#Override
protected void onStart() {
// use findViewById() here instead of in onCreate()
}

Categories

Resources