an abstract in my mind is something like
idontknow x = (idontknow) findViewById(R.string.stringname);
so that whenever i change x the R.string.stringname would also change
and thus i can use the R.string.stringname anywhere in the same project
but obviously it is an error
edit:
i would like to input my name(R.string.name or global) and age(R.string.age or global) on an EditText field on a formActivity
and in another differentActivity i would like to have this:
TextView x = (TextView) findViewById(<some id>);
x.setText("Hello "+ getString(R.string.nfoname)+ "you are"+getString(R.string.nfoname)+"years old");
This really seems like poor design. What are you doing that you don't know the type of x, and it's something that you need to persist across your application?
Everything that gets returned by findViewById() is a View object or one of its subclasses. So, right off the bat you know you have a view object. Another thing is that findViewById doesn't accept a String as a parameter, it only accept an int value, such that R.id.myVar is actually an integer corresponding to a View in the inflated hierarchy.
If you absolutely have to do something like that, why wouldn't you just use a common id value so that you're always searching for the same id and assign it to a generic View object that can be compared using instanceof later? Like this:
View view = findViewById(R.id.generic_id);
if(view instanceof TextView) {TextView actualView=(TextView)findViewById(R.id.generic_id);}
else {ImageView actualView = (ImageView)findViewById(R.id.generic_id);}
return actualView;
In that case, your ID could be a constant that couldn't be changed, and you always can figure out what subclass of View you're dealing with. This feels like a more maintainable design than having global variables floating around, in my opinion
R.string.<anything> are ids of strings defined in your string.xml file. The line
idontknow x = (idontknow) findViewById(R.string.stringname);
will fail because the parameter to findViewById is an id, which you can find in R.id.<anthing>.
If you are saying you want to define the name and age in the string.xml file, then you do have access from any Activity or View in your code.
What I suspect you actually want is to have a name and age variable that is settable and accessible from multiple views. To pass data from one Activity to another Activity, you can put them into the extras in the Intent.
For example, in Activity1.java where you start Activity2.java, you could do something like:
Intent i = new Intent(this, Activity2.class);
i.putExtra("Name", name); // name is a variable with the name value you want to send
i.putExtra("Age", age); // age is a variable with the age value you want to send
startActivity(i);
Then, in Activity2.java, you can get the extras you put into the Intent, something like:
Bundle extras = getIntent().getExtras();
name = extras.getString("Name");
age = extras.getInt("Age");
Related
Should View objects (TextViews, EditTexts, etc) have a variable assigned to them in onCreateView even if the variable will never be used? Is it acceptable to just assign the object's id to the Fragment using findViewById and access the object by using its id instead?
More detail:
I have several EditText values that are being initialized like this:
EditText role1 = (EditText) root.findViewById(R.id.role1_edit_text);
EditText role2 = (EditText) root.findViewById(R.id.role2_edit_text);
// Six other similar entries truncated
However, I'm not using the actual variables for role1 so Android Studio suggests removing the variable and writing it like this:
root.findViewById(R.id.role1_edit_text);
root.findViewById(R.id.role2_edit_text);
// Six other similar entries truncated
I have never seen Views assigned this way and just happened upon it because I'm referencing the EditText by their ids in my methods like this:
// Accessing View objects using view ids
editTextIds = new int[]{R.id.add_location_role1_edit_text, R.id.add_location_role2_edit_text,
R.id.add_location_role3_edit_text, R.id.add_location_role4_edit_text,
R.id.add_location_role5_edit_text, R.id.add_location_role6_edit_text,
R.id.add_location_role7_edit_text, R.id.add_location_title_edit_text};
private boolean allFieldsHaveInput() {
for (int id : editTextIds) {
EditText editText = (EditText) getView().findViewById(id);
if (isTextEmpty(editText)) {
return false;
}
}
return true;
}
I have several such methods that use loops to go through all the EditText ids so switching to variables would definitely make the code more verbose. I feel like EditText editText = (EditText) getView().findViewById(id); might be slightly more expensive computationally, but with roughly eight Views it seems like a small price to pay so I don't have to write the method like this:
// Accessing View objects using a variable
private EditText role1, role2, role3, role4, role5, role6, role7, role8;
private boolean allFieldsHaveInput() {
return !isTextEmpty(role1) && !isTextEmpty(role2) && !isTextEmpty(role3)
!isTextEmpty(role4) && !isTextEmpty(role5) &&
!isTextEmpty(role6) && !isTextEmpty(role7) &&
!isTextEmpty(role8);
}
I have never seen View objects assigned without a variable in open source code so I'm a little concerned if removing the variable is a bad idea (especially since I'm planning to put the code up on GitHub).
From a readability standpoint would it be better to just assign variables like role1 even if the code becomes slightly more verbose?
You have already captured some of the nuances in the approaches. Personally, I'd choose code readability over performance in most cases. In your case however, I strongly believe an array approach would fare much better.
private EditeText[] roleEditTexts = new EditText[8];
// assign
This would also avoid the costly calls to findViewById() (if you are calling that code snippet multiple times).
I am on page 301 of this book and it is an example of an Activity getting "extras" from the intent that started it. I am fairly new to Java so maybe am missing something pretty obvious but...
I thought that when you declare a variable as "final" it meant that it doesn't change.
There is a line of code initialising a final variable:
public static final String EXTRA_MESSAGE="msg";
and then later in onCreate method:
tv.setText(getIntent().getStringExtra(EXTRA_MESSAGE));
The text displayed in the activity is not "msg" but is the string passed from the intent "I am the other activity". Why do you have to have the variable declaration above for the code to work? I don't understand what its doing.
Thanks
You are getting the extra received from another Activity indexed by the key 'msg'.
Like when you do this with the Intent used to start your Activity:
intent.putExtra("msg", "text going in the TextView");
The key is 'msg', but the value you get for the TextView is 'text going in the TextView'
Yes, final means EXTRA_MESSAGE value won't change, but you're not displaying EXTRA_MESSAGE value, but
getIntent().getStringExtra(EXTRA_MESSAGE)
which actually contains the value put in the previous activity. Regarding your question
Why do you have to have the variable declaration above for the code to work?
You don't actually need that variable for the code to work, but it's a good practice to use constant values instead of just hardcoding string values such in.-
getIntent().getStringExtra("msg")
The parameter you pass to getStringExtra is the key to which the String is mapped. All the extras you put in an Intent are mapped as key-value, so if you want to get a value you have to know the key, which must be the same key you used in the previous activity to save the value (with putStringExtra).
http://developer.android.com/reference/android/content/Intent.html#getStringExtra(java.lang.String)
I am using an intent to start another activity, and making my intent carry some data as an extra to the newly created activity. I am following a tutorial to do that.
This data is actually read from a text field in the first activity in the hierarchy, and carried to the other activity as an extra. so my code will be like:
//Make the intent
Intent intent = new Intent(this, SecondActivity.class);
/* Find the text field (view) which contains the data, and save it into a newly created text field (view of the same type)*/
EditText editText = (EditText) findViewById(R.id.iden1); //******************************
//Read that view's string data into a string called message
String message= editmessage.getText().toString();
//copy this message into the extra named extra_name, of intent.
intent.putExtra(extra_name, message);
My question is from this statement:
EditText editText = (EditText) findViewById(R.id.iden1);
My question is explicit casting i.e. (EditText). Why are we casting the EditText view (which was defined in layout.xml and was identified by android:id="#+id/iden1") returned by findViewById()to an EditText view again. The type of the view editText here and the one created in layout.xml is the same. So what is the point of this type-casting?
The point is that findViewById(int id) returns a generic View object. This method doesn't parse your xml in order to understand what kind of type is your view. It just makes a new View object from the relationship put in place by your R.java file, built up by your IDE (Eclipse, I suppose).
You need to cast the result of findViewById(int id) because you're not casting an EditText object, your casting a View, of which EditText is only a specification.
findViewById returns a View. If you need to use methods of a derived class you need to cast. If you need to use only the methods of the base class you can avoid the cast
I still am a beginner in Android development and will try to make my question as clear as possible with a schema of what I have in my mind.
Purpose of this application:
- I want the user to have the choice between a few buttons and when clicking on any of them, it would open a list view with different content according to the button.
ex : if you click on "Category_1" button, only elements with a fitting id will appear in the listview.
So far, I have :
- defined my "handler" class (extends SQLiteOpenHelper) : name/path of DB, definition of CRUD, .getReadableDatabase, etc.
- define a class for my table, in my case "Restaurants.java" with getters/setters and constructor.
- defined my MainActivity with empty listeners for my button.
- defined my "DatabaseAdapter.java" in which I want to define the methods/sql requests which will communicate with the database and get the information I want from it.
- defined my ListViewActivity with nothing to display so far.
Here is a schema of what I want with the idea of how to make it to try to optimize my application :
To sum up:
- I want a listener for each button setting a variable to a certain value (for example: "if you click on 1 then set the value of A to 1") and opening the ListViewActivity.
- There would be a method defined in "...Adapter.java" sending a request to the database and having the variable A defined earlier as an input.
- And then, when clicking on the button, the ListViewActivity will open and call the method from "..Adapter.java", and finally display the results.
So, here are my questions :
- First of all, is the design optimized enough to allow my application to run fast? I think it should as all the button open only one activity and there is only one method defined for all buttons.
- I have a hard time defining the method in "...Adapter.java" which will be called from my ListViewAcitivity. The input should be the variable obtained when clicking on the button but I don't really know how to get a variable in one activity, open a second activity where to display results by using the variable in a third activity... :s
Is it fine to set a variable to a certain value when we click on a button and use this variable in another class as an input for a method?
public findNameInTable(int A){
string sql = " select NAME from MY_TABLE where CAT1 = " + A;
c = database.rawQuery(sql, null); }
Thanks in advance for any indications, suggestions or links which could help me to make my application come true, and sorry if some questions really sounds newbie, I am starting !
Have a good day !
Part 1: The best way I have found to pass variables to other activities is with a putExtra(String, variable);. Say you change the variable name on a button press, you can then call:
YourNewActivityClassName var = new YourNewActivityClassName();
Intent i = new Intent(context, YourNewActivityClassName.class);
i.putExtra("name", name);
startActivity(i);
Then in the activity you just created, you can call this in the onCreate method:
Intent i = getIntent();
final String name = i.getStringExtra("name");
Of course this is assuming the variable was defined as a String before the putExtra was called.
If you want to use other variable types, there are different get***Extra commands you can call like getIntExtra(int, defaultval) but the putExtra will still be used to send it.
Part 2: For calling a method with a variable assigned in a button click, I have found the best way to do this is with a "holder class" this holder can be defined as a final, and a button press assigns a value to one of it's slots. Here is my holder for Integers:
public class holder {
int to;
public void setTo(int to){
this.to = to;
}
public int getTo(){
return to;
}
}
I instantiate my class as final within my on create final holder hold = new holder();
then call my hold.setTo(int); within a list click listener. When I want to get the data, I simply call hold.getTo(); and I have my integer.
Heres a similar post: Pass value outside of public void onClick
Hope this helps!
Mike
In my app I have 5 String arrays that represent different fields of objects.
i.e.
String_A[1],
String_B[1],
String_C[1],
String_D[1],
String_E[1],
All are attributes of the same object (which is not really an object).
Now I want to store those in order to be able to use them in a new activity that I am creating. Since you are not able to pass objects around I thought that i should save them in Shared preferences.
My question is: Should I save them as separate strings or create a new class with all those fields and then serialize the objects?
Which is the best way in terms of memory usage? In fact is there any other way that you might achieve similar functionality?
Thanks in advance
Mike
If each of those String Arrays are big "enough" and it appears you do want to store them - have you considered Sqlite? SharedPreferences is most effective to store primitive data in key-value pairs. Check this link - it has neat comparison about the options you have - http://developer.android.com/guide/topics/data/data-storage.html
You can pass around objects via an intent. The extras function of an intent can store a bundle and send it to specified activities, however they cannot be called at any time (like from a later activity without being explicitly sent). If this is a one time pass to a different activity, the you'd probably want to use that.
http://developer.android.com/reference/android/content/Intent.html#putExtras%28android.content.Intent%29
Here is an example from a test app I made a while back:
public void onClick(View v) {
switch(v.getId()) { //this references the unique ID of the view that was clicked
case R.id.Button01: //this is what happens when the Button in the XML with android:id="#+id/Button01" is clicked
Intent nameGreet = new Intent(this, MainMenu.class);//creates Intent which will send the EditText input
String theName = firstName.getText().toString();// creates a new string named "theName" which is the text from an EditText called "firstName"
nameGreet.putExtra("helloName", theName);//puts the input from EditText into the Intent, this is a key/value pair
this.startActivity(nameGreet);//setting off the Intent
break;
Then you catch it like so:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setContentView(R.layout.main_menu);
String personsname = this.getIntent().getStringExtra("helloName");
welcome = (TextView)this.findViewById(R.id.TextView01);
welcome.setText(personsname);
Hope this helps.
You can pass a Serializable using an Intent.
Intent.putExtra(String name, Serializable value).