如何禁用安卓系统的按钮?

444

我已经创建了一个包含“下一页”和“上一页”两个按钮的布局。在这些按钮之间,我正在生成一些动态视图。因此,当我首次启动应用程序时,由于没有任何先前的视图,我想禁用“上一页”按钮。当没有更多视图可显示时,我还想禁用“下一页”按钮。有没有办法禁用这些按钮?

示例布局的屏幕截图

13个回答

919

你试过这个了吗?

myButton.setEnabled(false); 

更新:感谢Gwen。几乎忘了可以在你的XML布局中设置android:clickable来确定按钮是否可点击。


73
相当于XML中的android:enabled。 - Namratha
1
你在文档中找到了这个信息吗?能否在这里提供链接? - Varun
5
@Namratha 这只适用于“Button”小部件,而不适用于作为按钮的imageView。 - mehmet
Xamarin 等价代码:myButton.Enabled = false; - Cameron Forward

58

是的,可以在XML中禁用它,只需使用:

<Button
android:enabled="false"
/>

7
这是 XML 的真正答案。所有那些把可点击性搞乱的废话都与按钮如何绘制以使其看起来被禁用无关。 - SMBiggs
3
我认为人们认为你做不到这一点是因为AS/IDEA代码完成在你开始输入时不建议使用android:enabled。(即使到现在也是如此。) - Kevin Krumwiede
4
我尝试了,但它不起作用,只有通过代码中的 setEnabled 起作用。 - FindOutIslamNow

52

你无法在XML中启用或禁用它(因为布局是在运行时设置的),但是你可以在活动启动时设置是否可点击,使用android:clickable


7
我有5年的Android经验,但现在才知道这件事!:/ - Sagar

46

您只需在活动中编写一行代码

Button btn = (Button) findViewById(R.id.button1);
btn.setEnabled(false);

当您想要启用相同的按钮时,只需编写

Button btn = (Button) findViewById(R.id.button1);
btn.setEnabled(true);

28
这是两行代码,这是其中一行: ((Button)findViewById(R.id.mybutton)).setEnabled(false); 它的作用是禁用一个名为"mybutton"的按钮。 - Matt Clark
44
尝试理解马特的感受.. ;) - Deepak Sharma

31

在Java中,一旦您获得了按钮的引用:

Button button = (Button) findviewById(R.id.button);

要启用/禁用按钮,您可以使用以下任一方法:

button.setEnabled(false);
button.setEnabled(true);

或者:

button.setClickable(false);
button.setClickable(true);

如果您想从一开始就禁用按钮,则可以在onCreate方法中使用 button.setEnabled(false);。 否则,您可以直接从XML中使用:

android:clickable = "false"
所以:
<Button
        android:id="@+id/button"
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"
        android:text="@string/button_text"
        android:clickable = "false" />

回答于2010年12月8日上午7:08,Varun - user146043
1
@Poldie:实际上,如果你读了这两个答案,你会明白它们非常相似但并不相等。 - Paolo Rovelli

10

在 Kotlin 中,如果您使用 id 引用 Button View,则可以像这样启用/禁用按钮

layout.xml

<Button
   android:id="@+id/btn_start"
   android:layout_width="100dp"
   android:layout_height="50dp"
   android:text="@string/start"
   android:layout_alignParentBottom="true"/>

activity.kt

  btn_start.isEnabled = true   //to enable button
  btn_start.isEnabled = false  //to disable button

10

就我的情况而言,

myButton.setEnabled(false);
myButton.setEnabled(true);

目前情况是功能正常,它能够按照预期启用和禁用按钮。但是一旦按钮状态变为禁用状态,即使它可点击,也不会再回到启用状态。我尝试了使绘图状态失效并刷新,但没有成功。

myButton.invalidate();
myButton.refreshDrawableState();

如果你或其他人遇到类似的问题,我使用的解决方法是重新设置背景drawable。在任何API级别上都有效。

myButton.setEnabled(true);
myButton.setBackgroundDrawable(activity.getResources().getDrawable(R.drawable.myButtonDrawable));

7

Kotlin让你可以做到以下事情:

// to disable clicks
myButton.isClickable = false 

// to disable button
myButton.isEnabled = false

// to enable clicks
myButton.isClickable = true 

// to enable button
myButton.isEnabled = true

1
// 启用按钮 myButton.isEnabled = false <----- 应该为 true - NullPointer

4

错误的方法:在监听器中使用变量而不是参数!!!

btnSend.setOnClickListener(new OnClickListener() {

    @Override
    public void onClick(View v) {
        btnSend.setClickable(false);

    }
});

正确的方法:

btnSend.setOnClickListener(new OnClickListener() {

    @Override
    public void onClick(View v) {

        /** check given view  by assertion or cast as u wish */
        if(v instance of Button) {

            /** cast */
            Button button = (Button) v;

            /** we can perform some check up */
            if(button.getId() == EXPECTED_ID) {

                /** disable view */
                button.setEnabled(false)            
                button.setClickable(false); 
            }

        } else {

             /** you can for example find desired view by root view  */
             Button bt = (Button) v.getRootView().findViewById(R.id.btId);

             /*check for button */
             if(bt!=null) {

                 /** disable button view */
                 ...
             } else {
                 /** according to @jeroen-bollen remark
                   * we made assumption that we expected a view
                   * of type button here in other any case  
                   */
                  throw new IllegalArgumentException("Wrong argument: " +
                         "View passed to method is not a Button type!");
             }
          }
       }
    });

编辑: 回复@jeroen-bollen

 View.OnClickListener 

is Interface definition for a callback to be invoked when a view is clicked.

with method definition

void onClick(View v);
当视图被点击时,View类对象会回调方法onClick()并将自身作为参数发送,因此如果发生null视图参数,则是一个断言错误。例如当View对象类在此期间被销毁(例如被GC收集)或由于黑客攻击而篡改方法时,可能会发生这种情况。
关于instanceof和null的一点说明:
JLS / 15.20.2. 类型比较运算符 instanceof
在运行时,如果RelationalExpression的值不为null并且引用可以转换为ReferenceType而不引发ClassCastException,则instanceof运算符的结果为true。否则结果为false。
作者的三个字:
如果你问为什么?
大多数情况下是为了避免NullPointerException。
更多的代码将节省您以后在代码中进行错误跟踪的时间,并减少异常出现的次数。
考虑以下示例:
View.OnClickListener listener = new OnClickListener() {

    @Override
    public void onClick(View v) {
        btnSend.setClickable(false);

    }
});

btnSend.setOnClickListener(listener)
btnCancel.setOnClickListener(listener)  

2
似乎每次else表达式被调用时,代码已经出现了错误。您期望一个按钮,但传递了其他东西。当“v”不是“Button”时,应该抛出异常。 - Jeroen
不完全是我想表达的,但仍然有所改善。 - Jeroen
@JeroenBollen 请详细说明一下 :) 好的,我看到只有一个不一致的地方,就是关于“错误视图传递给方法”的异常消息。除此之外,这只是尝试展示它应该是什么样子的。 - ceph3us
我的意思是当函数本身接收到null时,这已经是一个bug了,应该抛出异常。 - Jeroen

4

你可以在xml中禁用按钮,但那不会是动态的。最好的方式是动态地禁用按钮。

myButton.setEnabled(false);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接