我如何引用尚未在xml文件中创建的视图?

时间:2013-04-27 21:41:09

标签: java android eclipse android-layout

//首先我有这个方法,下面是我的问题

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

我知道当oncreate()方法启动复选框时会创建对象然后我将数字ID从0分配到for循环停止的任何地方,但稍后在程序中我需要检索点击的复选框所以首先我需要id但是eclipse不会让我把数字ID,请帮忙!抱歉我的英语我是机器人和英语的菜鸟

this.CheckBox =(CheckBox)this.findViewById(R.id。?);

3 个答案:

答案 0 :(得分:1)

正如您在View课程中所读到的,文档ID在树中应该是唯一的。您可以搜索。

您为TextView和Checkbox设置了相同的ID。

如果您知道您将在创建后稍后访问它们,请在数组中保留对它们的引用,而不是稍后使用findViewById尝试检索它们。

但更好的解决方案是为它们设置onClick事件监听器并跟踪检查/取消选中它们。

在@ HalR的回答中您可以阅读如何为您的复选框设置onCheckedChanged事件侦听器。在他的解决方案中将有一个已选中复选框的ArrayList。

下一步,你必须增加正确TextView的值,所以你需要将CheckBoxes和TextViews结合起来。

我认为最好的方法是使用TextView id的值为CheckBox设置Tag。

因此,在用户提交You迭代List of checkboxes,getTag并在findViewById中使用它来获取TextView并更新其值。

Id(IDentifier的缩写)是一个唯一标识元素的整数,您可以在findViewById中使用它来获取视图元素。您可以阅读more about ID in this answer

标签用于将View元素与您在getTag documentation中阅读的一些额外数据相关联。它作为参数对象类型,因此您设置标签不仅仅是数字。在你的情况下你可以将ChechBox的标签设置为TextView而不是它的id,它也可以工作。

答案 1 :(得分:0)

您是手动将您的ID设置为行的索引,这是我认为我不会做的事情。我通常使用setTag()来识别我的对象。

我认为使用侦听器检测复选框何时被检查会更容易,并且您可以在检查发生时跟踪更改。

使用类似的东西:

在您的Activity中,创建一个ArrayList

ArrayList<CheckBox> checkedBoxes = new ArrayList<CheckBox>();

然后在你的创作中:

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

Id vs Tag

的一些信息

Id是一个数值,用于标识视图层次结构中的视图。如果您正在使用布局中的内容,例如将一个视图与另一个视图对齐,那么它们会查找并期望具有特定ID的视图。所以在布局中,你将拥有android:id="@+id/bigBox",这将创建一个与bigBox关联的数字。当您找到该视图时,findViewById()就是它要查找的数字。当您手动设置这些数字时,您似乎在寻找麻烦。如果您将视图的ID设置为2,那么您应该可以使用myView = findViewById(2)找到它。

Tag是一个非常小的对象指针,可以与视图一起传递。通常它会是一个行号:

  Integer saveMe = new Integer(i);
  checkBox.setTag(saveMe);

或者它甚至可以是指向您用于创建该行的原始数据对象的指针。如果您使用联系人创建了每一行,则可以使用

myRow.setTag(contact)

以后当您点击该行时,您只需使用

contact = (Contact)myRow.getTag()

你会得到原来的联系方式。它的方式比保留行或复选框或whatevers的大数组清晰。只需使用侦测器来检测您何时执行某些操作,这是一种更好的方法。

哦,如果你确实有一个由你的CheckBox触发的onClick(View view),那么这个视图就是你的CheckBox。

CheckBox theBoxIJustChecked = (CheckBox)view;

你不需要用一些id来查找它。它就在那里。

答案 2 :(得分:0)

如果你想这样做,你应该做适当的操作,即:

for(int i = 0; i < n; ++i){
    ...
    ...(CheckBox))this.findViewById(i);
    ...
}

它应该适合你

但是要小心,好像在视图树中有相同ID的视图数量比 findViewById(i)可以返回意外结果,例如返回视图树中的第一个视图给定的id(它可能不是CheckBox类型,可能导致ClassCAstException)

更新回复评论

如果你想建立某种逻辑连接CheckBox-TextView,有几个选项:

  1. 您可以创建一个类似下面的函数(假设CheckBoxes和TextViews数量有限制):
  2. 代码:

    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;
    }
    

    然后你应该使用该函数将id设置为TextViews。

    checkBox.setId(i);
    textView.setId(getTextVieIdByCheckBoxId(i));
    ....
    // add Views to your layout
    ....
    (CheckBox)this.findViewById(i);
    TextView)this.findViewById(getTextVieIdByCheckBoxId(i));
    

    2.我认为有一些更准确的方法: 只需使用CheckBox实例的 setTag()来设置内部适当的TextView以创建互连。在这种情况下,您必须将所有创建的复选框存储在某个List或数组中:

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

    然后你可以达到你想要的效果:

    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
        }
    }
    

    在这里,您不需要生成id并担心可能产生的冲突