How to use setBackground with an Android Widget
android, android-layout, android-widget
Solution
A co-worker had the answer, I should have used:
remoteViews.setInt(R.id.nmcButton, "setBackgroundResource", color);
Instead of:
remoteViews.setInt(R.id.nmcButton, "setBackground", color);
Problem
I asked a similar question before but I was too vague in my request. The code below draws a nice stylized button. When you click on the button, you can input a number and based on the number, changes the background color using remoteViews.setInt(R.id.nmcButton, "setBackgroundColor", color); Unfortunately, when I try to preserve the styling by using remoteViews.setInt(R.id.nmcButton, "setBackground", color); the widget won't load. Is there a way around this? Is there a way to preserve the styling while changing the background color? Here are some of the relevant files ``` package test.widget; import android.os.Bundle; import android.app.PendingIntent; import android.appwidget.AppWidgetManager; import android.appwidget.AppWidgetProvider; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.util.Log; import android.widget.RemoteViews; import android.graphics.Color; public class MyWidget extends AppWidgetProvider { private final static String TEST_ACTIVITY = "test.widget.action.TEST_ACTIVITY"; private final static int INTENT_NO_REQUEST = 0; /* no requestCode */ private final static int INTENT_NO_FLAGS = 0; /* code for no Flags */ private int count = 9; @Override public void onReceive(Context context, Intent intent) { super.onReceive(context, intent); Bundle b = intent.getExtras(); if (b != null) { count = b.getInt("nmcCount"); callOnUpdate(context); } } private void callOnUpdate(Context context) { AppWidgetManager appWidgetManager = AppWidgetManager .getInstance(context); ComponentName thisAppWidget = new ComponentName( context.getPackageName(), MyWidget.class.getName()); int[] appWidgetIds = appWidgetManager.getAppWidgetIds(thisAppWidget); onUpdate(context, appWidgetManager, appWidgetIds); } @Override public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { super.onUpdate(context, appWidgetManager, appWidgetIds); buildUpdate(context, appWidgetManager, appWidgetIds); } private void buildUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { final int N = appWidgetIds.length; for (int i = 0; i < N; i++) { int appWidgetId = appWidgetIds[i]; RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget); Intent intent = new Intent(TEST_ACTIVITY); PendingIntent pendingIntent = PendingIntent.getActivity(context, INTENT_NO_REQUEST, intent, INTENT_NO_FLAGS); remoteViews.setOnClickPendingIntent(R.id.nmcButton, pendingIntent); remoteViews.setTextViewText(R.id.nmcButton, String.valueOf(count)); // the code below works, but the button does not have nice styling // int color = (count >= 5) ? Color.GREEN : Color.RED; // remoteViews.setInt(R.id.nmcButton, "setBackgroundColor", color); // this code doesn't work, you get "problem loading widget" int color = (count >= 5) ? R.drawable.btn_green : R.drawable.btn_red; remoteViews.setInt(R.id.nmcButton, "setBackground", color); appWidgetManager.updateAppWidget(appWidgetId, remoteViews); } } } ``` btn_red.xml ``` <?xml version="2.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_pressed="true"><shape> <solid android:color="#ef4444" /> <stroke android:width="1dp" android:color="#992f2f" /> <corners android:radius="3dp" /> <padding android:bottom="10dp" android:left="10dp" android:right="10dp" android:top="10dp" /> </shape></item> <item><shape> <gradient android:angle="270" android:endColor="#992f2f" android:startColor="#ef4444" /> <stroke android:width="1dp" android:color="#992f2f" /> <corners android:radius="3dp" /> <padding android:bottom="11dp" android:left="10dp" android:right="10dp" android:top="10dp" /> </shape></item> </selector> ``` styles.xml ``` <resources> <style name="ButtonText"> <item name="android:layout_width">wrap_content</item> <item name="android:layout_height">wrap_content</item> <item name="android:gravity">center</item> <item name="android:layout_margin">1dp</item> <item name="android:textSize">10dp</item> <item name="android:textStyle">normal</item> <item name="android:shadowColor">#000000</item> <item name="android:shadowDx">1</item> <item name="android:shadowDy">1</item> <item name="android:shadowRadius">2</item> <item name="android:textColor">#ffffff</item> </style> <style name="AppTheme" parent="android:Theme.Light" /> </resources> ```