Hi i'd like to develop a Dating Sim App for Android with eclipse.
The Game consists of Scenes.
Each Scene consists of one Background Picture (City), one Charakter Picture and one Balloon Image with text in it (Text which the Character says).
When i tap the Balloon, the next Scene will appear, the spoken text will change, maybe one of the pictures will change too.
It's a very simple game it just consists of .png Pictures and Text Strings.
This is my problem:
I assumed that every scene has to be an activity (each of my scenes has it's own layout.xml)
So i created now like 200 layouts, and just started to do the java classes for each activity (each class states, when a button is pressed, please go to the next layout file.)
It all worked pretty well until activity 25 or so appeared. When i tap it, the game crashes.
I tried to fix it with "finish" (please see code below) but it didn't help. Maybe i used it the wrong way?
I tried to bypass the activity that crashes (switched from Activity 25 to Activity 30 instead from 25 to 26) But it also crashes.
Questions 1:
Do i have to many Activites loaded? How can i fix it?
I really would like to continue with "Each Scene is one Activity" if possible, because it's the most easiest way to do it for now.
Question 2:
How would a professional Programmer do this?
Would he create a flash Animation for this and insert it as a view in ONE Activity?
Or just plain Java code?
Thank you very much in common.
package com.irbstudios.zargoslovestories;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Typeface;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
public class game_p1_prestory_00001 extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.game_p1_prestory_00001);
TextView tx = (TextView)findViewById(R.id.textView1);
Typeface custom_font = Typeface.createFromAsset(getAssets(),
"fonts/rosemary.ttf");
tx.setTypeface(custom_font);
Intent svc=new Intent(this, BackgroundSoundService.class);
startService(svc); //OR stopService(svc);
}
protected void onPause() {
super.onPause();
overridePendingTransition(0, 0);
}
public void onButtonClick(View view) { //Relevant Part for StackOverflow Question:
if(view.getId() == R.id.btn_prestory_00000) { //when the balloon is touched
startActivity(new Intent(this, game_p1_prestory_00002.class)); //got to the next activity
finish(); //delete this activity out memory.
}
}
}
I'd suggest the following:
Create an activity with a full screen ViewPager
Create a Fragment that will be a "scene", but this fragment would be able to load any of the layouts. As a starting point, just convert one of your activities to a fragment, it's pretty straightforward.
Create a FragmentStatePagerAdapter to display your fragments inside the ViewPager
This is a very compact structure, and it allows you to define very cool transitions (cube/3d/fadings/scrolls...) between scenes with very little effort (see PageTransformers when you have a working prototype)
After this is done, to change scenes you can do:
mViewPager.setCurrentItem(1); // change to scene 1
Some Docs:
http://developer.android.com/reference/android/support/v4/app/FragmentStatePagerAdapter.html
http://developer.android.com/training/animation/screen-slide.html
Related
In Android Studio, developing in Java, I have the following (a somewhat minimized version of what I'm trying to do).
package com.example.japanesequiz;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.TextView;
import java.util.Random;
public class MainActivity extends AppCompatActivity {
String[] hiragana = {"あ", "か"};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button generate = findViewById(R.id.generate);
TextView questionText = findViewById(R.id.question_text);
RadioGroup radioGroup = new RadioGroup(this);
MainActivity ma_inst = this;
generate.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Random rand = new Random();
int hir_index = rand.nextInt(2);
questionText.setText(hiragana[hir_index]);
RadioButton rb1 = new RadioButton(ma_inst);
rb1.setId(View.generateViewId());
rb1.setText("Ah");
radioGroup.addView(rb1);
RadioButton rb2 = new RadioButton(ma_inst);
rb2.setId(View.generateViewId());
rb2.setText("Ka");
radioGroup.addView(rb2);
}
});
}
}
The basic idea is that I want to have the main screen initially mostly blank, but with a button at the bottom. When tapped, it eventually show some text and a radio button group. (I haven't yet fully built out the rest, of course.)
But at this stage what I expect when I launch the app is to see the mostly blank screen, and maybe if I tap the button it will generate some text and options (that then do nothing, further implementation to come).
But the app never launches. Instead, Graddle finishes building, I get a terminal saying that it's launching the app, but it hangs and times out.
If I had to guess -- and this is a guess because I'm very new to Android development -- there is some issue with grabbing the this instance and then using it in the OnClickListener. I'm not certain what the issue is, but it's the only thing I see here that looks fishy. Also, I'm not sure how else one is supposed to add objects to the current activity from inside of the anonymous class passed into the OnClickListener since, there, a reference to this then refers to the anonymous inner class.
I know that it is possible to use a lambda instead, and that probably resolves the issue, but I want to really understand what's going on here, since it seems like it might be conceptually important for later development.
My question: If I have correctly understood this much, then how does a lambda get around this issue? If I've not correctly understood then I'd appreciate any insight, thanks!
There are many questions in one question. First, let me try to answer your title question: "How to get context inside a mouse click listener":
There are many ways, but you can consider this one (your click lisener's onClick has the signature void onClick(View view), hence you have access to view.
view.getContext()
Next, nothing wrong with these though you better migrate to view binding https://developer.android.com/topic/libraries/view-binding as butterknife is deprecated officially
Button generate = findViewById(R.id.generate);
TextView questionText = findViewById(R.id.question_text);
Next, you don't really need this trick in order to get activity in your lambda:
MainActivity ma_inst = this;
Instead and if really needed, you can always do Context context = MainActivity.this;
Lastly, I think the issue the app never launches roots into something else not related with title question you posted, unfortunately.
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.
In android Studio, I want when i click on button , next activity/fragment should come from right side and present activity sholud gone left.I implimented its working on Activity but not on adapters is showing error.
holder.questions.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent i = new Intent(DoctorsProfile.this,Questions.class);
i.putExtra("DOCTOR_ID",doctor_id);
startActivity(i);
overridePendingTransition( R.anim.slide_in_right_up, R.anim.slide_out_right_up);
}
});
overridePendingTransition is working on Activity but not working on Adapters of Recyclerview and Listview, Please tell any other option. I want when i click on recyclerview item next Activity should navigate or come from right side by using overridePendingTransition.
Fragment fragment = Fragment.newInstance();
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.setCustomAnimations(R.anim.fragment_slide_left_enter,
R.anim.fragment_slide_left_exit, R.anim.fragment_slide_right_enter,
R.anim.fragment_slide_right_exit);
Utils.addFragmentToActivity(fragmentTransaction, Fragment, R.id
.content_frame);
This tip features how to change Android’s default animation when switching between Activities.
The code to change the animation between two Activities is very simple: just call the overridePendingTransition() from the current Activity, after starting a new Intent. This method is available from Android version 2.0 (API level 5), and it takes two parameters, that are used to define the enter and exit animations of your current Activity.
Here’s an example:
//Calls a new Activity
startActivity(new Intent(this, NewActivity.class));
//Set the transition -> method available from Android 2.0 and beyond
overridePendingTransition(R.anim.slide_in_right_up, R.anim.slide_out_right_up);
These two parameters are resource IDs for animations defined with XML files (one for each animation). These files have to be placed inside the app’s res/anim folder. Examples of these files can be found at the Android API demo, inside the anim folder.
for example code visit http://www.christianpeeters.com/android-tutorials/tutorial-activity-slide-animation/#more-483
Change like this code you must be passing activity as context in adapter
holder.questions.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent i = new Intent(DoctorsProfile.this,Questions.class);
i.putExtra("DOCTOR_ID",doctor_id);
Activity activity = (Activity) context;
activity.startActivity(i);
activity.overridePendingTransition(R.anim.slide_in_right_up, R.anim.slide_out_right_up);
}
});
Note : Context is the Base Object of Activity
Update :
I have checked the accepted answer but hope you understand that it will be called everytime when your activity get launched and thats not supposed to be best practice. I am suggesting better approach if you want to follow the accepted answer .
Alternative :
Pass one parameter in bundle to new activity to make sure that transition coming from that specific adapter so double transation should not happen when you are coming rom any other activity also.
There is a easy way to do this. just put overridePendingTransition on your OnCreate method of next Activity/Fragment.So that when next Activity will come it will come according to your choice.Need not add overridePendingTransition on adapters.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_ask_question);
overridePendingTransition( R.anim.slide_in_right_up, R.anim.slide_out_right_up);
}
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
My activity_main_layout has 2 buttons:
//Start game on click
<Button android:id="#+id/btnStart"/>
//If not sign in Google Game play Service
//Sign in then show leader board on click
<Button android:id="#+id/btnLeader board" />
Click on btnStart to begin playing game:
btnStart.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// Perform action on click
Intent intent = new Intent(MainActivity.this, game_play.class);
startActivity(intent);
finish();
}
});
As you can see, class game_play is the place to play and update height score.
I'm wondering where to extends BaseGameActivity? Inside class MainActivity or game_play or both of them?
I try many times but it's not successfull.
I'm really an amateur, I expect that you give me some ideas.
Have you gone through the QuickStart Guide? This is a good place to start if you are new to developing games for Android. To answer you question, you need to access the Play Game Services from the activity that is going to handle signing in and calling game services APIs.
From your description it sounds like both your activities will need to make calls (the main activity is showing the leaderboard, and the game activity is most likely posting scores).
Extending your activity from BaseGameActivity really is not needed any longer (for an entertaining explanation watch: Death of BasegameActivity. What you do need to do is implement the two interfaces that handle initializing the GoogleAPIClient:
public class MainActivity extends Activity implements
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener {
}
To implement these, refer to the samples and the doc: https://developers.google.com/games/services/android/init
You can do the same in your game activity. The application will maintain the login state between activities, so the player will not have to login twice.