I am developing an Android app with a Navigation Drawer working this way: the user opens the app and a Tutorial (an activity with a pager sliding fragments, called ScreenSlideActivity.java) pops up; when the user finishes sliding the tutorial, he presses the "finish" button resulting in the initialization of the MainActivity (creating a drawerLayout, drawerToggle etc.)
What I need to do is opening the Tutorial activity just once, after the app's first launch.
I've tried with this code in the main Activity:
if (savedInstanceState == null) {
SelectItem("tutorial");
}
making sure that ScreenSlideActivity.java is immediately started. The problem with this solution is that when the tutorial is opened, from there I'm not able to access MainActivity.java anymore, neither from the "up" botton neither from the Tutorial's last page's "finish" button, probably because for some reason I don't have the main as the parent activity anymore.
Then I've tried this solution change application's starting activity - Android modifying the manifest xml file. Adding:
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
to ScreenSlideActivity.
The problem with this solution is that it changes the structure of my project, making my ScreenSlideActivity.java as the Main and Launching Activity (and therefore from here I cannot access the MainActivity anymore) while all I want to do is to display it once.
What else can I do?
You can use SharedPreferences to check/set if it's the first time opening the app
String preferences_name = "isFirstTime";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
...
firstTime();
}
...
public void firstTime(){
SharedPreferences sharedTime = getSharedPreferences(preferences_name,0);
if (sharedTime.getBoolean("firstTime",true))
{
//Your tutorial code
sharedTime.edit().putBoolean("firstTime",false).apply();
}
else
{
//When not using tutorial code
}
}
Similiar question here : https://stackoverflow.com/a/13237848/4555911
What I usually to deal with temporary screens is similar to your first solution:
In your MainActivity check if it is the first time the user launches the application. The most common way to do this is using SharedPreferences and checking if a boolean is true or false.
If it is the first time, you start a new activity for your ScreenSlideActivity class with no particular flags. your MainActivity will be in the stack:
MainsActivity -> ScreenSlideActivity
When the users press the finish button you can call the finish() method on your ScreenSlideActivity which will remove the activity from the stack and bring back your MainActivity.
Related
I am very new to Java. I am doing a school project at the moment and I have my main activity, then I have a settings activity. I am trying to modify the xml from the main activity with the settings activity. I am able to modify the settings xml file with the settings.java, but I would like to modify the main activity xml with settings.java
public class Settings extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_settings);
// Get the Intent that started this activity and extract the string
Switch switchButton;
final RelativeLayout mRelativeLayout = (RelativeLayout) findViewById(R.id.activity_settings);
final RelativeLayout mRelativeLayoutMain = (RelativeLayout) findViewById(R.id.activity_main);
switchButton = (Switch) findViewById(R.id.switch1);
switchButton.setChecked(true);
switchButton.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton compoundButton, boolean bChecked) {
if (bChecked) {
mRelativeLayoutMain.setBackgroundColor(Color.GRAY);
mRelativeLayout.setBackgroundColor(Color.GRAY);
} else {
mRelativeLayoutMain.setBackgroundColor(Color.WHITE);
mRelativeLayout.setBackgroundColor(Color.WHITE);
}
}
});
if (switchButton.isChecked()) {
mRelativeLayoutMain.setBackgroundColor(Color.GRAY);
mRelativeLayout.setBackgroundColor(Color.GRAY);
} else {
mRelativeLayoutMain.setBackgroundColor(Color.WHITE);
mRelativeLayout.setBackgroundColor(Color.WHITE);
}}
public void toast1(View view) {
android.widget.Toast.makeText(this, "Created by Cody Walls and Tommy Serfas", android.widget.Toast.LENGTH_LONG).show();
}
/*public void switch1(View view) {
ScrollView mScrollView = (ScrollView) findViewById(R.id.scrollView);
mScrollView.setBackgroundColor(Color.GRAY);
}*/
}
In the Code I am trying to change the background of the main activity xml with :
mRelativeLayoutMain.setBackgroundColor(Color.GRAY);
and when I run the app and click the intent it will crash with the error:
"java.lang.NullPointerException: Attempt to invoke virtual method
'void android.widget.RelativeLayout.setBackgroundColor(int)' on a null
object reference"
I think the easiest way is to create an PreferenceManager.SharedPreferences, in which I recommend you to store current app data. This will help you not to loose any changes in app after you exit the it. Here is short instructions:
Create button in settings activity which will change something in main activity.
Create onClickListener for your button.
Use .SharedPreferences to store was you button clicked or not. (I recommend storing boolean variables, this way you can store was button clicked or not.)
I both of your activities in onCreate method call .getSharedPreferences to read saved app values. (I mean to read was the button clicked or not.)
Use app values you got from 4. to change any element in activity. (For example if you stored that button was clicked, then change some TextView text or etc.)
I hope you understood the idea.
Link to the Android developer tutorial about App key values storing & saving
Link to the StackOverflow much easier explanation & examples
There are a couple of ways of doing this (Some of which depends on how you are switching back and forth from each activity). It also depends on what things you are changing.
From your settings page, as you are changing different settings, you'll save this content within Preferences. (You can see more how to use Preferences here: https://examples.javacodegeeks.com/android/core/ui/settings/android-settings-example/ or by just Googling it).
On you main activity, depending on how you come back to it (onStart most likely), you can setup the things you need to programmatically.
So, you may need to do a little research on the Android lifecycle and how each cycle works (https://developer.android.com/guide/components/activities/activity-lifecycle.html), how to program the UI programmatically through Java (http://startandroid.ru/en/lessons/220-lesson-16-creating-layout-programmatically-layoutparams.html), and the Preferences Android library to save certain settings.
The xml isn't meant to be "altered". You can change the UI programmatically. It's possible to build an Android app without any xml. When Android was first built, it didn't use the xml to create the UI. It was all done through Java. It was then added to use xml to create your activities or fragments or any UI component. This made things easier for more static activities or activities with very little dynamic content.
I searched a lot but i did not find my answer. I have developed an android application where on the very first lunch user will be shown a welcome screen made of viewpager. The problem is i don't know which place is the best to put the welcome activity code in my application.
The simplest way it could be that in the main activity at the very fist line even before super.onCreate(), inside onCreate method where i try to get the shared preference value and then evaluate whether it is fist lunch. If it is, then i start the welcome activity as shown below
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
boolean welcome = sharedPreferences.getBoolean(getString(R.string.key_welcome), true);
if (welcome) {
// go and start welcoming activity
Intent intent = new Intent(this, WelcomeSlideActivity.class);
startActivity(intent);
}
super.onCreate();
}
}
But i found another approach to deal with it. It is Application class. Since Application class is the first one, which runs even before any other codes in my application. So i thought, i would be nice to do it there as shown below
public class App extends Application {
#Override
public void onCreate() {
super.onCreate();
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
boolean welcome = sharedPreferences.getBoolean(getString(R.string.key_welcome), true);
if (welcome) {
// go and start welcoming activity
Intent intent = new Intent(this, WelcomeSlideActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
}
}
So i am in dilemma, which one would be the best option to choose. And i am even not sure if i am doing it in the right way since there is no such documentation in android developer website or anywhere.
Have a look at how to create splash screens the correct way. https://www.bignerdranch.com/blog/splash-screens-the-right-way/
As for using the Application class - this is primarily used for Application-wide configuration for maintaining a global application state. Hence starting an activity from here does not make much sense as it's purpose has changed into becoming an entry point into the application rather than providing state for the app as a whole.
Furthermore, why not make the WelcomeSlideActivity the first 'launcher' activity? Then in there, you can create the logic of whether to launch the next activity without history or whether to show the current view.
Ideally, you should create a splash screen activity, which determines whether to show the WelcomeSlideActivity Or the MainActivity. The advantage of this is that while he app determines which Activity to launch, the user is presented with a splash screen that informs the user that the app has started
Here is my source code of launcher activity.
I search a lot on stack overflow but nothing getting good answer
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_select_lang);
init();
}
private void init(){
spnLanguage = (Spinner)findViewById(R.id.spnLanguage);
btnNext = (Button)findViewById(R.id.btnNext);
btnNext.setOnClickListener(this);
}
Android apps do take some amount of time to start up, especially on a cold start. There is a delay there that you may not be able to avoid
https://www.bignerdranch.com/blog/splash-screens-the-right-way/
In the AndroidManifest file of your starting Activity, mention a transparent Theme
<activity
android:name="Your activity name"
android:theme="#android:style/Theme.Translucent.NoTitleBar" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
In my case delay was bit more. After searching a lot I found that it is because of android studio auto run feature. After disabling the auto run issue is solved.
I had a similar problem some time ago.
The activity is displayed to the user when it reaches the onStart() method. Your init() seems to take some time so until it finishes, you will only see the empty activity.
You could either trigger all heavy background work (that is not needed for the initial GUI setup) in a later method or first call another activity acting as splash screen if you have to keep all content of init() where it is.
I had also same issue please find below the question as well as the resolution:
White screen is displayed first time on gradle build.
I want to create an activity that will hide the keyboard. The activity will keep on running in the background as a service and prevent the keyboard from being visible for all the apps. As in the keyboard will not come up unless the activity is stopped. Can anyone point me towards the correct source?
put below code in your manifest file:
<activity
android:name=".View.ViewRegistration"
android:configChanges="keyboardHidden"
android:windowSoftInputMode="stateHidden" />
I hope its useful to you.and you can call below method in every activity onresume() and onPause().
public static void hideKeyboard(final Activity activity) {
InputMethodManager inputManager = (InputMethodManager) activity
.getSystemService(Context.INPUT_METHOD_SERVICE);
if (activity.getCurrentFocus() != null) {
inputManager.hideSoftInputFromWindow(activity.getCurrentFocus()
.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
}
}
An Activity can not just be kept "running in the background as a service".
From the documentation:
An activity is a single, focused thing that the user can do. Almost all activities interact with the user, so the Activity class takes care of creating a window for you...
You would need to create an Service. I haven't tried hiding the keyboard via a service, but a wild guess is, that it isn't possible.
A solution could be to create your own keyboard, that the user would then need to switch to.
You can add this one line of code in your manifest for all those activities where you need to hide the keyboard:
android:windowSoftInputMode="stateHidden"
For example:
<activity
android:name="com.example.yourappname.MainActivity"
android:screenOrientation="portrait"
android:windowSoftInputMode="stateHidden"
>
My app crashec when rotating the device. I know it crashes because whenI rotate the screen it tries to create new View to draw and display but how can it create the view and display it properly on the launch but crashes when trying to create the second new view?
I dont know what part of my code I should post here? Can you give a clue to solve this problem?
I found something usefull. I put try/catch statement and now when I rotate the device, it doesnt crash but displays a blank page, when I re-rotate to the old position it display the page. here is my code
#Override
protected void onCreate(Bundle savedInstanceState) {
try{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mSectionsPagerAdapter);
} catch (Exception e) {
Log.i("my_error", e.getMessage());
}
}
but eclipse cannot catch the exception.
How can I solve this problem?
There are two possible ways to do this:
1) You don't care about the orientation change of the screen and you just want to be "resized". Just add the following properties in your Manifest file:
<activity
android:name=".SplashScreen"
android:configChanges="orientation|keyboardHidden|screenSize" ... />
and add this lines of code in your activity:
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// do nothing, just override
}
2) You do care about the orientation change. Then there are a couple of things that you should know about the activity lifecycle in an orientation change.
Firstly the onConfigurationChanged() is called and you should store in a Bundle everything that you need. For example the user has editted an EditText and you should save the value.
Why to do that? Because afterwards the onCreate() method will be called again in order for you to implement a different layout or alter something in the Views. You should then take the previously saved Bundle and restore the variables that you saved in your newly created layout.
Just add the android:configChanges="orientation" to your activity
<activity android:name=".MyActivity"
android:configChanges="orientation"/>
if you given like this, then oncreate will not called if your screen orientation is changed.
If you need more information about this you can check this link
There are a couple of things you can do:
1) Ignore screen orientation changes. If your app is only designed for portrait mode, most likely it won't look good in landscape mode and vice versa. Best is to specify the target orientation in your activities.
2) If you want to allow orientation changes, then you should have written some code re-create the view with different/modified layout. Mind sharing the code with us?
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
//Override this and recreate your view or set adapter here
}
Dont forget to add android:configChanges="orientation" in your manifest.
On a side note you can fix orientation through manifest like this -
android:screenOrientation="portrait"
Add this to your Activity tag in the manifest:
android:configChanges="orientation|screenSize"
This will cause that the activity is not recreated on rotation change.
The flag sreenSize is for newer devices(API level 13 or higher), with including only the orientation flag the activity will stil recreate when rotating on devices running API level 13 or higher.