Upon starting my game, the game does not utilise the entire android screen. This only happens with the game itself, shown by the image as the user is unable to reach the bottom of the screen. Have tried to find a solution however all attempts I have tried seems not to work. Unsure which code to supply, and therefore do not want to provide a large amount of code. Let me know which code to post. Any help would be appreciated.
Image of game
package com.example.spaceattack;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.os.Handler;
import java.util.Timer;
import java.util.TimerTask;
public class MainActivity extends AppCompatActivity
{
private SpaceShipView gameView;
private Handler handler = new Handler();
private final static long Interval = 30;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
gameView = new SpaceShipView(this);
setContentView(gameView);
Timer timer = new Timer();
timer.schedule(new TimerTask() {
#Override
public void run()
{
handler.post(new Runnable() {
#Override
public void run()
{
gameView.invalidate();
}
});
}
}, 0, Interval);
}
}
You need to hide the status/system by getting the window of your app and set below flags:
More from Documentation
// hide status bar
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN);
} else {
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
}
So in your code:
public class MainActivity extends AppCompatActivity
{
private SpaceShipView gameView;
private Handler handler = new Handler();
private final static long Interval = 30;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
gameView = new SpaceShipView(this);
setContentView(gameView);
// hide status bar
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
mUiOptions = View.SYSTEM_UI_FLAG_FULLSCREEN;
getWindow().getDecorView().setSystemUiVisibility(mUiOptions);
} else {
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
}
Timer timer = new Timer();
timer.schedule(new TimerTask() {
#Override
public void run()
{
handler.post(new Runnable() {
#Override
public void run()
{
gameView.invalidate();
}
});
}
}, 0, Interval);
}
}
Related
The splash screen's supposed to work every time I use my app But once I clear the application from task manager and restart it.
The animation doesn't appear and it goes straight to the login screen with no animation occurring.
package com.example.promilek;
import androidx.appcompat.app.AppCompatActivity;
import android.annotation.SuppressLint;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.view.WindowManager;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.ImageView;
#SuppressLint("CustomSplashScreen")
public class SplashScreen extends AppCompatActivity {
private static final int SPLASH_SCREEN = 2000;
//Variables
Animation topAnim;
ImageView ImageViewButla;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow() .setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_splash_screen);
topAnim= AnimationUtils.loadAnimation(this, R.anim.top_animation);
ImageViewButla = findViewById(R.id.imageViewButla);
ImageViewButla.setAnimation(topAnim);
new Handler() .postDelayed(() -> {
Intent intent = new Intent(SplashScreen.this, Login.class);
startActivity(intent);
finish();
},SPLASH_SCREEN);
}
}
In my solution, I will use the Thread class to do this. At least this will give you more control in the activity lifecycle methods.
I have also included a SessionManager to help you incase you need it now or later.
Activity with animation
#SuppressLint("CustomSplashScreen")
public class SplashScreen extends AppCompatActivity {
private static final int SPLASH_SCREEN = 2000;
//Variables
Animation topAnim;
ImageView ImageViewButla;
private Thread counterThread;
Context mContext;
private SessionManager sessionManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow() .setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_splash_screen);
mContext = getApplicationContext(); // Get application context
topAnim = AnimationUtils.loadAnimation(this, R.anim.top_animation);
ImageViewButla = findViewById(R.id.imageViewButla);
ImageViewButla.setAnimation(topAnim);
sessionManager = new SessionManager(mContext); // Initialize Session manager object
// Counter thread
counterThread = new Thread() {
#Override
public void run() {
try {
int wait = 0; // Thread wait time
// Loop
while (wait < SPLASH_SCREEN) {
sleep(100); // Sleep
wait += 100;
}
Intent intent;
if (sessionManager.isSignedIn()) {
// Launch MainActivity
intent = new Intent(SplashActivity.this, MainActivity.class);
} else {
// Launch Signin or SignUp activity
intent = new Intent(SplashActivity.this,
SignInSignUpActivity.class);
}
startActivity(intent); // Start activity
finish(); // Exit Activity
} catch (Exception ignored) {
} finally {
finish(); // Exit Activity
}
}
};
}
}
#Override
public void onBackPressed() {
super.onBackPressed(); // Exit
counterThread.start(); // Start thread
}
#Override
public void onResume() {
super.onResume();
counterThread.start(); // Start thread
}
#Override
protected void onStop() {
super.onStop();
counterThread.interrupt(); // Interrupt thread on activity exit
}
#Override
protected void onDestroy() {
super.onDestroy();
counterThread.interrupt(); // Interrupt thread on activity exit
}
SessionManager class
Below is the code for the session manager
public class SessionManager {
private static final String KEY_IS_SIGNED_IN = "isSignedIn";
private static String PREFERENCE_NAME; // Shared Preference File Name
// Shared Preference
private final SharedPreferences sharedPreferences;
private final SharedPreferences.Editor editor;
// Shared Preference mode
int PRIVATE_MODE = 0;
#SuppressLint("CommitPrefEdits")
public SessionManager(Context context) {
this.sharedPreferences = context.getSharedPreferences(PREFERENCE_NAME, PRIVATE_MODE);
this.editor = sharedPreferences.edit();
PREFERENCE_NAME = context.getResources().getString(R.string.app_name) +
"_SessionManagerPreference";
}
public boolean isSignedIn() {
return sharedPreferences.getBoolean(KEY_IS_SIGNED_IN, false);
}
public void setSignedIn(boolean isLoggedIn) {
editor.putBoolean(KEY_IS_SIGNED_IN, isLoggedIn);
editor.commit(); // Commit Changes
}
}
I want to Increment the TextView's value in Android Studio automatically but the problem i am facing is > when i run the following code it only show the app interface when the code is finished. Any Solution?
package com.example.assignment2;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.*;
import static android.os.SystemClock.sleep;
public class MainActivity extends AppCompatActivity{
private TextView tv;
int count = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv = findViewById(R.id.t);
while(count<10000000) {
count++;
tv.setText("" + count);
}
}
}
new Thread(new Runnable(){
#Override
public void run() {
int counter = 0;
while (counter < 10000000) {
counter++;
final String counterStr = counter.toString();
tv.post(new Runnable(){
#Override
public void run() {
tv.setText(counterStr);
}
});
Thread.sleep(1000);
}
}
}).start();
The problem here is that:
On Android, there is something called Main Thread. This thread is responsible for rendering all the UI of your app, if this thread is busy with any other task (like run a while with 10.000.000 of loops) your UI will just freeze because there are no resources available to render the UI. To avoid that kind of issue, you should run the heavy part of your code in a separate thread, and all the UI updates on the main / UI thread (both are the same thing). Making these changes your code will look like that:
package com.example.assignment2;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.*;
import static android.os.SystemClock.sleep;
public class MainActivity extends AppCompatActivity{
private TextView tv;
int count = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv = findViewById(R.id.t);
//Creating a new thread
new Thread(new Runnable() {
#Override
public void run() {
//This while will run on this new thread
while(count<10000000) {
count++;
/*To ensure that the TextView update will run on the right thread
* we should run this update inside the runOnUiThread method*/
MainActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
tv.setText("" + count);
}
});
}
}
});
}
To learn more about thread take a look at this article:
https://developer.android.com/topic/performance/threads
I have problem with Runnable. It don't want to works, and i don't know what is the problem, because it is works in my other app... Can somebody help me?
Just example, there are "healt" with deafult value=5, for the test i made a button, when i click button, healt value -1... and i want start Runnable when health<5... and add +1 to health.... for the test i setted the Runnable 1 secunds
Here is the code:
MainActivity.java
package com.mygame.test;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.TextView;
import static com.mygame.test.variables.coin;
import static com.mygame.test.variables.health;
public class Main2Activity extends AppCompatActivity {
public static final String PREFS_NAME_MAIN = "mainpref";
TextView coinText, healthText, textView;
Button button3;
private final Context app = this;
private final Handler update = new Handler();
private final Runnable updateHealth = new Runnable()
{
public void run()
{
if (variables.run)
{
healthText.setText(""+health);
update.postDelayed(updateHealth, 500);
}
else if (!variables.run) update.removeCallbacksAndMessages(null);
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_main2);
coinText = findViewById(R.id.coinText);
healthText = findViewById(R.id.healthText);
healthText.setText(String.valueOf(health));
button3 = findViewById(R.id.button3);
textView = findViewById(R.id.textView);
Button closeButton = findViewById(R.id.closeButton);
closeButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//finishAffinity();
startActivity(new Intent(Main2Activity.this, ExitActivity.class));
}
});
Button coinsplusButton = findViewById(R.id.coinsplusButton);
coinsplusButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//finishAffinity();
startActivity(new Intent(Main2Activity.this, StoreActivity.class));
}
});
Button level1Button = findViewById(R.id.level1Button);
level1Button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//finishAffinity();
startActivity(new Intent(Main2Activity.this, Level1Activity.class));
}
});
}
public void buttontest(View button3)
{
if (health > 0) {
health = health-1;
healthText.setText(""+health);
}
variables.run = true;
Intent activeClick = new Intent(this, ClickService.class);
this.startService(activeClick);
update.post(updateHealth);
save();
}
#Override
protected void onStart()
{
super.onStart();
load();
textupgrade();
if (!variables.run)
{
variables.run = true;
Intent activeClick = new Intent(this, ClickService.class);
this.startService(activeClick);
}
}
protected void onResume()
{
super.onResume();
load();
textupgrade();
update.post(updateHealth);
}
private void load()
{
SharedPreferences varReader = app.getSharedPreferences(PREFS_NAME_MAIN, MODE_PRIVATE);
variables.run = varReader.getBoolean("run", false);
coin = varReader.getInt("coin", 0);
health = varReader.getInt("health", 5);
}
private void save()
{
SharedPreferences.Editor varReader = app.getSharedPreferences(PREFS_NAME_MAIN, 0).edit();
varReader.putBoolean("run", variables.run);
varReader.putInt("coin", coin);
varReader.putInt("health", health);
varReader.apply();
}
private void textupgrade(){
coinText.setText(""+coin);
healthText.setText(""+health);
}
}
ClickService.java
package com.mygame.test;
import android.app.IntentService;
import android.content.Intent;
import android.os.Handler;
public class ClickService extends IntentService
{
private final Handler handler = new Handler();
private final Runnable addHealth = new Runnable()
{
public void run()
{
variables.health++;
if (!variables.run) handler.removeCallbacksAndMessages(null);
else if (variables.run) handler.postDelayed(addHealth, 1000);
}
};
public ClickService()
{
super("ClickService");
}
#Override
protected void onHandleIntent(Intent activeClick)
{
handler.postDelayed(addHealth, 500);
}
}
variables.java
package com.mygame.test;
public class variables {
static int coin;
static int health;
static boolean run;
}
Oh, i fixed it :D ClickService was not registered in AndroidManifest
<service
android:name=".ClickService"
android:exported="false" />
I've created a timer and placed it in its own separate class. For some reason when I try to run it it crashes with the following error:
Java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference
I think it because its trying to update a textview from a class other than Mainactvity but I cant figure out how to get it to work.
Here's the code:
MainActivity
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
Button resetButton;
TextView textTimer;
int elapsedTime;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
elapsedTime = 60;
textTimer = (TextView) findViewById(R.id.textTimer);
resetButton = (Button) findViewById(R.id.resetButton);
final Button resetbttn = (Button) findViewById(R.id.resetButton);
resetbttn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
CountUp mycountup = new CountUp();
mycountup.count();
}
});
}
}
Timer Class:
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
/**
* Created by Mat on 24-Feb-17.
*/
public class CountUp extends MainActivity{
TextView textTimer;
Button resetButton;
int elapsedTime;
Handler h;
int RATE = 1000;
MainActivity mainact = new MainActivity();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
textTimer = (TextView) findViewById(R.id.textTimer);
resetButton = (Button) findViewById(R.id.resetButton);
h = new Handler();
count();
final Button resetbttn = (Button) findViewById(R.id.resetButton);
resetbttn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
reset();
}
});
}
public void reset(){
elapsedTime = 60000;
}
public void count(){
elapsedTime--;
textTimer.setText(String.valueOf(elapsedTime));
h.postDelayed(r,RATE);
final String endcomparison = textTimer.getText().toString();
if (endcomparison.equals("0")){
reset();
}
}
private Runnable r = new Runnable() {
#Override
public void run() {
count();
}
};
}
findViewById() method actually looks for view in layout file.
when you set layout for activity or fragment using
setContentView(R.layout.activity_main);
findViewById() find those views in that layout. it can't find random objects on the fly.
so in second activity set layout first or create sub class in first activity and then try to update data in textview.
Your are just instantiating an activity, which it's onCreate will never get called.
CountUp mycountup = new CountUp();
mycountup.count(); // view never created so it's null
To load the views you need to use a method like startActivity.
If I am understanding you correctly, if you are extending CountUp from MainActivity then in your manifest, you'd set CountUp as your launching activity. Then using Java inheritance, you don't need to re-find the views, because in CountUp we are calling super.onCreate(savedInstanceState), which calls the MainActivity's onCreate.
public class MainActivity extends AppCompatActivity {
Button resetButton;
TextView textTimer;
int elapsedTime;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
elapsedTime = 60;
textTimer = (TextView) findViewById(R.id.textTimer);
resetButton = (Button) findViewById(R.id.resetButton);
}
}
public class CountUp extends MainActivity{
Handler h;
int RATE = 1000;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// can access this since inheritance
resetButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
reset();
}
});
h = new Handler();
count();
}
//...
public void count(){
elapsedTime--;
// inheritance
textTimer.setText(String.valueOf(elapsedTime));
h.postDelayed(r,RATE);
final String endcomparison = textTimer.getText().toString();
if (endcomparison.equals("0")){
reset();
}
}
//...
}
I am following a tutorial in how to set up a Surface View in Android Studio using Java. This is my code:
package com.example.benjamin.labb3;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.SurfaceHolder;
public class SurfaceView extends Activity {
private OurView v;
#Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(v);
v = new OurView(this);
}
#Override
protected void onPause() {
super.onPause();
v.pause();
}
#Override
protected void onResume() {
super.onResume();
v.resume();
}
public class OurView extends SurfaceView implements Runnable {
Thread t = null;
SurfaceHolder holder;
boolean isOk = false;
public OurView(Context context){
super(context);
holder = getHolder();
}
public void run(){
if(isOk){
}
}
public void pause(){
isOk = false;
while (true){
try {
t.join();
t = null;
break;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void resume(){
isOk = true;
t = new Thread(this);
t.start();
}
}
}
In
setContentView(v);
I am getting the error msg:
"Cannot resolve method
setContentView(com.example.ben3.pl2.SurfaceView.OurView)"
And in
public OurView(Context context){
super(context);
holder = getHolder();
}
I am getting the errors:
"Cannot resolve method super(android.content.Context)"
"Cannot resolve method getHolder()"
Can anyone help me? The tutorial is from 2011 so it could have something to do with them having a older version of AS, or i just missed something perhaps.
Couple things you should fix here. Rename your class and file to MyActivity or at least something other than SurfaceView to avoid confusion. You want to use the SurfaceView from android.view.SurfaceView not your own so you should import that one.
import android.view.SurfaceView;
Also, you must create a new instance of OurView before using it in setContentView().
Here is your code with the changes applied.
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
public class MyActivity extends Activity {
private OurView v;
#Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
v = new OurView(this);
setContentView(v);
}
#Override
protected void onPause() {
super.onPause();
v.pause();
}
#Override
protected void onResume() {
super.onResume();
v.resume();
}
public class OurView extends SurfaceView implements Runnable {
Thread t = null;
SurfaceHolder holder;
boolean isOk = false;
public OurView(Context context){
super(context);
holder = getHolder();
}
public void run(){
if(isOk){
}
}
public void pause(){
isOk = false;
while (true){
try {
t.join();
t = null;
break;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void resume(){
isOk = true;
t = new Thread(this);
t.start();
}
}
}
just try to instanciate your view before the setcontentview method
like this
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
v = new OurView(this);
setContentView(v);
}
keep me up to date