2

//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.?);

Bongoking
  • 3
  • 2
Trainee Programmer
  • 171
  • 1
  • 3
  • 18
  • why should you know the id of objects to comprobe if they are checked? also, addrows should be addRows instead, for java good practice. – aran Apr 27 '13 at 22:29

3 Answers3

1

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.

Community
  • 1
  • 1
Gustek
  • 3,680
  • 2
  • 22
  • 36
  • thanks for the help :), but this is what im trying to do: first i have a tableview where depend of the user input it will fill with a name and a checkbox, so lets say the user adds 2 names so in my db will be 2 rows with the columns name(text) and asist(int) so when the user enter into the mainActivity the table layout will have 2 textview and 2 checkboxes(the ones i need the id) and if the user check the 2 checkboxes for example and then click on a button i created, the app must add 1 to the field asist depending on the checkboxes that were checked, could be only 2, like this example or more – Trainee Programmer Apr 27 '13 at 23:21
  • so i need to retrieve all the information of which checkboxes were checked all at once – Trainee Programmer Apr 27 '13 at 23:23
  • Hi Gustek : )! thanks for the help , the last thing i think i need is the same question i made for halR but if you like to answer it too iwill be very thankfull to you. look: what is the difference between setTag() and setId() ?? and how can you retrieve the tag? for example for the id is: txtNombres = (TextView)findViewById(j); thanks you so much and sorry again for my English XD! – Trainee Programmer Apr 28 '13 at 04:16
0

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.

HalR
  • 11,411
  • 5
  • 48
  • 80
  • excuse me , I almost understand so let me ask you one more question. what is the difference between setTag() and setId() ?? and how can you retrieve the tag? for example for the id is: txtNombres = (TextView)findViewById(j); thanks you so much! – Trainee Programmer Apr 28 '13 at 04:10
0

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:

  1. 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

vir us
  • 9,920
  • 6
  • 57
  • 66