I have two activities; the first activity starts the second one with some data passed through the intent.
Intent i = new Intent(this,BActivity.class);
i.putExtra("identify", "c2f");
startActivityForResult(i, 1);
In the second activity, I want to make some TextViews/EditTexts visible (which are initially set to invisible) based on the information passed from the first activity.
Here's the code for that:
tv1 = (TextView)findViewById(R.id.textView2);
tv2 = (TextView)findViewById(R.id.textView3);
et1 = (EditText)findViewById(R.id.editText1);
et2 = (EditText)findViewById(R.id.editText2);
button = (Button)findViewById(R.id.send_result);
Bundle extras = getIntent().getExtras();
String identifier = extras.getString("identify");
if(identifier == "c2f")
{
tv1.setVisibility(0);
tv1.setText("Celcius");
et1.setVisibility(0);
}
else if(identifier == "f2c")
{
tv1.setVisibility(0);
tv1.setText("Fahrenheit");
et1.setVisibility(0);
}
else if(identifier == "currency")
{
tv1.setVisibility(0);
tv1.setText("Amount");
tv2.setVisibility(0);
tv2.setText("Conv. Rate");
et1.setVisibility(0);
et2.setVisibility(0);
}
Now when the second activity starts, none of these TextViews or EditTexts seem to get visible!
identifier (string) holds the correct value passed from first activity and it even goes into the if conditions, but it doesn't make any view visible.
Am I making any mistake in trying to make these views visible?
Use .equals instead of == to string comparison. You can also use the variable after the quoted string to avoid nullpointer. And you can use TextView.VISIBLE, it's a constant to get it visible.
if("c2f".equals(identifier))
{
tv1.setVisibility(TextView.VISIBLE);
tv1.setText("Celcius");
et1.setVisibility(TextView.VISIBLE);
}
Simply use the View's constants for this.
your_view.setVisibility(View.VISIBLE);
This will make your View visible.
your_view.setVisibility(View.INVISIBLE);
This will make it invisible but still with the layout visible (basically, the space where it goes remains untouched)
your_view.setVisibility(View.GONE);
This will make your View disappear, like it never existed!
As pointed by giacomoni, please use equals for String comparison. Here is a link to explain why.
http://javarevisited.blogspot.in/2012/03/how-to-compare-two-string-in-java.html
Also, try using the standard View.VISIBLE etc constants for showing and hiding views. They are much more easy to use and understand. Happy coding. :)
Related
I have 2 activities in my assignment: MainActivity and Country_Activity.
I'm trying to pass 2 inputs the user puts in MainActivity:
int counter
String Country
But the app always crashes here: (this is Country_Activity)
private void Update(){
Intent mIntent = getIntent();
int intValue = mIntent.getIntExtra("intCounter", 0);
String country = mIntent.getStringExtra("country");
counterTextView.setText(intValue);
countryTextView.setText(country);
if (country.equals("canada")){
flagView.setImageResource(R.drawable.canada);
}
else if (country.equals("us")){
flagView.setImageResource(R.drawable.us);
}
}
Specifically on the lines "setText" for each variable.
Everything else works. I can't figure out why they wouldn't.
Thanks!
Usually the extras that are passed from one activity to another are read inside on onCreate() where all the needed initialization of variables and views is made.
In your case I see that you get the extras inside another method (maybe it's called inside onCreate()?).
So you forgot to initialize the textviews:
TextView counterTextView = findViewById(R.id.countersomething);
TextView countryTextView = findViewById(R.id.countrysomething);
also another error that you will encounter later is this:
counterTextView.setText(intValue);
change it to:
counterTextView.setText(String.ValueOf(intValue));
Don't pass an integer value inside setText() because it will be treated as the id of a resource.
My goal is to programmatically change the text size of a Textview item within certain Cardviews, which are contained in a recyclerview. I am successfully able to do that, with an unusual side effect. What happens then is that, although the correct cardviews' textview's properties have been successfully modified, random cards, which are not suppose to be modified, are now modified. However, as the user scrolls through more and more of the recyclerview, both directions, the more and more cards are modified. Eventually, what began with a few random cards (in addition to my request cards) lead to all the calls being modified.
A better example: Let's say I have 5 cards I want to change the text size to something else, within a recyclerview containing 50 cards. Now, those cards, along with a few other, random cards, are now have big text. The rest remain small. As the user scrolls up and down, more and more cards are being set to have big text, until all cards have big text.
How my code works is that I have a class, ListAdapter which extends RecyclerView.Adapter<ListAdapter.VersionViewHolder>. Since I gather my objects from a database, I use arraylists to gather my info, and programmically add them in, as shown:
#Override
public void onBindViewHolder(VersionViewHolder versionViewHolder, int i) {
if (ActivitiesList.size() != 0)
versionViewHolder.title.setText(ActivitiesList.get(i));
if (ActivitiesSubList.size() != 0)
versionViewHolder.subTitle.setText(ActivitiesSubList.get(i));
if (ActivitiesSubList2.size() != 0)
versionViewHolder.subTitle2.setText(ActivitiesSubList2.get(i));
if (ActivitiesID.size() != 0)
versionViewHolder.id.setText(ActivitiesID.get(i));
// TODO: POST QUESTION ON STACK OVERFLOW
if (!ActivitiesTag.get(i).equals("")) {
Log.d("CardPos", Integer.toString(versionViewHolder.getAdapterPosition()));
versionViewHolder.title.setTextSize(TypedValue.COMPLEX_UNIT_SP, 56);
}
}
I set ActivitiesList,ActivitiesSubList,ActivitiesSubList2,ActivitiesID, and ActivitiesTag within a child class GradesListAdapter which extends the ListAdapter.
What should be noted is the ActivitiesTag Arraylist. When I wish to add an value to be large, I simply insert any non-empty value into the arraylist. Otherwise, I add an empty string. Thus, for it to be large, it must successfully fulfill the criteria. (On a side note, is there any way of improving this method?) On testing, it appears that only the cards with the correct position are set to be large, but nevertheless it also affects non-tagged cards.
Here is the VersionViewHolder class:
class VersionViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
CardView cardItemLayout;
TextView title;
TextView subTitle;
TextView subTitle2;
TextView id;
public VersionViewHolder(View itemView) {
super(itemView);
cardItemLayout = (CardView) itemView.findViewById(R.id.grades_item);
title = (TextView) itemView.findViewById(R.id.listitem_name);
subTitle = (TextView) itemView.findViewById(R.id.listitem_subname);
subTitle2 = (TextView) itemView.findViewById(R.id.listitem_subname2);
id = (TextView) itemView.findViewById(R.id.listitem_id);
itemView.setOnClickListener(this);
}
#Override
public void onClick(View v) {
clickListener.onItemClick(v, getAdapterPosition());
}
}
What can I do to remove this unintended side effect? I believe I have all the data needed for others to help debug this, but if I'm missing something, please say so; I'm still quite new to StackOverflow.
Thank you for reading.
In your onbindViewHolder, change
if (!ActivitiesTag.get(i).equals("")) {
Log.d("CardPos", Integer.toString(versionViewHolder.getAdapterPosition()));
versionViewHolder.title.setTextSize(TypedValue.COMPLEX_UNIT_SP, 56);
}
to
if (!ActivitiesTag.get(i).equals("")) {
Log.d("CardPos", Integer.toString(versionViewHolder.getAdapterPosition()));
versionViewHolder.title.setTextSize(TypedValue.COMPLEX_UNIT_SP, 56);
}else{
versionViewHolder.title.setTextSize(TypedValue.COMPLEX_UNIT_SP,"Your Original Text Size");
}
If you only set an if clause without an else clause in viewholder, since this view is reused again and again, your text size will not be reset to normal. So, you'll have to manually reset the text size.
I get a nullPointerException on status variable on this line of code : if (view.getId() == R.id.button && status.equals("Dorado"). Now ive looked on many threads in here and i havnt really gotten much luck with this exception. Like many others, i pass a string from activity 1 to activity 2, except this string is extracted from the textview when it is pressed(Dorado).
Activity 1:
TextView text = (TextView) view;
String selection = text.getText().toString();
Bundle b = new Bundle();
b.putString("Selection", selection);
Intent i = new Intent(MunicipioList.this,SubestacionInfo.class);
i.putExtra("extra", b);
startActivity(i);
Acitivity 2:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_subestacion_info);
Bundle extras = getIntent().getExtras();
if (extras != null) {
extras = extras.getBundle("extra");
status = extras.getString("Selection");
}
}
I know the bundle isnt necessary i was just experimenting since i was still getting Null with other codes. Ah one more thing, the status varoable is global, declared right at the beginning of the activity as "public String status;" so i dont believe that to be the issue here, Any help? :)
Lets break this down. If you get an NPE in this line:
if (view.getId() == R.id.button && status.equals("Dorado"))
then either:
view is null, or
R.id is null (which I think is impossible), or
status is null.
You should be able to work out which with a debugger, or by adding a traceprint. But I suspect that it is status.
You say:
Ah one more thing, the status variable is global, declared right at the beginning of the activity as "public String status;" so I don't believe that to be the issue here.
That declaration does not initialise status. Did you initialize status following the declaration? If not, its initial value will be null, and that would be sufficient to cause an NPE ... if you never changed it!
//first i have this method , below is my question
public void addrows(){
TableRow fila;
tabla = (TableLayout)findViewById(R.id.tabla);
TextView txtNombre;
for(int i = 0;i<id;i++){
String x[] = helper.leer();
layoutFila = new TableRow.LayoutParams(TableRow.LayoutParams.WRAP_CONTENT,
TableRow.LayoutParams.WRAP_CONTENT);
caja= new CheckBox(this);
fila = new TableRow(this);
fila.setLayoutParams(layoutFila);
txtNombre = new TextView(this);
txtNombre.setId(i);
txtNombre.setTextSize(17);
txtNombre.setText(x[i]);
txtNombre.setGravity(Gravity.LEFT);
// txtNombre.setLayoutParams(layoutTexto);
caja.setText("");
caja.setId(i);
fila.addView(txtNombre);
fila.addView(caja);
tabla.addView(fila);
}
}
i know that when the oncreate() method start the checkboxes objects are created and then i assign an numerical id from 0 to wherever the for cycle stop , but later in the program i need to retrieve what checkboxes were clicked so first i need the id but eclipse wont let me put the numerical id, please help! and sorry for my English i'm a noob in android and the English language
this.CheckBox = (CheckBox)this.findViewById(R.id.?);
As You may read in View class documentation ID should be unique within a tree You search.
You set same id for TextView and Checkbox.
If You know You are going to access them all later after creation keep references to them in array instead of trying to retrieve them later using findViewById.
But even better solution would be to set onClick event listener for them and keep track of checking/unchecking them.
In #HalR's answer You may read how to set onCheckedChanged event listeners for Your checkboxes. Folowing his solution will have an ArrayList of checked checkboxes.
Next step, You have to increment values of correct TextView so You need to couple CheckBoxes and TextViews.
I think best for this would be to set Tag for CheckBox with value of TextView id.
So after user submits You iterate over List of checkboxes, getTag and use it in findViewById to get TextView and update its value.
Id (short for IDentifier) is an integer to uniquely identify elements, You can use it in findViewById to get view elements. You can read more about ID in this answer
Tag is used to associate View element with some extra data as You may read in getTag documentation. It takes as parameter Object type so You set as tag anything not only numbers. In Your case You could set as ChechBox's tag a TextView instead of its id and it will work too.
You are manually setting your id to the index of the row, which is something I don't think I'd do. I'd normally use setTag() to identify my object.
I think it would be easier to use a listener to detect when the checkboxes have been checked, and you can track the changes when the check happens.
use something like this:
In your Activity, create a ArrayList
ArrayList<CheckBox> checkedBoxes = new ArrayList<CheckBox>();
then in your creation:
caja= new CheckBox(this);
caja.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView,boolean isChecked) {
int index = buttonView.getId();//pulling back the number you set originally, if that is what you like. I would get the tag I had set, and maybe do something here.
//do something in here!
if (buttonView.isChecked()) {
//including this checkbox in the list of checked boxes
checkedBoxes.addObject(buttonView);
} else {
//take it out of the list of checked boxes
checkedBoxes.removeObject(buttonView);
}
}
};
Some info on Id vs Tag
Id is a numeric value that identifies the view in the view hierarchy. If you are using things in your layout, like aligning one view with another, they look for and expect a view with a specific id. So in layout, you'll have android:id="#+id/bigBox" and that will create some number that it associates with bigBox. When you find that view, with findViewById() that is the number it is looking for. When you manually set those numbers, it seems like you are asking for trouble. If you set a view's id to 2, then you should be able to find it with myView = findViewById(2).
Tag is a nicely little object pointer that you can pass along with your view. Quite often it will be a row number:
Integer saveMe = new Integer(i);
checkBox.setTag(saveMe);
Or it can even be a pointer to your original data object that you used to create that row. If you had created each row using a contact, you could use
myRow.setTag(contact)
and later when you clicked on that row, you would just use
contact = (Contact)myRow.getTag()
and you would have your original contact back. Its way cleaner than keeping big arrays of your rows or checkboxes, or whatevers. Just use listeners that detect when you do something, that is a much better way.
Oh, and if you if you do have an onClick(View view) that is triggered by your CheckBox, that view IS your CheckBox.
CheckBox theBoxIJustChecked = (CheckBox)view;
You don't need to look it up with some id. It's right there.
If you want to go this way than you should just do the apposite operation i.e.:
for(int i = 0; i < n; ++i){
...
...(CheckBox))this.findViewById(i);
...
}
It should work for you
However be careful as if you have number of views with the same id inside the view-tree than findViewById(i) can return an unexpected result such as returning the first view in view-tree with given id (it can be not of CheckBox type which can lead to ClassCAstException)
Update in reply to comment
If you want to make some sort of logical connection CheckBox-TextView there are several options:
You can make a sort of function like the following (assuming that there is the limit of CheckBoxes and TextViews quantity):
Code:
private static int CHECK_BOX_MAX_NUMBER = 10000;
public void int getTextVieIdByCheckBoxId(int checkBoxId){
if(checkBoxId >= CHECK_BOX_MAX_NUMBER){
// you can throw an exception here for example
}
return CHECK_BOX_MAX_NUMBER + checkBoxId;
}
And then you should set id's to your TextViews with that function.
checkBox.setId(i);
textView.setId(getTextVieIdByCheckBoxId(i));
....
// add Views to your layout
....
(CheckBox)this.findViewById(i);
TextView)this.findViewById(getTextVieIdByCheckBoxId(i));
or
2.I think there is a little bit more accurate method:
Just use setTag() of CheckBox instances to set appropreate TextView inside in order to create interconnection. In thiscase you have to store all the created checkBoxes in some List or array:
List<CheckBox> checkBoxList = new ArrayList<CheckBox>();
for(int i = 0; i < n; ++i){
...
CheckBox checkBox = new CheckBox();
TextView textView = new TextView();
checkBox.setTag(textView);
checkBoxList.add(checkBox);
}
Then you can achieve what you want like this:
int textBoxListSize = checkBoxList.size();
for(int i = 0; i < textBoxListSize; ++i){
CheckBox checkBox = checkBoxList.get(i);
if(chechkBox.isChecked()){
TextView textView = (TextView)checkBox.getTag();
//do whatever with textView
}
}
Here you don't need to generate id's and worry about collisions which could accure
So I'm trying to create an activity that passes some values into another activity and then, depending on those values, chooses one of several different layouts.
I know that the values are passed through fine, but it won't display the layout (or any layout, it just stays on the previous screen). My code is:
public class ContactDisplay extends GetContact {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle extras = getIntent().getExtras();
String nameChosen = extras.getString("nameSpinner");
String addressChosen = extras.getString("addressSpinner");
if((nameChosen == "Michael") && (addressChosen == "Michaels Address")){
setContentView(R.layout.contact1_layout);
}
}
}
I've only set it up to with one of the layouts so far, but it should work if Michael and Michaels Address are chosen. Does anyone have any idea where I'm going wrong?
Use this code instead:
if((transportItemChosen.equals("Michael")) && (locationItemChosen.equals("Michaels Address"))){
setContentView(R.layout.contact1_layout);
}
In Java you want to use the equals() function when comparing strings not the == operator.
The first thought is that I would try to not use hard coded values for extras because you can misspell something and it is very easy to get stuck ... if that is not the problem then try to make some logs and see what exactly you receive in transportItemChosen and locationItemChosen
EDIT:
And yes, to compare two Objects you have to use equals() method not the == operator.