【发布时间】:2011-12-09 01:58:12
【问题描述】:
谁能帮我编写一种方法来获取视图中的所有 EditText?我想实施此处发布的解决方案 htafoya: How to hide soft keyboard on android after clicking outside EditText?
很遗憾,getFields() 方法丢失了,htafoya 没有回答我们分享他的getFields() 方法的请求。
【问题讨论】:
标签: android
谁能帮我编写一种方法来获取视图中的所有 EditText?我想实施此处发布的解决方案 htafoya: How to hide soft keyboard on android after clicking outside EditText?
很遗憾,getFields() 方法丢失了,htafoya 没有回答我们分享他的getFields() 方法的请求。
【问题讨论】:
标签: android
获取任何类型布局中的所有编辑文本。
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;
}
【讨论】:
此方法递归遍历所有 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;
}
【讨论】:
这是我编写的一种方法,用于递归检查 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;
}
【讨论】:
编辑
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 ) ?
new List<EditText>() 无效......而且我想知道列表类型是否与数组 [] htafoya 的解决方案兼容。这是一样的还是我也必须将其更改为列表?感谢您的帮助!
List 问题可能是我的错误。尝试将其更改为ArrayList。如果您需要一个数组而不是列表,您只需在完成添加/删除列表后使用myList.toArray()。列表的优点是它是动态的,这意味着不需要像普通数组那样固定大小。
您可以通过调用View#getFocusables 来完成此操作,这将返回一个视图中所有可聚焦视图的数组列表。
然后您可以使用 (instanceof) 检查它们是否是 EditTexts,或者对它们都采取行动。
【讨论】: