2012-11-21 7 views
5

Ich fragte eine ähnliche Frage vor, aber ich war zu vage in meiner Anfrage. Der folgende Code zeichnet einen schönen stilisierten Knopf. Wenn Sie auf die Schaltfläche klicken, können Sie eine Zahl eingeben und basierend auf der Nummer die Hintergrundfarbe mitWie benutze setBackground mit einem Android Widget

remoteViews.setInt (R.id.nmcButton, "setBackgroundColor", Farbe);

Leider, wenn ich versuche, das Styling zu bewahren, indem sie mit

remoteViews.setInt (R.id.nmcButton "setBackground", Farbe);

das Widget wird nicht geladen. Gibt es einen Weg dahin? Gibt es eine Möglichkeit, das Styling beizubehalten und gleichzeitig die Hintergrundfarbe zu ändern?

Hier sind einige der relevanten Dateien

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> 

Antwort

13

Ein Mitarbeiter die Antwort hatte, sollte ich verwendet habe, :

remoteViews.setInt(R.id.nmcButton, "setBackgroundResource", color); 

Statt:

remoteViews.setInt(R.id.nmcButton, "setBackground", color); 
+0

Funktioniert nicht. Das Styling ist entfernt. Es beantwortet nicht Ihre eigene Frage – AxeManTOBO

1

habe ich versucht, dies aber nicht für mich zu arbeiten.

Wenn Sie eine Farbe in Ihrem Widget setzen Sie dies tun sollten:

remoteViews.setInt(R.id.nmcButton, "setBackgroundColor", color); 
+0

Ich downvoted, weil es nicht das Problem des Verlierens von Stil nach einem setBackgroundColor behandelt –

+0

@BrenoSalgado Dann warum downvote? Dies ist vielleicht nicht die Antwort für Sie, aber es funktioniert sicher perfekt für mich.Die obige Antwort geht auch nicht auf dieses Problem ein, oder? Sie könnten auch einen Kommentar hinterlassen, dass Sie Ihren Stil verlieren, nachdem Sie diese Methode verwendet haben. –

+0

Nichts Persönliches, aber ich denke, dass es die Frage nicht richtig behandelt. Ich denke, die Qualität auf Java/Android-Antworten ist etwas niedrig, weil es zu viel davon gibt. Bei Ruby Antworten (als Beispiel) war ich an Antworten gewöhnt, die versuchen zu erklären, was das Problem für den Leser ist, Lösungsvorschläge zu machen, jede in OP gestellte Frage anzusprechen, Links zu liefern usw. Das ist der bessere Weg IMO (wenn ich ein Brief an Sie fragen Sie 3 Dinge, die Sie nur 1 beantworten und ignorieren Sie den Rest, das ist nicht die höflichste, ist es?), SO ist kein Forum (wieder, ich bin nicht gemeint, Sie zu beleidigen, aber ich denke, das gilt wahr) –

0

Das ist für mich nicht in meinem Widget in Listview nicht funktioniert, so kam ich mit einer Vermeidung des Problems auf:

Zuerst definiert ich mein Layout FrameLayout werden, wo ein Image gibt es mein Hintergrund zu zeichnen:

<?xml version="1.0" encoding="utf-8"?> 
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent"> 

    <ImageView 
     android:id="@+id/iv_widget_background" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:scaleType="fitXY" /> 

    <LinearLayout 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:background="@android:color/transparent" 
     android:orientation="vertical" 
     android:padding="@dimen/widget_listview_padding"> 

     <ListView 
      android:id="@+id/lv_widget" 
      android:layout_width="match_parent" 
      android:layout_height="match_parent" 
      android:divider="@null" 
      android:dividerHeight="0dp" /> 
    </LinearLayout> 

</FrameLayout> 

Dann definiert ich Drawables in R.drawable wie folgt aus:

red.xml:

<?xml version="1.0" encoding="utf-8"?> 
<shape xmlns:android="http://schemas.android.com/apk/res/android" 
    android:shape="rectangle"> 
    <solid android:color="#F44336" /> 
</shape> 

Wenn der Benutzer den Hintergrund über SharedPrefs ändert Ich habe folgendes zu tun:

 Intent intent = new Intent(context, WidgetProvider.class); 
     intent.setAction("android.appwidget.action.APPWIDGET_UPDATE"); 
     intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds); 
     context.sendBroadcast(intent); 

Da ist in meinem onUpdate() Funktion in der AppWidgetProvider ich die folgende :

@Override 
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWdgetIds) { 
    try { 
     RemoteViews remoteViews; 
     for (int appWdgetId : appWdgetIds) { 
      remoteViews = updateWidgetListView(context, appWdgetId); 
      appWidgetManager.updateAppWidget(appWdgetId, remoteViews); 
     } 
     super.onUpdate(context, appWidgetManager, appWdgetIds); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 

private RemoteViews updateWidgetListView(Context context, int appWidgetId) { 
    //which layout to show on widget 
    RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget_layout); 
    Intent svcIntent = new Intent(context, WidgetService.class); 
    svcIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);  svcIntent.setData(Uri.parse(svcIntent.toUri(Intent.URI_INTENT_SCHEME))); 
    remoteViews.setRemoteAdapter(appWidgetId, R.id.lv_widget, svcIntent); 

    setBackground(context, remoteViews); 

    return remoteViews; 
} 

private void setBackground(Context context, RemoteViews remoteViews) { 
    String background = Utils.getStringValue(context, R.string.pref_widget_backgroundcolor_key, 
      R.string.pref_widget_backgroundcolor_default); 

    if (!TextUtils.isEmpty(background)) { 
     int identifier = context.getResources().getIdentifier(
       background, "drawable", context.getPackageName()); 
     remoteViews.setImageViewResource(R.id.iv_widget_background, identifier); 
    } 
} 

Ergebnis:

enter image description here