View.setEnabled(false)在android中不能正常工作

时间:2013-10-07 12:10:07

标签: android view android-ui

我刚发现View.setEnabled(false)在android中运行不正常,方法如下:

  1. 禁用父视图不会自动禁用子视图。这很不方便。
  2. 虽然颜色为灰色,但禁用的视图仍然可以获得焦点并获得键盘输入,做出选择等。这是不对的。
  3. 获取键盘输入时,无论输入多少,DEL / BACK都只能向后移除一个键。此行为仅在禁用的EditText中显示。
  4. 无线电标签显示为灰色,但单选按钮图像未显示为灰色。
  5. 这似乎是一个错误。但是如何获得真正的DISABLE功能呢?

    编辑:忘记提及第一个。

4 个答案:

答案 0 :(得分:3)

需要递归设置所有后代,否则布局中的RadioButtons将不会获得setEnabled,因为RadioButtons是非直接子节点的子节点,其间有RadioGroup。到目前为止,我根据其他人的回答记录了我最好的解决方案。

public static void setEnabledAll(View v, boolean enabled) {
    v.setEnabled(enabled);
    v.setFocusable(enabled);

    if(v instanceof ViewGroup) {
        ViewGroup vg = (ViewGroup) v;
        for (int i = 0; i < vg.getChildCount(); i++)
            setEnabledAll(vg.getChildAt(i), enabled);
    }
}

此时子类不起作用。如果我有:

public MyView class View {
    protected void setEnabled(boolean enabled, boolean setChildren){
        setEnabled(enabled);
        setFocusable(enabled);
        if(setChildren && this isinstanceof ViewGroup){
              for ( int i = 0 ; i < this.getChildCount() ; i++ )
                  //this line will have issue if it is not MyView                      
                  this.getChildAt(i).setEnabled(enabled, true); 
        }
    }
}

除非View本身像这样重载了setEnabled:

public class View {
    protected void setEnabled(boolean enabled, boolean setChildren){
        setEnabled(enabled);
        setFocusable(enabled);
        if(setChildren && this isinstanceof ViewGroup){
              for ( int i = 0 ; i < this.getChildCount() ; i++ )         
                  this.getChildAt(i).setEnabled(enabled, true); 
        }
    }
}

此解决方案将消除问题1,2,3。问题4可以通过为RadioGroup设置禁用样式选择器来解决 - 我不确定为什么android没有为RadioGroup设置默认禁用样式选择器。也许是Android增强的另一点。 Android在SDK设计方面非常灵活,也意味着有时需要额外的工作。

答案 1 :(得分:1)

从记忆中,请原谅错别字:

class ExtendedLinearLayout extends LinearLayout{

    protected void setEnabled(boolean enabled, boolean setChildren){

        super.setEnabled(enabled);

        if(setChildren){
              for ( int idx = 0 ; idx < this.getChildCount() ; idx++ ) {
                  (View)(this.getChildAt(idx)).setEnabled(enabled);
              }
        }
    }
}

答案 2 :(得分:0)

我没有回答你的所有问题,但我会尝试firstsecond

  • 1 在禁用Parent时不禁用子项是绝对正确的。考虑一种情况,您希望单击布局的按钮但不想单击外部区域。 Listrow中的最佳示例,您有要单击但不想单击行的按钮。

    立即停用所有儿童

    LinearLayout layout = (LinearLayout) findViewById(R.id.my_layout);
    for (int i = 0; i < layout.getChildCount(); i++) {
    View child = layout.getChildAt(i);
    child.setEnabled(false);
     }
    
  • 2 它仅针对EditText发生,但您也可以将其停止。 view.setFocusable(false);是正确的停止视图获得焦点

答案 3 :(得分:0)

只想用kotlin更新此Michael SM' solution。覆盖视图的方式如下:

override fun setEnabled(enabled: Boolean) {
    super.setEnabled(enabled)
    children.forEach { it.isEnabled = enabled }
}

现在拨打电话是:

view.isEnabled = false
相关问题