英文:
The widget is coming as empty. Using retrofit to get the data in listview
问题
I am trying to display data using retrofit inside of a widget using listview. I have checked the logs in the android studio, there are no error. App is fetching the data using retrofit. There is no issue getting data. Can someone please look at it and tell me what I have doing wrong.
App Widgete provider class
public class ExampleAppWidgetProvider extends AppWidgetProvider {
static void updateAppWidget(Context context, AppWidgetManager appWidgetManager, int appWidgetId) {
RemoteViews views = getlistView(context, appWidgetId);
appWidgetManager.updateAppWidget(appWidgetId, views);
}
static RemoteViews getlistView(Context context, int appWidgetId) {
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.example_widget);
Intent intent = new Intent(context, ExampleWidgetService.class);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
views.setEmptyView(R.id.example_widget_stack_view, R.id.example_widget_empty_view);
views.setRemoteAdapter(R.id.example_widget_stack_view, intent);
Intent launchIntent = new Intent(context, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, launchIntent, PendingIntent.FLAG_UPDATE_CURRENT);
views.setPendingIntentTemplate(R.id.example_widget_stack_view, pendingIntent);
return views;
}
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
for (int appWidgetId : appWidgetIds) {
updateAppWidget(context, appWidgetManager, appWidgetId);
}
}
}
This is RemoteViewsFactory class
public class ExampleWidgetItemFactory implements RemoteViewsService.RemoteViewsFactory {
private Context mContext;
private List<Articles> articlesList = new ArrayList<>();
private News news;
public ExampleWidgetItemFactory(Context applicationContext) {
mContext = applicationContext;
}
private void getData() {
ApiService apiService = ApiClient.getRetrofit().create(ApiService.class);
Call<News> call = apiService.getheadlines("us", "");
call.enqueue(new Callback<News>() {
@Override
public void onResponse(Call<News> call, Response<News> response) {
news = response.body();
assert news != null;
articlesList = news.getArticles();
Log.i("ExampleWidgetService", news.getStatus());
}
@Override
public void onFailure(Call<News> call, Throwable t) {
Log.i("ExampleWidgetService", t.getMessage());
}
});
}
@Override
public void onCreate() {
}
@Override
public void onDataSetChanged() {
getData();
}
@Override
public void onDestroy() {
articlesList.clear();
}
@Override
public int getCount() {
if (articlesList == null) {
return 0;
}
return articlesList.size();
}
@Override
public RemoteViews getViewAt(int position) {
RemoteViews remoteViews = new RemoteViews(mContext.getPackageName(), R.layout.example_widget_item);
remoteViews.setTextViewText(R.id.example_widget_item_text, articlesList.get(position).getTitle());
Intent fillInIntent = new Intent();
remoteViews.setOnClickFillInIntent(R.id.example_widget_item_text, fillInIntent);
return remoteViews;
}
@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;
}
}
英文:
I am trying to display data using retrofit inside of a widget using listview. I have checked the logs in the android studio, there are no error. App is fetching the data using retrofit. There is no issue getting data. Can someone please look at it and tell me what I have doing wrong.
App Widgete provider class
public class ExampleAppWidgetProvider extends AppWidgetProvider {
static void updateAppWidget(Context context,AppWidgetManager appWidgetManager,int appWidgetId){
RemoteViews views = getlistView(context,appWidgetId);
appWidgetManager.updateAppWidget(appWidgetId,views);
}
static RemoteViews getlistView(Context context, int appWidgetId){
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.example_widget);
Intent intent = new Intent(context,ExampleWidgetService.class);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,appWidgetId);
views.setEmptyView(R.id.example_widget_stack_view,R.id.example_widget_empty_view);
views.setRemoteAdapter(R.id.example_widget_stack_view,intent);
Intent launchIntent = new Intent(context,MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, launchIntent,PendingIntent.FLAG_UPDATE_CURRENT );
views.setPendingIntentTemplate(R.id.example_widget_stack_view,pendingIntent);
return views;
}
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
for (int appWidgetId : appWidgetIds) {
updateAppWidget(context,appWidgetManager,appWidgetId);
}
}
}
This is RemoteViewsFactory class
public class ExampleWidgetItemFactory implements RemoteViewsService.RemoteViewsFactory {
private Context mContext;
private List<Articles> articlesList = new ArrayList<>();
private News news;
public ExampleWidgetItemFactory(Context applicationContext) {
mContext = applicationContext;
}
private void getData(){
ApiService apiService = ApiClient.getRetrofit().create(ApiService.class);
Call<News> call = apiService.getheadlines("us","");
call.enqueue(new Callback<News>() {
@Override
public void onResponse(Call<News> call, Response<News> response) {
news = response.body();
assert news != null;
articlesList = news.getArticles();
Log.i("ExampleWidgetService", news.getStatus());
}
@Override
public void onFailure(Call<News> call, Throwable t) {
Log.i("ExampleWidgetService",t.getMessage());
}
});
}
@Override
public void onCreate() {
}
@Override
public void onDataSetChanged() {
getData();
}
@Override
public void onDestroy() {
articlesList.clear();
}
@Override
public int getCount() {
if (articlesList == null){
return 0;
}
return articlesList.size();
}
@Override
public RemoteViews getViewAt(int position) {
RemoteViews remoteViews = new RemoteViews(mContext.getPackageName(), R.layout.example_widget_item);
remoteViews.setTextViewText(R.id.example_widget_item_text,articlesList.get(position).getTitle());
Intent fillInIntent = new Intent();
remoteViews.setOnClickFillInIntent(R.id.example_widget_item_text, fillInIntent);
return remoteViews;
}
@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;
}
}
答案1
得分: 0
onDataSetChanged 只能在同步(阻塞)调用时正常工作。Retrofit 调用是异步的,所以它不会起作用。您需要做的是从 RemoteViewsFactory 类向 AppWidgetProvider 类发送包含数据的消息(可以使用 LocalBroadcastManager 或类似 EventBus 的库),以便系统手动为您刷新小部件。
英文:
onDataSetChanged only works well with synchronous (blocking) calls. The Retrofit call is asynchronous by nature so it wouldn't work. What you need to do is send a message containing the data (using either a LocalBroadcastManager or libraries like EventBus) from the RemoteViewsFactory class to the AppWidgetProvider class to have the system manually refresh the widget for you.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论