Виджеты Android ListView иногда не реагируют на клики

Я реализую виджет с RemoteViewsService, содержащим ListView элементов, где все элементы доступны для запуска службы. Короче говоря, я использую setPendingIntentTemplate в своем AppWidgetProvider.onUpdate() и setOnClickFillInIntent в своем RemoteViewsService.RemoteViewsFactory().

И в большинстве случаев я получаю ожидаемое поведение. Однако при использовании некоторой памяти и возвращении к попытке снова щелкнуть элемент в списке иногда ничего не происходит при нажатии элементов в списке: служба не запускается, и сенсорная обратная связь не предоставляется. Если у меня есть несколько виджетов, в одном из списков может быть проблема, а в других - нет.

кто-нибудь знает, как решить эту проблему?

Некоторые другие тесты показали, что:

  • Если я некоторое время прокручиваю список с проблемой, а затем пытаюсь щелкнуть снова, это работает! Моя первая мысль заключалась в том, что причина была в том, что был вызван RemoteViewsFactory.getView, и таким образом было обновлено ожидающее намерение, но, проверив журналы, я вижу, что этот метод не введен.
  • Я также зарегистрировал RemoteViewsService.RemoteViewsFactory.onDestroy, чтобы узнать, была ли причина проблемы в том, что это было удалено, но это было не так.
  • Если мне удастся вызвать AppWidgetManager.updateAppWidget (чтобы AppWidgetProvider.onUpdate запустился), проблема исчезнет (я вызываю updateAppWidget из своего основного приложения).

Эти три наблюдения указывают на то, что проблема связана с AppWidgetManager, а не с RemoteViewsFactory.

AppWidgetProvider.onUpdate:

@Override
public void onUpdate(Context iContext, AppWidgetManager iWidgetMgr,
        int[] iWidgetIds){
    Log.d(DbgU.getAppTag(), DbgU.getMethodName());

    //Going through all widgets placed (could be more than one)
    for(int i = 0; i < iWidgetIds.length; i++){
        //Setting up the remote view service
        Intent tmpRVServiceIntent = new Intent(iContext,
                RemoteViewsServiceC.class);
        tmpRVServiceIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,
                iWidgetIds[i]);
        tmpRVServiceIntent.setData(Uri.parse(tmpRVServiceIntent.toUri(
                Intent.URI_INTENT_SCHEME)));

        //Setting up the remote views
        RemoteViews tmpRemoteViews = new RemoteViews(iContext.getPackageName(),
                R.layout.widget);
        tmpRemoteViews.setRemoteAdapter(R.id.widget_listview,
                tmpRVServiceIntent);
        tmpRemoteViews.setEmptyView(R.id.widget_listview,
                R.id.widget_empty_view);

        //Setting up the pending intent template (the id will be filled
        //in later in RemoteViewsFactoryC.getViewAt())
        Intent tmpTemplateIntent = new Intent(iContext,
                LauncherServiceC.class);

        tmpTemplateIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,
                iWidgetIds[i]);
        PendingIntent tmpPendingIntent = PendingIntent.getService(iContext,
                0, tmpTemplateIntent, PendingIntent.FLAG_UPDATE_CURRENT);
        tmpRemoteViews.setPendingIntentTemplate(R.id.widget_listview,
                tmpPendingIntent);

        //Applying the update for the views
        iWidgetMgr.updateAppWidget(iWidgetIds[i], tmpRemoteViews);
    }
}

RemoteViewsService.RemoteViewsFactory.getViewAt:

@Override
public RemoteViews getViewAt(int inPosition) {
    Log.v(DbgU.getAppTag(), DbgU.getMethodName()
            + ", inPosition = " + inPosition);

    //Moving the cursor to the current position
    mItemCursor.moveToPosition(inPosition);

    //Extracting values from the database
    String tmpName = mItemCursor.getString(
            mItemCursor.getColumnIndexOrThrow(ItemTableM.COLUMN_NAME));
    long tmpItemId = mItemCursor.getLong(
            mItemCursor.getColumnIndexOrThrow(ItemTableM.COLUMN_ID));
    Uri tmpItemUri = DatabaseU.getItemUriFromId(tmpItemId);

    //Setting up the remote views object
    RemoteViews retRemoteViews = new RemoteViews(
            mContext.getPackageName(), R.layout.widget_listitem);
    retRemoteViews.setTextViewText(R.id.widget_listitem_textView, tmpName);

    //Adding action URI to the intent template which was set for all the
    //list rows in WidgetProviderC.onUpdate
    Intent tmpFillInIntent = new Intent();
    tmpFillInIntent.setData(tmpItemUri);
    retRemoteViews.setOnClickFillInIntent(R.id.widget_listitem_textView,
            tmpFillInIntent);

    return retRemoteViews;
}

У меня была эта проблема в течение долгого времени, и я очень благодарен за любую помощь


person sunyata    schedule 18.03.2014    source источник


Ответы (1)


У меня тоже давно такая же проблема.

На устройствах Sony с Android 4.0, если провести пальцем на другую домашнюю панель, а затем вернуться к той, где находится виджет, элементы списка виджетов не будут активны. Sony Android 4.1 и более поздние версии не имеют этой проблемы, но иногда они отображают неправильный элемент списка. На некоторых устройствах Samsung с Android 4.1 я видел ту же проблему. На домашнем экране эмулятора Android 4.0 этой проблемы нет.

Я пытался исправить это разными способами, в том числе и таким образом: after-setting-descendantfocusabilit"> stackoverflow.com/questions/21891008/a-textview-in-a-listview-s-row-cannot-click-after-setting-descendantfocusabilit

Однако я не смог решить проблему, которая заставила меня поверить, что это проблема домашнего экрана. Чтобы убедиться в этом, я решил установить «Go Launcher» на устройство Sony Android 4.0, и там все работает как надо!

Ответ: Это проблема домашнего экрана, которую, скорее всего, невозможно решить без использования какого-либо хака. Пожалуйста, скажи мне, что я ошибаюсь.

person user3500940    schedule 14.04.2014
comment
Спасибо за эту информацию, у меня есть Sony Xperia с ICS, поэтому, как вы говорите, причина должна быть в проблеме с домашним экраном. - person sunyata; 16.04.2014