我想创建一个ListView
小部件,在小部件中显示ArrayList
个数据....
我花了很长时间尝试将ListView
添加到窗口小部件,但它添加时没有显示任何数据。
虽然我在添加断点时在类之间成功获取数据
我不知道问题是什么......
这些是我的课程:
package com.example.android.advancebakingapp.Widget;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Parcelable;
import android.util.Log;
import android.widget.RemoteViews;
import android.widget.Toast;
import com.example.android.advancebakingapp.BuildConfig;
import com.example.android.advancebakingapp.MainActivity;
import com.example.android.advancebakingapp.Model.Ingredient;
import com.example.android.advancebakingapp.R;
import java.lang.reflect.Array;
import java.util.ArrayList;
/**
* Implementation of App Widget functionality.
*/
public class BakingAppWidgetProvider extends AppWidgetProvider
{
public static Ingredient[] mIngredients;
public ArrayList<Ingredient> parcelables;
public static ArrayList<Ingredient> ingredients1= new ArrayList<>();
public static final String WIDGET_UPDATE_ACTION = "android.appwidget.action.APPWIDGET_UPDATE";
private static final String TAG = "WidgetProvider";
public BakingAppWidgetProvider()
{
}
@Override
public void onReceive(final Context context, final Intent intent)
{
super.onReceive(context, intent);
final Bundle bundle = intent.getBundleExtra("BUNDLE");
if(bundle != null) {
parcelables = (ArrayList<Ingredient>) bundle.getSerializable("INGREDIENTS");
ingredients1.addAll(parcelables);
}
else {
Toast.makeText(context,"nuuuuuuuul",Toast.LENGTH_LONG).show();
}
intent.setAction(WIDGET_UPDATE_ACTION);
if (BakingAppWidgetProvider.WIDGET_UPDATE_ACTION.equals(intent.getAction()))
{
if (BuildConfig.DEBUG)
Log.d(BakingAppWidgetProvider.TAG, "onReceive "
+ BakingAppWidgetProvider.WIDGET_UPDATE_ACTION);
final AppWidgetManager appWidgetManager = AppWidgetManager
.getInstance(context);
final ComponentName thisAppWidget = new ComponentName(
context.getPackageName(), BakingAppWidgetProvider.class.getName());
final int[] appWidgetIds = appWidgetManager
.getAppWidgetIds(thisAppWidget);
onUpdate(context, appWidgetManager, appWidgetIds);
}
}
/**
* method will update the ListView each time the user opens the IngredientsActivity,
* meaning that the widget will always show the last IngredientsActivity Ingredients[] that the user seen.
* @param context app context
* @param appWidgetManager app WidgetManger
* @param appWidgetIds ids which will be updated
* @param ingredients the ingredients that will fill the ListView
*
*/
static void updateAppWidget(Context context, AppWidgetManager appWidgetManager,
int appWidgetIds[], Ingredient[] ingredients)
{
mIngredients = ingredients;
for (int appWidgetId : appWidgetIds)
{
Intent intent = new Intent(context, listViewsService.class);
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.baking_app_widget_provider);
views.setRemoteAdapter(R.id.list_view_widget, intent);
ComponentName component = new ComponentName(context, BakingAppWidgetProvider.class);
appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetId, R.id.list_view_widget);
appWidgetManager.updateAppWidget(component, views);
}
}
/**
* the widget will update itself each time the IngredientsActivity will open,meaning that this method
* is unnecessary in our implementation.
* @param context app context
* @param appWidgetManager the application WidgetManager
* @param appWidgetIds ids which will be updated
*/
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds)
{
if (BuildConfig.DEBUG)
Log.d(BakingAppWidgetProvider.TAG, "onUpdate");
Intent serviceIntent = new Intent(context,WidgetUpdateService.class);
Bundle args1 = new Bundle();
args1.putSerializable("INGREDIENTS",parcelables);
serviceIntent.putExtra("BUNDLE", args1);
context.sendBroadcast(serviceIntent);
serviceIntent.setAction("android.appwidget.action.APPWIDGET_UPDATE");
context.startService(serviceIntent);
}
@Override
public void onEnabled(Context context)
{ }
@Override
public void onDisabled(Context context)
{ }
}
&#13;
package com.example.android.advancebakingapp.Widget;
import android.app.IntentService;
import android.appwidget.AppWidgetManager;
import android.content.ComponentName;
import android.content.Intent;
import android.os.Bundle;
import android.os.Parcelable;
import android.support.annotation.Nullable;
import android.widget.Toast;
import com.example.android.advancebakingapp.MainActivity;
import com.example.android.advancebakingapp.Model.Ingredient;
import com.example.android.advancebakingapp.Model.Step;
import java.util.ArrayList;
public class WidgetUpdateService extends IntentService
{
public static final String WIDGET_UPDATE_ACTION = "android.appwidget.action.APPWIDGET_UPDATE";
private Ingredient[]mIngredients;
ArrayList<Ingredient> parcelable = new ArrayList<>();
public WidgetUpdateService()
{
super("WidgetUpdateService");
}
@Override
protected void onHandleIntent( Intent intent)
{
if (intent != null && intent.getAction().equals(WIDGET_UPDATE_ACTION)) {
final Bundle bundle = intent.getBundleExtra("BUNDLE");
parcelable =(ArrayList<Ingredient>) bundle.getSerializable("INGREDIENTS");
if (parcelable != null)
{
mIngredients = new Ingredient[parcelable.size()];
for (int i = 0; i < parcelable.size(); i++)
{
mIngredients[i] = (Ingredient) parcelable.get(i);
}
}
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(this);
int[] appWidgetIds = appWidgetManager.getAppWidgetIds(new ComponentName(this, BakingAppWidgetProvider.class));
intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
BakingAppWidgetProvider.updateAppWidget(this, appWidgetManager, appWidgetIds,mIngredients);
}
}
}
&#13;
package com.example.android.advancebakingapp.Widget;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.widget.RemoteViews;
import android.widget.RemoteViewsService;
import android.widget.Toast;
import com.example.android.advancebakingapp.Model.Ingredient;
import com.example.android.advancebakingapp.R;
public class listViewsService extends RemoteViewsService
{
public static final String TAG = "ListViewsService";
/**
* @param intent intent that triggered this service
* @return new ListViewsFactory Object with the appropriate implementation
*/
public ListViewsFactory onGetViewFactory(Intent intent)
{
return new ListViewsFactory(this.getApplicationContext());
}
}
class ListViewsFactory implements RemoteViewsService.RemoteViewsFactory
{
private Context mContext;
private Ingredient[] mIngredients;
public ListViewsFactory(Context mContext)
{
this.mContext = mContext;
}
@Override
public void onCreate()
{
mIngredients = BakingAppWidgetProvider.mIngredients;
}
//Very Important,this is the place where the data is being changed each time by the adapter.
@Override
public void onDataSetChanged()
{
mIngredients = BakingAppWidgetProvider.mIngredients;
}
@Override
public void onDestroy()
{
}
@Override
public int getCount()
{
if (mIngredients == null)
return 0;
return mIngredients.length;
}
/**
* @param position position of current view in the ListView
* @return a new RemoteViews object that will be one of many in the ListView
*/
@Override
public RemoteViews getViewAt(int position)
{
RemoteViews views = new RemoteViews(mContext.getPackageName(), R.layout.baking_app_widget_ingrediant);
views.setTextViewText(R.id.text_view_recipe_widget, mIngredients[position].getIngredient());
return views;
}
@Override
public RemoteViews getLoadingView()
{
return null;
}
@Override
public int getViewTypeCount()
{
return 1;
}
@Override
public long getItemId(int position)
{
return position;
}
@Override
public boolean hasStableIds()
{
return true;
}
}
&#13;
这些是我的布局:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#09C"
android:padding="@dimen/widget_margin">
<ListView
android:id="@+id/list_view_widget"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/widgetBodyMarginTop" />
</RelativeLayout>
&#13;
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="@dimen/widgetPadding"
android:background="#FFFFFF">
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
style="@style/TextAppearance.AppCompat.Display1"
android:id="@+id/text_view_recipe_widget"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center">
</TextView>
</LinearLayout>
&#13;
谢谢。
答案 0 :(得分:0)
你检查过onDataSetChanged()是否被调用? 您是否使用以下权限在清单中声明了RemoteViews服务?
android:permission =“android.permission.BIND_REMOTEVIEWS”
答案 1 :(得分:0)
我的建议是不使用像这种情况那样的静态变量:
mIngredients = BakingAppWidgetProvider.mIngredients;
我所做的是使用intent putExtra方法将数据传递到远程适配器,然后从listViewsService中的intent中提取数据。使用一些虚拟数据测试listViewsService代码,并验证它是否显示在窗口小部件中。如果你可以看到虚拟数据,那么你的listViewsService代码是正确的,你需要检查数据的来源,在这种情况下,我认为静态变量的值是问题的原因。如果这有帮助,请告诉我。祝你好运。