How to disable a button on an appwidget?


SDK Version: 
M3

Would you like to disable a button on an appwidget?
As far as I know it can not be done, since the appwiget UI manipulation is limited by the methods of the RemoteViews class.

But if you insist to do that there is a way to make it look like the button were disabled!

RemoteViews can't manipulate a buttons enabled/disabled state, but it can modify its visibility. So the trick is to have two buttons, the real one, and an other which is designed to look like the real one in disabled state, and change witch one is visible.

Lets see a simple example:
We want to have two buttons on the widget, a stop and a start button in order to stop and start some kind of functionality. Once we have started it, we can not start it agin, until we stopped it and vica versa, so we want to disable the button which can not be used right now.

The XML definition of the buttons can be like this:

  1. <Button android:id="@+id/startbutton" android:text="Start" android:visibility="visible" android:layout_width="wrap_content" android:layout_height="wrap_content"></Button>
  2. <Button android:id="@+id/startbutton_disabled" android:text="Start" android:clickable="false" android:textColor="#999999" android:visibility="gone" android:layout_width="wrap_content" android:layout_height="wrap_content"></Button>
  3.  
  4. <Button android:id="@+id/stopbutton" android:text="Stop"  android:visibility="gone" android:layout_width="wrap_content" android:layout_height="wrap_content"></Button>
  5. <Button android:id="@+id/stopbutton_disabled" android:text="Stop" android:clickable="false" android:textColor="#999999" android:visibility="visible" android:layout_width="wrap_content" android:layout_height="wrap_content"></Button>

The code that runs when clicked on the start button will contain someting like this:

  1. RemoteViews remoteView = new RemoteViews(context.getPackageName(), R.layout.widget);
  2. remoteView.setViewVisibility(R.id.startbutton, View.GONE);
  3. remoteView.setViewVisibility(R.id.startbutton_disabled, View.VISIBLE);
  4. remoteView.setViewVisibility(R.id.stopbutton, View.VISIBLE);
  5. remoteView.setViewVisibility(R.id.stopbutton_disabled, View.GONE);
  6. AppWidgetManager.getInstance(context).updateAppWidget(appWidgetId, remoteView);

And the same for the stop button:

  1. RemoteViews remoteView = new RemoteViews(context.getPackageName(), R.layout.widget);
  2. remoteView.setViewVisibility(R.id.startbutton, View.VISIBLE);
  3. remoteView.setViewVisibility(R.id.startbutton_disabled, View.GONE);
  4. remoteView.setViewVisibility(R.id.stopbutton, View.GONE);
  5. remoteView.setViewVisibility(R.id.stopbutton_disabled, View.VISIBLE);
  6. AppWidgetManager.getInstance(context).updateAppWidget(appWidgetId, remoteView);

A working example can be downloaded HERE