I'm still struggling to find a clean easy way to load some values in my onCreate method and pass them to another class in order that a game may load and save option settings.
I can successfully retrieve and change values from my other class but the problem is, no matter what I try, variable set in the onCreate method will not carry to the rest of the code.
I take the point that by only showing snipits of the code I may have obscured the problem but my original is far to massive and sprawling to post HOWEVER it was based on a great tutorial by Martin
http://www.droidnova.com/android-3d-game-tutorial-part-i,312.html
So I've returned to first principles and just added the problematic portion to that tutorial code and my problem has been replicated. So here is the complete code:
Vortex.java **
package com.clockworkrobot.vortex;
import android.app.Activity;
import android.os.Bundle;
public class Vortex extends Activity {
private static final String LOG_TAG = Vortex.class.getSimpleName();
private VortexView _vortexView;
private float _red ; // these are the values that actually reach VortexRender class
private float _green = 1f ; // touch the screen, it will turn green.
private float _blue ; // but why don't the variable in my onCreate override these?
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
_red = 1f; // The test values I want to reach my Vortex Renderer class.
_green = 0f; // to help debug. they should make the screen magenta
_blue = 1f; // Eventually these value will be loaded during onCreate
setRed(_red); // I don't think these are needed
setGreen(_green); // But since the variable within this method
setBlue(_blue); // don't appear to be reaching their target..worth a try
_vortexView = new VortexView(this);
setContentView(_vortexView);
}
public float getRed() {
return _red;
}
public void setRed(float value) {
_red = value;
}
public float getGreen() {
return _green;
}
public void setGreen(float value) {
_green = value;
}
public float getBlue() {
return _blue;
}
public void setBlue(float value) {
_blue = value;
}
}
VortexRender.java**
package com.clockworkrobot.vortex;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import android.app.Activity;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
public class VortexRenderer extends Activity implements GLSurfaceView.Renderer {
private static final String LOG_TAG = VortexRenderer.class.getSimpleName();
// Vortex sw = new Vortex();
private Vortex sw;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
sw = new Vortex();
}
private float _red = 0f;
private float _green = 0f;
private float _blue = 0f;
#Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
// Do nothing special.
}
#Override
public void onSurfaceChanged(GL10 gl, int w, int h) {
gl.glViewport(0, 0, w, h);
}
#Override
public void onDrawFrame(GL10 gl) {
// define the color we want to be displayed as the "clipping wall"
gl.glClearColor(_red, _green, _blue, 1.0f);
// clear the color buffer to show the ClearColor we called above...
gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
}
public void setColor(float r, float g, float b) {
_red = sw.getRed(); // Want these to grab the values from my onCreate method
_green = sw.getGreen(); // But instead it's getting the nul values
_blue = sw.getBlue(); // eg values as set above me onCreate.
// _red = r;
// _green = g;
// _blue = b;
}
}
VortexView.java**
package com.clockworkrobot.vortex;
import android.content.Context;
import android.opengl.GLSurfaceView;
import android.view.MotionEvent;
public class VortexView extends GLSurfaceView {
private static final String LOG_TAG = VortexView.class.getSimpleName();
private VortexRenderer _renderer;
public VortexView(Context context) {
super(context);
_renderer = new VortexRenderer();
setRenderer(_renderer);
}
public boolean onTouchEvent(final MotionEvent event) {
queueEvent(new Runnable() {
public void run() {
_renderer.setColor(event.getX() / getWidth(), event.getY() / getHeight(), 1.0f);
}
});
return true;
}
}
AndroidManifest.xml**
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.clockworkrobot.vortex"
android:versionCode="1"
android:versionName="1.0">
<application android:icon="#drawable/icon" android:label="#string/app_name">
<activity android:name=".Vortex"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<uses-sdk android:minSdkVersion="3" />
</manifest>
In essence.. What I require is a way to save and recover the current screen colour when the game opens and closes.
Thanks to everyone who has helped so far.
I'm still struggling to find a clean easy way to load some values in my onCreate method and pass them to another class in order that a game may load and save option settings.
Use SharedPreferences -- that is why they are there.
Anyone got any helpful ideas?
Either:
Your other class is not talking to the Activity object you think it is, or
You are not calling the code in the other class that invokes your setter, or
Your activity is being recreated (e.g., configuration change) as part of your testing, or
As #Arnout Engelen notes, you are calling the setter from multiple places and are overwriting what you want, or
Something else, since the code you have above most likely is not really the code from your app, and fake examples like this just cause problems when you go to ask people for help, because you introduce differences between what you're really running and what you're claiming you're running
UPDATE
You are creating a Vortex via new Vortex(). Vortex is an Activity. Never create activities via the constructor. You do not access activities from other activities. Your red/green/blue values need to be in some data model accessible from all your components.
Given your code and comments, I strongly encourage you to first learn Java outside of Android, then learn Android.
I had a similar problem. The solution is easy.
If the setter method is setting an int, initially it must be written as "public int...{} " instead of "public void...{} ".
Then it must return an int variable at the end with the following code line: "return a;" (where a is any int or int variable that has previously been initiated).
Then, whenever you want an int b to get a's number, simply write:
int b = new exampleClassWhereYourMethodIs().setterMethodName();
Hope I helped!
Related
I need to create a login screen and a simple first screen (with a log out button). When a user logs in, for convenience, it does not require to log in again (only when the log out button is hit). To do this, i need to store a boolean variable whether the users is logged in or not.
When I hit the home button and open the app again, the app remembers that I already logged in. But when I hi the back button, it does not remember it.
Here is my code of the login screen:
package com.example.a20172425.login;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
public class LoginActivity extends AppCompatActivity {
EditText usernameEditText;
EditText passwordEditText;
TextView falseLoginTextView;
SharedPreferences pref;
boolean validCredentials = false;
public static Boolean login = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
usernameEditText = (EditText)findViewById(R.id.usernameField);
passwordEditText = (EditText)findViewById(R.id.passwordField);
falseLoginTextView = (TextView)findViewById(R.id.falseLoginText);
pref = getPreferences(MODE_PRIVATE);
login = getLoginStatus();
if(login) {
toMainActivity();
}
}
public void checkCredentials(View v){
//clear possible previous content
falseLoginTextView.setText("");
//retrieve username and password
String username = usernameEditText.getText().toString();
String password = passwordEditText.getText().toString();
if ((username.equals("username")) && (password.equals("password"))) {
validCredentials = true;
setLoginStatus(true);
//setUsername(username);
} else if ((username.equals("a")) && (password.equals("a"))) {
validCredentials = true;
setLoginStatus(true);
//setUsername(username);
}
if (validCredentials){
toMainActivity();
}
else
{
falseLoginTextView.setText("Incorrect username and or password");
}
}
public void toMainActivity(){
Intent intent = new Intent(LoginActivity.this, MainActivity.class);
intent.putExtra("Username", usernameEditText.getText().toString());
this.startActivity(intent);
//makes sure pressing the back button does not send the app back to the login screen
this.finish();
}
// gets the logged_in value from persistent memory.
public Boolean getLoginStatus (){
return pref.getBoolean("Logged_in",false);
}
//sets the logged_in boolean value in persistent memory.
public void setLoginStatus(Boolean loginStatus){
//editor to change values to be stored in memory
SharedPreferences.Editor edit = pref.edit();
edit.putBoolean("Logged_in",loginStatus);
//save changes
edit.commit();
}
}
This is my code of the simple first screen:
package com.example.a20172425.login;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
import static com.example.a20172425.login.LoginActivity.login;
public class MainActivity extends AppCompatActivity {
TextView LoginTextView;
LoginActivity loginActivity;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
LoginTextView = (TextView) findViewById(R.id.LoginTV);
String username = getIntent().getStringExtra("Username");
LoginTextView.setText("Currently logged in as: " + username);
loginActivity = new LoginActivity();
}
public void toLoginActivity(View v) {
Intent intent = new Intent(MainActivity.this, LoginActivity.class);
this.startActivity(intent);
login = false;
//loginActivity.setLogin(false);
//makes sure pressing the back button does not send the app back to the login screen
this.finish();
}
}
Any suggestion will be appreciated.
EDIT: I write Kotlin in my day to day job, I didn't actually compile the Java examples below so there may be some syntactical errors. However, it should be fairly trivial to resolve these with basic working Java knowledge. The concepts in this answer are applicable to the vast majority of OO languages (Kotlin, Java, C# etc.).
I'm updating this answer to give some more detail on what an interface is, why they are useful, how callbacks work and how they are implemented under the hood.
In object oriented programming (OO) and, in this case, Java; there is a type system that allows for polymorphism. Polymorphism, when broken down, means (poly -> many) and (morphism -> behaving like), or, in other words, many similarly behaving different types.
What these means in more concrete coding terms is that you can have many different classes of types which conform to a common behaviour (or interface). The behaviour of a type should be thought of as it's outwardly observable behaviours and not the internal implementation. It is useful to conceptualise this with respect to the type system. For example, a behaviour is defined as a transformation from one type to another (for instance a function that takes a collection of strings and returns a string). There are many functions that could perform this transformation, but the outwardly observable behaviour of all of these functions is the same (in other words, a transformation Collection -> String).
It therefore follows that such a type system can allow for arbitrary swapping of implementations as long as the outwardly observable behaviour is maintained.
Interfaces are a popular language construct to achieve this. An interface merely defines the tranformations between types and gives them names. Other types may then depend on this interface and call methods of this interface without any concern as to the actual implementation of the methods (the only constraint being that the implementors of said interface must conform to the type transformations - this is enforced at compile time in Java).
Here is a very simple interface:
public interface Car {
public Int accelerate(Int force);
public Int steer(Int direction);
}
I use the car example as it's quite intuitive. Here we can see two type transformations, from Int -> Int with a name accelerate, and from Int -> Int with a name of steer.
All cars can accelerate and steer. But not all cars accelerate and steer in the same way. However, all cars steer and accelerate behaviours follow a common pattern (or type transformation). They take some input value and result in some output value.
So, we could provide several implementations of car like so (bear in mind this is a very contrived example, so don't judge):
public class Ford implements Car {
#Override
public Int accelerate(Int force) {
return force * 1;
}
#Override
public Int steer(Int direction) {
return direction * 1;
}
}
public class Ferrari implements Car {
#Override
public Int accelerate(Int force) {
return force * 10;
}
#Override
public Int steer(Int direction) {
return direction * 10;
}
}
As you can see, a Ford and Ferrari both steer and accelerate. But the Ferrari does it differently (but it still conforms to the type transformation just as the Ford does).
Now, here we introduce polymorphism, which is a very powerful tool. Imagine we have the following class:
public class Person {
private Car car;
public Person(Car car) {
this.car = car
}
}
So, a person can be constructed by passing a car as a dependancy to it. Due to polymorphism we can pass any instance of an object that implements (or conforms to) the Car interface. For instance, we could do the following:
public class Main {
public void main([String] args) {
Person poorPerson = new Person(new Ford());
Person richPerson = new Person(new Ferrari());
}
}
Pretty nifty! Now we can create hundreds of different types of cars but our person class never has to change! Our person class can call methods on their respectively owned cars and never have to worry about anything breaking (because all cars can accelerate and steer).
So, how does this relate to the original question? Let us consider this very contrived example of an Android View class and a Callback interface:
public interface ContrivedCallback {
public void onClick();
}
public class ContrivedView {
private ContrivedCallback callback;
public void setOnClickListener(ContrivedCallback: callback) {
this.callback = callback;
}
private void onClick() {
this.callback.invoke();
}
}
Let us assume that the onClick method in the ContrivedView class is magically called by the Android OS when the view is clicked. Now, when the view is clicked, the callback (if set) is invoked. But, as we now know, the callback is just an interface, so whatever implementation was provided to the setCallback method will be invoked.
So, the callbacks single defined method is merely a transformation from Void -> Void (in other words, it takes no arguments and returns no value). It's just some code to run. The implementation may launch rockets, save to a database, print a string or do literally nothing, it's up to the coder providing the implementation).
I hope this makes sense? Now, with respect to the original question:
You can use an onClickListener callback. In this callback implementation you can write some code that updates some state of the Activity or Fragment (or write to preferences or local database, or launch missiles... you get the picture).
You create an implementation and then assign this implementation to the callback listener on the button in question like so (in your onCreate method):
logoutButton = (Button)findViewById(R.id.logoutButton);
logoutButton.addOnClickListener(class callback extends DialogInterface.OnClickListener {
#Override
public void onClick() {
// Do stuff here...
}
});
I am new to android. I am developing an CGPA App for my college. though many apps are available, I just wanted to do one on my own.
Let me come to the Question..
I want to get all the GPA values to my Main_Activity.java so that i can calculate my CGPA. I used the concept of Global Variables using Application in android. But i get my output as NaN. Though I referred many articles, I cant clear that error. As I need to submit the app to my college I am in need of help..
First i would like to show you my global class..
package com.example.cgpa;
import android.app.Application;
public class global extends Application{
private Float f[]={0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f};
private Float f1[]={0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f};
public Float getfloat(int a){
return f[a];
}
public void setfloat(Float a,int b){
this.f[b]=a;
}
public Float getfloat1(int a){
return f1[a];
}
public void setfloat1(Float a,int b){
this.f1[b]=a;
}
}
This is the place I have used the Global variables in mainactivity.java
b.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
final global x=((global)getApplicationContext());
Float t=0.0f,c=0.0f;
for(int i=0;i<8;i++){
t+=x.getfloat(i);
c+=x.getfloat1(i);
}
final Float g=t/c;
txt.setText("Your CGPA is "+g.toString());
}
});
Also this is the place I have set the values in gpa1.java and like the same way I have used this in other classes.
b.setOnClickListener(new View.OnClickListener() {
Float[] n={4.0f,4.0f,3.0f,3.0f,3.0f,4.0f,2.0f,2.0f,1.0f};
Float t=0.0f;
Float c=0.0f;
#Override
public void onClick(View arg0) {
for(int i=0;i<9;i++){
c+=n[i];
}
for(int i=0;i<9;i++)
{
if(s[i]=="S")
n[i]*=10;
else if(s[i]=="A")
n[i]*=9;
else if(s[i]=="B")
n[i]*=8;
else if(s[i]=="C")
n[i]*=7;
else if(s[i]=="D")
n[i]*=6;
else if(s[i]=="E")
n[i]*=5;
else
n[i]*=0;
}
for(int i=0;i<9;i++){
t+=n[i];
}
Float g=t/c;
final global x=((global)getApplicationContext());
x.setfloat(t, 0);
x.setfloat1(c, 0);
TextView txt=(TextView)findViewById(R.id.textView9);
txt.setText("Your GPA is "+g.toString());}
});
You may also tell me how to get values from other classes as I already used intent and image buttons to move from main activity to other activities.
Thank you friends for your kind advice... I have found what's wrong. it is very silly.. (0/any number)=NaN.. I have just cleared the error using isNaN() method..
Thank you..
How do i go to the next text when my snake eat a food? (When the snake eat the food, the text will change from testing to success.) I'm using the snake game provided by eclipse. This is the code i have done so far. I am doing this for my project so i appreciate all the help i can get.
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
public class Snake extends Activity {
/**
* Constants for desired direction of moving the snake
*/
public static int MOVE_LEFT = 0;
public static int MOVE_UP = 1;
public static int MOVE_DOWN = 2;
public static int MOVE_RIGHT = 3;
private static String ICICLE_KEY = "snake-view";
private SnakeView mSnakeView;
/**
* Called when Activity is first created. Turns off the title bar, sets up the content views,
* and fires up the SnakeView.
*
*/
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.snake_layout);
init();
mSnakeView = (SnakeView) findViewById(R.id.snake);
mSnakeView.setDependentViews((TextView) findViewById(R.id.text),
findViewById(R.id.arrowContainer), findViewById(R.id.background));
if (savedInstanceState == null) {
// We were just launched -- set up a new game
mSnakeView.setMode(SnakeView.READY);
} else {
// We are being restored
Bundle map = savedInstanceState.getBundle(ICICLE_KEY);
if (map != null) {
mSnakeView.restoreState(map);
}
}
}
#Override
public void onSaveInstanceState(Bundle outState) {
// Store the game state
outState.putBundle(ICICLE_KEY, mSnakeView.saveState());
}
private int currentQuestion;
private String [] questions;
private TextView questionView;
public void init() {
questions = new String[]{"testing","success"};
currentQuestion = -1;
questionView = (TextView) findViewById(R.id.QuestionTextView);
showQuestion();
}
public void showQuestion() {
currentQuestion++;
if(currentQuestion == questions.length)
currentQuestion =0;
questionView.setText(questions[currentQuestion]);
}
}
After checking out the source code (which I did here: http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android-apps/4.2_r1/com/example/android/snake/SnakeView.java), I dont think it's possible to add this functionality without altering the source code...
However, if u want to edit the source to make it work, I would suggest the following:
create an interface to use as a listener
public interface AppleEatenListener{
public void appleEaten(int size);
}
Then add a variable of this interface to the SnakeView class
private AppleEatenListener mAppleEatenListener;
Create a setter in the SnakeView class to set the mAppleEatenListener
public void setAppleEatenListener(AppleEatenListener listener){
this.mAppleEatenListener = listener;
}
After that, make your way down to the updateSnake() method in the SnakeView class and find the following piece of code (consider using ctrl+f (search function)):
This snippet comes from the current source code:
// except if we want the snake to grow
if (!growSnake) {
mSnakeTrail.remove(mSnakeTrail.size() - 1);
}
And here we want to add, that if the snake should grow, we call the AppleEatenListener's function appleEaten(), like so:
// except if we want the snake to grow
if (!growSnake) {
mSnakeTrail.remove(mSnakeTrail.size() - 1);
}
else{
if(mAppleEatenListener != null){
mAppleEatenListener.appleEaten(mSnakeTrail.size());
}
}
Now, we should return to your own Snake class and add the following in onCreate():
mSnakeView.setOnAppleEatenListener(new AppleEatenListener() {
#Override
public void appleEaten(int size) {
showQuestion();
//size is the current size of the snake after the apple was eaten
}
});
Note that I've added that the listener requests a "size" parameter, I'm supposing it could be useful to know the size of the snake after it has eaten an apple, since I didn't see a function for requesting the size of the snake in the API either...
I have not tested this code, but I hope this helps u at least a little
I'm new to android and I am making an app as part of an assignment, and can't get this function to return a value - the app closes and I get an error message: "Unfortunately, APP has stopped".
I have two classes, one is the MainActivity and one is a class that I am wanting to use to do arithmetic, and they are:
import com.calc.Calculation;
public class MainActivity extends Activity {
private Calculation util;
calculate = (Button) findViewById(R.id.btnCalc);
private TextView tvMultiply;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tvMultiply = (TextView) findViewById(R.id.tvMult);
}
btnCalc.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
tvMiltiply.setText(String.valueOf(util.CalculateMult(4,6)));
}
});
}
and
package com.calc;
public class Calculation{
public int CalculateMult(int numOne, int numTwo)
{
return numOne * numTwo;
}
}
I've tried a few alternatives but to no avail. It's going to be something simple that I am not doing quite right.
Any help appreciated.
Thanks
You need to create instance to the class before acccessing the member.
private Calculation util = new Calculation()
Else make the method in the class as static and access without creating instance.
This would be done by defining the class as:
package com.calc;
public class Calculation{
public static int CalculateMult(int numOne, int numTwo)
{
return numOne * numTwo;
}
}
and calling the method as:
Calculation.CalculateMult(4,6)
You should move the line
calculate = (Button) findViewById(R.id.btnCalc);
to the onCreate() function after you have set the content view. You should also move the assignment of the onClickListener to your button to the onCreate() method.
Finally, you should initialize your Calculation object by using the new operator in onCreate(), i.e:
util = new Calculation();
The answer is at the bottom.
I've added a modification to the 4.0.4 browser which adds a new preferences section. When the browser is launched, the value is read in correctly and seems to get cached. I added a log event any time getMaxTabs is used by Controller.java and it's only read on first launch. If I change the setting nothing happens. But if I kill the browser and re-launch after changing the setting, the new value is read in correctly. Is there a way to force this setting to be re-cached on change?
I am looking at SharedPreferences.OnSharedPreferenceChangeListener but I don't see HOW to have that variable re-read forcibly.
int getMaxTabs() {
Context mContext = mActivity.getApplicationContext();
SharedPreferences mPrefs = PreferenceManager.getDefaultSharedPreferences(mContext);
String numTabs = mPrefs.getString(PreferenceKeys.PREF_MAX_TABS, "20");
int t = Integer.parseInt(numTabs);
Log.i("max open tabs", "max: " + t);
return t;
// The original content of getMaxTabs is below
// return mActivity.getResources().getInteger(R.integer.max_tabs);
}
So the log item only appears the first time the browser is launched. The new preference is set because if I change it and kill/relaunch the browser, the new value is reflected. I need to either not cache this setting or force the cache to be refreshed on change, which would be more efficient.
src/com/android/browser/preferences/TabsPreferencesFragment.java
package com.android.browser.preferences;
import android.os.Bundle;
import android.preference.Preference;
import android.preference.PreferenceFragment;
import com.android.browser.BrowserSettings;
import com.android.browser.PreferenceKeys;
import com.android.browser.R;
import com.android.browser.search.SearchEngine;
public class TabsPreferencesFragment extends PreferenceFragment {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Load the XML preferences file
addPreferencesFromResource(R.xml.tabs_preferences);
}
}
res/xml/tabs_preferences.xml
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android" >
<ListPreference
android:key="max_open_tabs"
android:defaultValue="20"
android:title="#string/pref_max_open_tabs"
android:entries="#array/pref_max_open_tabs_choices"
android:entryValues="#array/pref_max_open_tabs_values"
/>
</PreferenceScreen>
This is how it is called in src/com/android/browser/TabControl.java
private int mMaxTabs;
TabControl(Controller controller) {
mController = controller;
mMaxTabs = mController.getMaxTabs();
mTabs = new ArrayList<Tab>(mMaxTabs);
mTabQueue = new ArrayList<Tab>(mMaxTabs);
}
boolean canCreateNewTab() {
return mMaxTabs > mTabs.size();
}
SOLUTION
The answer lies here, in packages/apps/Browser/src/com/android/browser/TabControl.java
Around line 55 we see:
/**
* Construct a new TabControl object
*/
TabControl(Controller controller) {
mController = controller;
mMaxTabs = mController.getMaxTabs();
mTabs = new ArrayList<Tab>(mMaxTabs);
mTabQueue = new ArrayList<Tab>(mMaxTabs);
}
The TabControl object is constructed one time at browser launch. Here we define mMaxTabs by calling mController.getMaxTabs().
Around line 155 canCreateNewTab is defined, using mMaxTabs.
boolean canCreateNewTab() {
return mMaxTabs > mTabs.size();
}
Since mMaxTabs is a static value it will never change on preference update.
The solution is this.
/**
* Construct a new TabControl object
*/
TabControl(Controller controller) {
mController = controller;
mTabs = new ArrayList<Tab>(mMaxTabs);
mTabQueue = new ArrayList<Tab>(mMaxTabs);
}
boolean canCreateNewTab() {
return mController.getMaxTabs() > mTabs.size();
}
Now every time a new browser tab is requested, the pref setting is verified.