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.
Related
android xamarin code
lockctl = ((PowerManager)GetSystemService(Android.Content.Context.PowerService)).NewWakeLock(
WakeLockFlags.Partial, "tag"); //cpu on
lockctl.Acquire();
WifiManager wifi = ((WifiManager)GetSystemService(Android.Content.Context.WifiService));
lockwifi = wifi.CreateWifiLock(Android.Net.WifiMode.Full, "wifilock");
lockwifi.SetReferenceCounted(true);
lockwifi.Acquire();
`
I am making a cctv app. The problem is that the screen turns off after a day.
I want to keep this screen on.
I want the screen to stay on even after several days
Here is the code you can use to keep the screen awake and never goes off while your application is running.
getWindow(). addFlags (WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
This is one of the flag we can set to make the screen awake.
Put this inside your activity ex:- MainActivity inside onCreate().
If your app is running foreground, you can keep the screen on by add the following code into the each activity's OnCreate method of your project:
protected override void OnCreate(Bundle savedInstanceState)
{
....
this.Window.AddFlags(Android.Views.WindowManagerFlags.KeepScreenOn);
}
Or you can just add the android:keepScreenOn="true" in the every layout.xml file, such as:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:keepScreenOn="true"
android:layout_width="match_parent"
android:layout_height="match_parent">
</RelativeLayout>
For more information, you can check the offical document about the keeping screen on.
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)
Hi everyone I have an Activity which is loading after I click on an Item inside my Listview.
This activity shows the location inside a MapView like this:
<FrameLayout
android:id="#+id/mapContainer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_toEndOf="#+id/imageView"
android:layout_above="#+id/button"
android:layout_below="#+id/imageView"
android:layout_alignParentStart="true"
android:layout_marginTop="10dp" >
<TextView
android:id="#+id/loading"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Loading Map..." />
</FrameLayout>
The Problem is, that I want to show the Map to the User later on if he/she clicks on a button.
But the Activity is loading very slow and even has a black blank screen before showing anything. This looks very unprofessional, and seems wrong.
I tried making the MapView invisible first and show it when user hits the button, but it is loading when the activity starts.
I'am trying following code:
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_single_event);
mapView = new MapView(SingleEvent.this);
mapView.onCreate(savedInstanceState);
com.google.android.gms.maps.MapView.LayoutParams mapParams = new com.google.android.gms.maps.MapView.LayoutParams(com.google.android.gms.maps.MapView.LayoutParams.MATCH_PARENT,220);
mapContainer = (FrameLayout) findViewById(R.id.mapContainer);
mapContainer.addView(mapView, mapParams);
This one is working it is showing the map, but the activity is loading to long with a black blank screen, until my activity is loaded.
Is there any way to first load the activity and after that load the MapView on a button click?
I'am trying to do something like this:
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
mapView = new MapView(SingleEvent.this);
mapView.onCreate(savedInstanceState);
com.google.android.gms.maps.MapView.LayoutParams mapParams = new com.google.android.gms.maps.MapView.LayoutParams(com.google.android.gms.maps.MapView.LayoutParams.MATCH_PARENT,220);
mapContainer = (FrameLayout) findViewById(R.id.mapContainer);
mapContainer.addView(mapView, mapParams);
}
},1000);
But with that code, the Map isnt loading its only showing the grey blank grid.
I think its because of the savedInstanceState but maybe there is a work around?
I tried to save the Bundle savedInstanceState, loading like above.
You can use a MapFragment. In onCreate(), you can set visibility to invisible. When the map is ready, onMapReady() will be called and you can configure map settings there.
I had the same issue which was occurring due to hardware accelartion and largeheap. I had used these features at application level. But I removed them from the app level and used them in the activity they used. The Activity which contained SupportMapFragment didn't need these features. So I moved this code from Application tag to Activity in Manifest.
Issue was in Manifest.
<application
android:label="#string/app_name"
android:theme="#style/AppTheme"
android:hardwareAccelerated="false"
android:largeHeap="true">
Remove from Manifest and Use in the Activity
<activity
android:name="com.mycompayname.activities.SignUpActivity"
android:hardwareAccelerated="false"
android:largeHeap="true"/>
In My application i am setting orientation of the application on button click, using setRequestedOrientation(), My application has one webview which displays local web page.
I am using solution as mentioned in below link, to stop reloading of page when orientation changes.
http://www.devahead.com/blog/2012/01/preserving-the-state-of-an-android-webview-on-screen-orientation-change/
Only difference is that i am not having onSaveInstanceState and onRestoreInstanceState in my activity.
What happens in my case is that, my web view does not reload when i change the orientation but it just re-renders the UI upon changing the orientation.
It happens like it first displays the UI and then it displays the white blank screen for few seconds and then again it displays UI.
How can i workaround it?
Once upon a time I used their implementation however I after reading up on the Android documentation I realized that much of their code was pointless since registering for config changes (in the manifest) means that your activity won't be destroyed as it normally is.
Long story short, you don't need to use a FrameLayout as a container for your webView, you may not need onConfigurationChanged, etc. If I get some time I will post some code as an example.
For now, make sure you have the following in your manifest file
android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
instead of
android:configChanges="keyboard|keyboardHidden|orientation"
since on orientation change devices may get get a screenSize change
EDIT This is what I have done (skimmed from one of my projects so I may have missed minor details)
in AndroidManifest.xml
<activity android:name=".Activities.WebWrapperActivity"
android:theme="#android:style/Theme.NoTitleBar"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize"/>
web_wrapper_activity_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<WebView android:id="#+id/web_wrapper_activity_web_view"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scrollbarStyle="outsideOverlay"/>
</LinearLayout>
The Activity (or a portion of it)
public class WebWrapperActivity extends Activity {
private WebView _webView;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.web_wrapper_activity_layout);
init();
}
private void init() {
_webView = (WebView) findViewById(R.id.web_wrapper_activity_web_view);
_webView.setScrollbarFadingEnabled(true);
_webView.getSettings().setLoadsImagesAutomatically(true);
_webView.getSettings().setJavaScriptEnabled(true);
_webView.getSettings().setAllowFileAccess(true);
_webView.getSettings().setSavePassword(false);
_webView.getSettings().setPluginState(WebSettings.PluginState.ON);
_webView.loadUrl(“http://www.google.com”);
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
_webView.saveState(outState);
}
}
As i mentioned previously, you may not need onConfigurationChanged if your webView is the only view in the Activity.
If you have any issues let me know
I am developing an app that is very similar to the typical newsreader app. I have a Listview in a fragment on the left side of the screen and the right side shows the details of the selected item if we're in landscape view. Otherwise the details fragment is shown in its own Activity. I have this working just fine.
However there is one caveat: I only want it to behave this way on larger screen sizes (probably only tablets but that's subject to change). On smaller devices I want to see only the the Listview fragment and launch the details fragment in its own activity no matter the orientation. I also have this working.
The problem I currently have is in the Details Activity and how to determine when to finish() and return back to the previous activity to show the fragments side by side. I have the following code that works for larger devices but doesn't allow smaller devices to view this activity and thus the details fragment at all:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getResources().getConfiguration().orientation ==
Configuration.ORIENTATION_LANDSCAPE) {
finish();
return;
}
How can I determine that going back to the previous activity will allow the fragments to be displayed side by side?
Eureka! My solution is to provide an alternate layout for the Details Activity that was empty. After I inflate the layout I can check to see if the fragment I am expecting is in the layout and if it isn't then I finish().
details_view.xml in /res/layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<fragment
android:name="com.website.DetailsFragment"
android:layout_width="0dp"
android:layout_height="match_parent"
android:id="#+id/details_fragment"
android:layout_weight="75">
</fragment>
</LinearLayout>
details_view.xml in /res/layout-[screen size]
This one is for any screen size that you do not want to display the Details fragment in its own activity in landscape mode (more or less tablets in my case).
<?xml version="1.0" encoding="utf-8"?>
<!-- Note: This file has an empty layout to notify
DetailsViewActivity that we should go back to landscape
and view the fragments side by side -->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
</LinearLayout>
Simply put the empty details_view.xml file in any layout directory that has the layout file that allows to show the fragments side by side.
Finally the code for DetailsViewActivity to exit if we want to go back to side by side:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.details_view);
mDetailsView = (TopicViewFragment)getSupportFragmentManager()
.findFragmentById(R.id.details_fragment);
// We can handle the fragments side by side in the previous activity
// so lets go back there
if ((mDetailsView == null || !mDetailsView.isInLayout()) &&
getResources().getConfiguration().orientation ==
Configuration.ORIENTATION_LANDSCAPE) {
finish();
return;
}
I would have liked a little less duplication of data but this solution isn't bad. It only forces you to copy one extra layout file into the same directory that you have the side by side fragments layout file. Not too bad really.
I think the following also work without the the usage of an empty layout.
package de.vogella.android.fragments;
import android.app.Activity;
import android.content.res.Configuration;
import android.os.Bundle;
import android.widget.TextView;
public class DetailActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Need to check if Activity has been switched to landscape mode
// If yes, finished and go back to the start Activity
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
finish();
return;
}
setContentView(R.layout.details_activity_layout);
Bundle extras = getIntent().getExtras();
if (extras != null) {
String s = extras.getString("value");
TextView view = (TextView) findViewById(R.id.detailsText);
view.setText(s);
}
}
}