Android widget with ListView doesn't load items correclty
Asked Answered
F

2

11

I'm trying to implement a widget for my app with ListView.

To do so, I've gone step-by-step in all the following links:

  • Android app widget with list view
  • Using App Widgets with collections - developer.android.com/guide/topics/appwidgets/index.html#collections
  • Filling ListView in homescreen widget in Android - https://mcmap.net/q/752968/-filling-listview-in-homescreen-widget-in-android

However, when I place the widget on the homescreen, the number of list items does match the number of items I have in the database, but the view of each row does not update and keeps showing "Loading..." (as shown in this screen capture)

I don't unnderstand what is missing.

Thanks a lot in advance for your help!

Here is my AppWidgetProvider:

package com.appro.illbeback;

import com.appro.illbeback.R;
import com.appro.illbeback.data.CallsDataSrouce;

import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.widget.RemoteViews;

public class CallsAppWidgetProvider extends AppWidgetProvider {

    private CallsDataSrouce dataSource;

    @SuppressWarnings("deprecation")
    @Override
    public void onUpdate(Context context, AppWidgetManager
            appWidgetManager,int[] appWidgetIds) {

        dataSource = new CallsDataSrouce(context);
        dataSource.open();

        for (int i = 0; i < appWidgetIds.length; i++) {
            Intent serviceIntent = new Intent(context, WidgetService.class);
            serviceIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetIds[i]);
            serviceIntent.setData(Uri.parse(serviceIntent.toUri(Intent.URI_INTENT_SCHEME)));

            // Which layout to show on widget
            RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget);

            // Setting the adapter for listview of the widget
            remoteViews.setRemoteAdapter(appWidgetIds[i], R.id.listViewWidget, serviceIntent);

            // Setting an empty view in case of no data
            remoteViews.setEmptyView(R.id.listViewWidget, R.id.empty_view);

            // Application Launcher
            Intent launchActivity = new Intent(context, Main.class);
            PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, launchActivity, 0);
            remoteViews.setOnClickPendingIntent(R.id.imageViewAppLauncher, pendingIntent);

            // Number of Calls Text  
            String numOfCallsText = dataSource.getNumberOfCalls() + " Calls";
            remoteViews.setTextViewText(R.id.textViewNunberOfCalls, numOfCallsText);

            appWidgetManager.updateAppWidget(appWidgetIds[i], remoteViews);
        }

        super.onUpdate(context, appWidgetManager, appWidgetIds);
    }
}

Here is the RemoteViewsService :

public class WidgetService extends RemoteViewsService {

    @Override
    public RemoteViewsFactory onGetViewFactory(Intent intent) {
        RemoteViewsFactory listProvidder = new CallsListRemoteViewsFactory(this.getApplicationContext(), intent);
        return listProvidder;
    }

}

Here is my RemoteViewFactory:

package com.appro.illbeback;

import java.util.List;
import com.appro.illbeback.R;
import com.appro.illbeback.data.CallItem;
import com.appro.illbeback.data.CallsDataSrouce;

import android.content.Context;
import android.content.Intent;
import android.widget.RemoteViews;
import android.widget.RemoteViewsService;

public class CallsListRemoteViewsFactory implements RemoteViewsService.RemoteViewsFactory {

    private CallsDataSrouce mDataSource;
    private List<CallItem> mCallsList;
    private Context mContext = null;

    public CallsListRemoteViewsFactory(Context context, Intent intent) {
        this.mContext = context;
    }

    @Override
    public int getCount() {
        return mCallsList.size();
    }

    @Override
    public long getItemId(int position) {
        return mCallsList.get(position).getId();
    }

    @Override
    public RemoteViews getViewAt(int position) {
        RemoteViews row = new RemoteViews(mContext.getPackageName(), R.layout.widget_list_row_layout);
        CallItem callItem = mCallsList.get(position);

        String contactID = callItem.getContactID();
        if (!contactID.equals(CallItem.CONTACT_ID_UNKOWN)) {
            row.setTextViewText(R.id.textViewWidgetContactName, callItem.getName());
        } else {
            row.setTextViewText(R.id.textViewWidgetContactName, callItem.getNumber());          
        }

        return row;
    }

    @Override
    public RemoteViews getLoadingView() {
        return null;
    }

    @Override
    public int getViewTypeCount() {
        return 0;
    }

    @Override
    public boolean hasStableIds() {
        return false;
    }

    @Override
    public void onCreate() {
        mDataSource = new CallsDataSrouce(mContext);
        mDataSource.open();
        mCallsList = mDataSource.findAllCalls();
    }

    @Override
    public void onDataSetChanged() {
        mCallsList = mDataSource.findAllCalls();
    }

    @Override
    public void onDestroy() {
    }
}
Frizz answered 7/3, 2014 at 23:43 Comment(1)
where does CallsDataSrouce came from? I'm having the save problem. :(Metronome
F
18

Found the solution!!! The problem was with my RemoteViewsService. The getViewTypeCount function returned '0' instead of '1'.

Explanation of getViewTypeCount

Frizz answered 16/4, 2014 at 23:29 Comment(1)
This was the answer for the same issue as described, Please mark as answerIncest
N
13

You could check if there are any views in your layout that are not supported by RemoteViews (http://developer.android.com/guide/topics/appwidgets/index.html#collections). I had the same issue because of a checkbox in my list item layout. After removing it, the list was shown correctly.

Nuisance answered 29/3, 2014 at 12:38 Comment(3)
Thanks... my app's widget contains only listView component, so I've double-checked and verified that it is supported in RemoteViews.Frizz
Hmm... Your code looks alright so far, but maybe you could provide your layout-files, too? If you say that there is only a listView in R.layout.widget, I don't know where you would set the text to R.id.textViewNunberOfCalls... And just to be sure, I guess it's a typo at the declaration of CallsDataSrouce, but you typed it this way everywhere you use it?Nuisance
@RonFerens And just seen another typo at R.id.textViewNunberOfCalls. Check there also if it's the ID you provided in your layout-file.Nuisance

© 2022 - 2024 — McMap. All rights reserved.