2012-11-21 17 views
5

Tôi đã hỏi một câu hỏi tương tự trước đây nhưng tôi quá mơ hồ trong yêu cầu của mình. Mã dưới đây vẽ một nút cách điệu đẹp mắt. Khi bạn nhấp vào nút, bạn có thể nhập số và dựa trên số, thay đổi màu nền bằng cách sử dụngCách sử dụng setBackground với Tiện ích con Android

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

Thật không may, khi tôi cố gắng giữ gìn phong cách bằng cách sử dụng

remoteViews.setInt (R.id.nmcButton, "setBackground", màu sắc);

tiện ích sẽ không tải. Có cách nào để giái quyết vấn đề này không? Có cách nào để bảo toàn kiểu dáng trong khi thay đổi màu nền?

Dưới đây là một số các tập tin có liên quan

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> 

Trả lời

13

Một đồng nghiệp đã có câu trả lời, tôi nên đã sử dụng :

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

Thay vì:

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

Không hoạt động. Kiểu dáng được xóa. Nó không trả lời câu hỏi của riêng bạn – AxeManTOBO

1

Tôi cố gắng này nhưng điều đó không làm việc cho tôi.

Nếu bạn muốn thiết lập một màu trong widget của bạn, bạn nên làm điều này:

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

Tôi downvoted vì nó không giải quyết vấn đề mất phong cách sau khi setBackgroundColor –

+0

@BrenoSalgado Sau đó tại sao downvote? Đây có thể không phải là câu trả lời cho bạn, nhưng nó chắc chắn hoạt động hoàn hảo cho tôi.Câu trả lời ở trên cũng không giải quyết vấn đề đó đúng không? Bạn cũng có thể để lại nhận xét rằng bạn mất phong cách của mình sau khi sử dụng phương pháp này. –

+0

Không có gì cá nhân nhưng tôi nghĩ rằng nó không giải quyết đúng câu hỏi. Tôi nghĩ rằng chất lượng trên các câu trả lời Java/Android có phần thấp vì có quá nhiều điều này. Tại câu trả lời của Ruby (ví dụ) tôi đã từng trả lời cố gắng giải thích vấn đề với người đọc, đề xuất giải pháp, giải quyết từng câu hỏi được thực hiện trong OP, cung cấp liên kết, v.v. Đây là cách tốt hơn IMO (nếu tôi viết thư cho bạn hỏi bạn 3 điều bạn trả lời chỉ 1 và bỏ qua phần còn lại, đó không phải là lịch sự nhất, phải không?), SO không phải là diễn đàn (một lần nữa, tôi không có ý xúc phạm bạn, nhưng tôi nghĩ rằng điều này giữ thật) –

0

này không làm việc cho tôi trên ListView của tôi trong widget của tôi, vì vậy tôi đã đưa ra một cách giải quyết:

Trước tiên tôi được xác định bố trí của tôi để được FrameLayout nơi một ImageView là có để vẽ nền của tôi:

<?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> 

Sau đó, tôi định nghĩa drawables trong R.drawable như thế này:

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> 

Khi người dùng thay đổi nền qua SharedPrefs tôi phải làm như sau:

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

Sau đó, trong chức năng của tôi onUpdate() trong AppWidgetProvider tôi thực hiện như sau :

@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); 
    } 
} 

Kết quả:

enter image description here