【问题标题】:Android: Using findViewById() with a string / in a loopAndroid:在循环中使用带有字符串 / 的 findViewById()
【发布时间】:2011-06-19 09:52:32
【问题描述】:

我正在制作一个 android 应用程序,其中有一个由数百个按钮组成的视图,每个按钮都有一个特定的回调。现在,我想使用循环设置这些回调,而不必编写数百行代码(针对每个按钮)。

我的问题是:如何使用 findViewById 而无需静态输入每个按钮 ID? 这是我想做的:

    for(int i=0; i<some_value; i++) {
       for(int j=0; j<some_other_value; j++) {
        String buttonID = "btn" + i + "-" + j;
        buttons[i][j] = ((Button) findViewById(R.id.buttonID));
        buttons[i][j].setOnClickListener(this);
       }
    }

提前致谢!

【问题讨论】:

    标签: android button clicklistener


    【解决方案1】:

    你应该使用getIdentifier()

    for(int i=0; i<some_value; i++) {
       for(int j=0; j<some_other_value; j++) {
        String buttonID = "btn" + i + "-" + j;
        int resID = getResources().getIdentifier(buttonID, "id", getPackageName());
        buttons[i][j] = ((Button) findViewById(resID));
        buttons[i][j].setOnClickListener(this);
       }
    }
    

    【讨论】:

    • 谢谢,这正是我想要的。
    • "com.sample.project" 可以替换为 getPackageName()。
    • 我见过与此非常相似的其他答案,但第二个参数是“id”是我需要它工作的最后一件事。
    • 请注意,根据我的经验,这样做会给您带来非常糟糕的性能。
    【解决方案2】:

    您可以尝试创建一个包含所有按钮 ID 的 int[],然后对其进行迭代:

    int[] buttonIDs = new int[] {R.id.button1ID, R.id.button2ID, R.id.button3ID, ... }
    
    for(int i=0; i<buttonIDs.length; i++) {
        Button b = (Button) findViewById(buttonIDs[i]);
        b.setOnClickListener(this);
    }
    

    【讨论】:

      【解决方案3】:

      【讨论】:

      • @user573536 请注意,当您进行大量查找时,在循环中使用 getResources().getIdentifier() 会导致性能下降。
      • 你是对的。我建议仅在资源有顺序或顺序并且资源很多时才使用这种方法(创建一个由 50 个资源气味组成的数组)。
      【解决方案4】:

      如果你想访问,你可以使用标签。

      onClick

      int i=Integer.parseInt(v.getTag);
      

      但是你不能像这样访问那个按钮。

      只需以编程方式创建按钮

      Button b=new Button(this);

      【讨论】:

        【解决方案5】:

        在 java 代码中而不是在 Xml 中创建自定义按钮,如下所示

        Button bs_text[]= new Button[some_value];
        
            for(int z=0;z<some_value;z++)
                {
                    try
                    {
        
                    bs_text[z]   =  (Button) new Button(this);
        
                    }
                    catch(ArrayIndexOutOfBoundsException e)
                    {
                        Log.d("ArrayIndexOutOfBoundsException",e.toString());
                    }
                }
        

        【讨论】:

          【解决方案6】:

          如果您的顶级视图只有那些按钮视图作为子视图,您可以这样做

          for (int i = 0 ; i < yourView.getChildCount(); i++) {
              Button b = (Button) yourView.getChildAt(i);
              b.setOnClickListener(xxxx);
          }
          

          如果存在更多视图,您需要检查所选视图是否是您的按钮之一。

          【讨论】:

          • 您知道与其他建议方法相比性能如何吗?我假设它比 ID 数组稍慢,但我很想知道它与 getResources().getIdentifier() 的比较。
          • 不抱歉不知道。一个观点认识他的孩子,所以我觉得也不算太糟糕。
          【解决方案7】:

          如果由于某种原因您不能使用 getIdentifier() 函数和/或您事先知道可能的 id,您可以使用开关。

          int id = 0;
          
          switch(name) {
              case "x":
                  id = R.id.x;
                  break;
              etc.etc.
          }
          
          String value = findViewById(id);
          

          【讨论】:

            【解决方案8】:

            简单来说,这里有一个函数

            public View findViewByArrayName (String name, int i) {
                    buttonID = name + Integer.toString(i);
                    resID = getResources().getIdentifier(buttonID, "id", getPackageName());
                    return findViewById(resID);
                }
            

            与 Python 不同的是,Java 是一种编译语言,因此没有任何机会使用动态变量名可能是有道理的。除非通过像这样的某种方法来实现。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2012-04-07
              • 2013-11-08
              • 2013-11-02
              • 2017-03-29
              相关资源
              最近更新 更多