我想制作一个带有 ListView 的小部件,您可以在其中添加 listItems 来显示计数器计时器,以查看您有多少时间来处理某个事件。
这是我第一次使用小部件,我不知道我的方法是好还是坏,到目前为止我得到了这个:
AppWidgetProvider 用于通过启动服务的周期性事件来启动可运行程序。该服务称为 UpdateService,它正在更新数据集并刷新 listView。
好吧,我可以说它正在工作,但是每次刷新发生时,我的列表视图都会闪烁很短的时间,就像列表项消失很短的时间然后重新出现并刷新值。它非常丑陋,我想摆脱它。
我尝试将 listView 的 cacheColorHint 更改为 #00000000 但没有解决我的问题,也无法在互联网上找到任何内容。
如果可以的话请提供帮助,如果这种方法不是实现此“时间计数器列表”的最佳方法,请提供一些建议
public class WidgetProvider extends AppWidgetProvider {
static public String TAG = "widgetProvider";
static Handler handler = new Handler();
//TODO: stop runnables at widget destroying
static MyRunnable myRunnable;
static long refreshInterval = 1000 * 1;
//Runnable for refreshing my widget
class MyRunnable implements Runnable {
Context context;
public MyRunnable(Context context) {
this.context = context;
}
public void run() {
Log.i(TAG, "My runnable has ran!");
context.startService(new Intent(context, UpdateService.class));
handler.postDelayed(myRunnable, refreshInterval);
}
}
//Service for updating the widget
public static class UpdateService extends Service {
@Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
Log.i(TAG, "UpdateService - onStart()");
int[] appWidgetIds = AppWidgetManager.getInstance(getApplicationContext()).getAppWidgetIds(new ComponentName(getApplicationContext(), WidgetProvider.class));
int N = appWidgetIds.length;
Log.i(TAG, "appWidgetIds.length: " + appWidgetIds.length);
for (int i = 0; i < N; ++i) {
//Changing dataset
ListProvider.populateAndRefreshData();
//Notifying the listview about the change
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(getApplicationContext());
appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetIds, R.id.listViewWidget);
}
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
@Override
public void onDeleted(Context context, int[] appWidgetIds) {
//TODO: stop runnables
}
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
super.onUpdate(context, appWidgetManager, appWidgetIds);
final int N = appWidgetIds.length;
//init each widget, then call the runnable for periodic event for counting time
for (int i = 0; i < N; ++i) {
RemoteViews remoteViews = updateWidgetListView(context, appWidgetIds[i]);
appWidgetManager.updateAppWidget(appWidgetIds[i], remoteViews);
}
//start the runnable
myRunnable = new MyRunnable(context);
handler.postDelayed(myRunnable, 0);
}
private static RemoteViews updateWidgetListView(Context context, int appWidgetId) {
Log.i(TAG, "updating a widget: " + appWidgetId);
//which layout to show on widget
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
//RemoteViews Service needed to provide adapter for ListView
Intent svcIntent = new Intent(context, WidgetService.class);
//passing app widget id to that RemoteViews Service
svcIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
//setting a unique Uri to the intent
svcIntent.setData(Uri.parse(svcIntent.toUri(Intent.URI_INTENT_SCHEME)));
//setting adapter to listview of the widget
remoteViews.setRemoteAdapter(appWidgetId, R.id.listViewWidget, svcIntent);
//setting an empty view in case of no data
remoteViews.setEmptyView(R.id.listViewWidget, R.id.empty_view);
return remoteViews;
}
}
RemoteViewService用于定义适配器
public class WidgetService extends RemoteViewsService {
/*
* Defining the Adapter of the listview here Adapter is ListProvider
*/
@Override
public RemoteViewsFactory onGetViewFactory(Intent intent) {
int appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
return (new ListProvider(this.getApplicationContext(), intent));
}
}
Adapter:
/**
* Adapter of ListView
*
*/
public class ListProvider implements RemoteViewsFactory {
public static ArrayList<Record> listItemList = new ArrayList<Record>();
private Context context = null;
private int appWidgetId;
public ListProvider(Context context, Intent intent) {
this.context = context;
appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
populateAndRefreshData();
}
//TODO: just test populating
public static void populateAndRefreshData() {
listItemList = new ArrayList<Record>();
Record record = new Record();
record.name = DateUtils.getIntervalToDate("2015-07-01 10:00:00");
record.content = "...";
record.icon = R.drawable.logo_1;
listItemList.add(record);
}
@Override
public int getCount() {
return listItemList.size();
}
@Override
public long getItemId(int position) {
return position;
}
/*
* Similar to getView of Adapter where instead of Viewwe return RemoteViews
*/
@Override
public RemoteViews getViewAt(int position) {
final RemoteViews remoteView = new RemoteViews(context.getPackageName(), R.layout.list_row);
Record listItem = listItemList.get(position);
remoteView.setTextViewText(R.id.heading, listItem.name);
remoteView.setImageViewResource(R.id.imageView, listItem.icon);
return remoteView;
}
@Override
public RemoteViews getLoadingView() {
return null;
}
@Override
public int getViewTypeCount() {
return 1;
}
@Override
public boolean hasStableIds() {
return true;
}
@Override
public void onCreate() {}
@Override
public void onDataSetChanged() {}
@Override
public void onDestroy() {}
}