【问题标题】:Method to get all EditTexts in a View获取视图中所有EditTexts的方法
【发布时间】:2011-12-09 01:58:12
【问题描述】:

谁能帮我编写一种方法来获取视图中的所有 EditText?我想实施此处发布的解决方案 htafoya: How to hide soft keyboard on android after clicking outside EditText?

很遗憾,getFields() 方法丢失了,htafoya 没有回答我们分享他的getFields() 方法的请求。

【问题讨论】:

    标签: android


    【解决方案1】:

    获取任何类型布局中的所有编辑文本。

    public List<EditText> getAllEditTexts(ViewGroup layout){
            List<EditText> views = new ArrayList<>();
            for(int i =0; i< layout.getChildCount(); i++){
                View v =layout.getChildAt(i);
                if(v instanceof EditText){
                    views.add((EditText)v);
                }
            }
            return views;
        }
    

    【讨论】:

      【解决方案2】:

      此方法递归遍历所有 ViewGroup 并收集它们的 TextView。我用它来为所有 TextViews 分配一个新的颜色(即使是那些嵌入在使用 TextViews 的预定义小部件中,如 Switch 等)

      private HashSet<TextView> getTextViews(ViewGroup root){
          HashSet<TextView> views=new HashSet<>();
          for(int i=0;i<root.getChildCount();i++){
              View v=root.getChildAt(i);
              if(v instanceof TextView){
                  views.add((TextView)v);
              }else if(v instanceof ViewGroup){
                  views.addAll(getTextViews((ViewGroup)v));
              }
          }
          return views;
      }
      

      【讨论】:

        【解决方案3】:

        这是我编写的一种方法,用于递归检查 ViewGroup 的所有 EditText 子项,这对于我必须执行的长注册表单很方便,并且可能更易于维护。

        private EditText traverseEditTexts(ViewGroup v)
        {
            EditText invalid = null;
            for (int i = 0; i < v.getChildCount(); i++)
            {
                Object child = v.getChildAt(i); 
                if (child instanceof EditText)
                {
                    EditText e = (EditText)child;
                    if(e.getText().length() == 0)    // Whatever logic here to determine if valid.
                    {
                        return e;   // Stops at first invalid one. But you could add this to a list.
                    }
                }
                else if(child instanceof ViewGroup)
                {
                    invalid = traverseEditTexts((ViewGroup)child);  // Recursive call.
                    if(invalid != null)
                    {
                        break;
                    }
                }
            }
            return invalid;
        }
        
        private boolean validateFields()
        {   
            EditText emptyText = traverseEditTexts(mainLayout);
            if(emptyText != null)
            {
                Toast.makeText(this, "This field cannot be empty.", Toast.LENGTH_SHORT).show();
                emptyText.requestFocus();      // Scrolls view to this field.
            }
            return emptyText == null;
        }
        

        【讨论】:

          【解决方案4】:

          编辑

          MByD 指出了一个错误,因此我的答案几乎与黑带的答案相同。我已将我的编辑为正确的方法。


          您可以执行一个 for-each 循环,然后检查每个视图是否属于 EditText 类型:

          ArrayList<EditText> myEditTextList = new ArrayList<EditText>();
          
          for( int i = 0; i < myLayout.getChildCount(); i++ )
            if( myLayout.getChildAt( i ) instanceof EditText )
              myEditTextList.add( (EditText) myLayout.getChildAt( i ) );
          

          您也可以拥有一个 ID 列表,而不是 EditTexts 列表,然后将孩子的 id 添加到列表中:myIdList.add( child.getId() );


          要访问您的布局,您需要获取它的参考。这意味着您需要在 XML 中为您的布局提供一个 ID:

          <LinearLayout android:id="@+id/myLinearLayout" >
             //Here is where your EditTexts would be declared
          </LinearLayout>
          

          然后,当您在活动中扩展布局时,您只需确保保存对它的引用:

          LinearLayout myLinearLayout;
          
          public void onCreate( Bundle savedInstanceState ) {
             super( savedInstanceState );
             setContentView( R.layout.myLayoutWithEditTexts );
          
             ...
          
             myLinearLayout = (LinearLayout) findViewById( R.id.myLinearLayout );
          }
          

          然后,您可以在活动中引用您的 EditTexts 的持有者。

          【讨论】:

          • 你确定这条线是有效的吗:for( View child : myLayout ) ?
          • 看来我的回复有点草率 - 正如 MByD 所说,for-each 循环对于视图/布局无效。
          • 我现在感觉很糟糕,我无法让您的建议发挥作用。到目前为止,我已经编写了几页 android/java 代码,但我被困在这里。我发现我必须为列表类型包含 java.util.list。但后来 Eclipse 告诉我 new List&lt;EditText&gt;() 无效......而且我想知道列表类型是否与数组 [] htafoya 的解决方案兼容。这是一样的还是我也必须将其更改为列表?感谢您的帮助!
          • 嗯,List 问题可能是我的错误。尝试将其更改为ArrayList。如果您需要一个数组而不是列表,您只需在完成添加/删除列表后使用myList.toArray()。列表的优点是它是动态的,这意味着不需要像普通数组那样固定大小。
          • 希望我的最后一个问题:如何访问布局?
          【解决方案5】:

          您可以通过调用View#getFocusables 来完成此操作,这将返回一个视图中所有可聚焦视图的数组列表。

          然后您可以使用 (instanceof) 检查它们是否是 EditTexts,或者对它们都采取行动。

          【讨论】:

            猜你喜欢
            • 2012-01-12
            • 1970-01-01
            • 1970-01-01
            • 2014-12-16
            • 2011-07-23
            • 1970-01-01
            • 1970-01-01
            • 2013-03-04
            • 1970-01-01
            相关资源
            最近更新 更多