Why this type casting? - android

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

Related

Android one line getText() declarations. What is the difference?

What is the difference? Aren't they actually the same thing?
I'm getting "Cannot resolve method 'getText' in 'View'"
string = findViewById(R.id.signup_email).getText().toString();
But it's working perfectly.
textView = findViewById(R.id.signup_email);
string = textView.getText().toString();
First of all findViewById(R.id.signup_email) returns the View object, so when you write this statement findViewById(R.id.signup_email).getText() here getText() applies on view object (apparently View class does not contain this method).
But when you separate in two lines, here textView = findViewById(R.id.signup_email); the View object will be type cast to TextView or EditText (which you defined) object. so from here you will get this method.
If you want to keep in single line you can use
string = ((TextView) findViewById(R.id.signup_email)).getText().toString();
you can do something like this
((TextView)findViewById(R.id.signup_email)).getText().toString();
if you do just findViewById you will get View as the returned Object which is the parent of TextView but have a limited method to work with. So if we know what type of our view is we should cast the Object to the correct view intended So we can perform a variety of operation specific to that view.
In this case, it's TextView that is the reason we cast it to it and then we are able to use the getText() method of TextView Class which was not available in the View class hence you were getting compilation error for the usage of that method.
findViewById() returns a View. So the view does not heve getText() method. So if you modify the first option as follows:
string = ((TextView)findViewById(R.id.signup_email)).getText().toString();
With this, it will cast view to TextView and than you can call get text method.

Semantics - Android EditText Class

I'm struggling a bit with some semantics on some basic Android/Java development. If I have the following code (which works) to gather user input from a textfield:
final EditText userInput=(EditText) findViewById(R.id.txtUserInput);
Is userInput an object or a variable? My understanding that it is an object being instantiated form the *EditText * class. What does the (EditText) do to the left of the findViewById. When I see open parens, I think casting. Can anyone provide some simple clarity?
You are correct in saying that userinput is an EditText Object, to be more specific it is an object that is a subclass of View. Everything you get back from the findViewbyId() method will be a View, which you then need to cast to the proper Object. The (EditText) is casting the View you got back from your xml to an EditText. This allows you to access methods from the EditText that are available to the EditText class in particular.
So whenever you use findViewById() you also need to cast the View you get to the Object that it represents.
Let me know if you need further help.
-Dejan
userinput is an object.
findViewById(xxx) returns a View object, but in your case you know that it will return an EditText. Therefore its possible to cast it with (EditText). And you can cast it from a View to EditText since EditText extends View.
When you have cast it to EditText you are able to find all methods exposed by EditText instead of only the methods exposed in View.

Application with different requests sent to a database (SQL) depending on buttons clicked

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

Declare content of Intent in layout for value of TextView

All
I'm new to Android, but have some Java experience.
I'm working through the standard lessons, and I've created the 2 basic Activities with the EXTRA_MESSAGE String passing between the activities and being displayed.
The content of the first Activity is static and declared in the layout file. The content of the second Activity is dynamic ( based on the value entered in an EditText on the first Activity ) and is built in the onCreate() method in the second Activity.
Is is possible to define the dynamic content in the layout file ? Something like:
android:text="the value of EXTRA_MESSAGE in the Intent that is passed to this Activity" ?
I understand the lesson is showing me two ways of doing things, but is this do-able ?
I think you have mean this:
android:text="#string/EXTRA_MESSAGE"
You can also set the text programmatacly:
TextView myText = (TextView) findViewById(R.id.txt_mytext);
myText.setText("This value will be shown");
//Or if you defined a static string in another Activity
myText.setText(FirstActivity.stringName);

do i need global variable or R.string.x is ok?

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");

Categories

Resources