Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android widget with ListView doesn't load items correclty

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 - stackoverflow.com/questions/14121602/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() {
    }
}
like image 555
Ron Ferens Avatar asked Mar 07 '14 23:03

Ron Ferens


2 Answers

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.

like image 196
TheNothingMan Avatar answered Nov 16 '22 16:11

TheNothingMan


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

Explanation of getViewTypeCount

like image 28
Ron Ferens Avatar answered Nov 16 '22 17:11

Ron Ferens