2017-04-17 146 views
0

在更改控件內部的ListView數據時,有沒有辦法保留滾動位置?在更改ListView控件的佈局時保留滾動位置

我目前使用此代碼更新widget的數據:

提供者:

public class OtpListWidgetProvider extends AppWidgetProvider { 

    @Override 
    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { 
     super.onUpdate(context, appWidgetManager, appWidgetIds); 
     for (final int widgetId : appWidgetIds) { 
      final RemoteViews widget = getFirstWidget(context, widgetId); 
      appWidgetManager.updateAppWidget(widgetId, widget); 
     } 
    } 

    @Override 
    public void onReceive(final Context context, final Intent intent) { 
     super.onReceive(context, intent); 
     if (OtpListWidgetService.ACTION_SHOW_CODE.equals(intent.getAction())) { 
      int appWidgetId = intent.getIntExtra(
        AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID); 

      final int codePosition = intent.getIntExtra(OtpListWidgetService.EXTRA_CODE_POSITION, 0); 
      final Intent serviceIntent = new Intent(context, OtpListWidgetService.class) 
        .setAction(OtpListWidgetService.ACTION_SHOW_CODE) 
        .putExtra(OtpListWidgetService.EXTRA_CODE_POSITION, codePosition); 
      // Intent.filterEquals doesn't take into account the extras on an Intent, 
      // so we have to set its data. 
      serviceIntent.setData(Uri.parse(serviceIntent.toUri(Intent.URI_INTENT_SCHEME))); 

      Toast.makeText(context, 
        "Calling show with values codePosition=" + codePosition + " appWidgetId=" + appWidgetId, 
        Toast.LENGTH_SHORT).show(); 
      final RemoteViews widget = getWidgetWithAdapter(context, serviceIntent); 
      AppWidgetManager.getInstance(context).partiallyUpdateAppWidget(appWidgetId, widget); 
     } 
    } 

    private RemoteViews getFirstWidget(Context context, int widgetId) { 
     final Intent serviceIntent = new Intent(context, OtpListWidgetService.class); 
     final RemoteViews widget = getWidgetWithAdapter(context, serviceIntent); 
     widget.setEmptyView(R.id.list_widget, android.R.id.empty); 

     final Intent showCodeIntent = new Intent(context, OtpListWidgetProvider.class) 
       .setAction(OtpListWidgetService.ACTION_SHOW_CODE) 
       .putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, widgetId); 
     showCodeIntent.setData(Uri.parse(showCodeIntent.toUri(Intent.URI_INTENT_SCHEME))); 
     final PendingIntent showCodeIntentTemplate = 
       PendingIntent.getBroadcast(context, 0, showCodeIntent, PendingIntent.FLAG_UPDATE_CURRENT); 
     widget.setPendingIntentTemplate(R.id.list_widget, showCodeIntentTemplate); 
     return widget; 
    } 

    private RemoteViews getWidgetWithAdapter(Context context, Intent serviceIntent) { 
     final RemoteViews widget = new RemoteViews(context.getPackageName(), R.layout.list_widget); 
     widget.setRemoteAdapter(R.id.list_widget, serviceIntent); 
     return widget; 
    } 
} 

服務:

public class OtpListWidgetService extends RemoteViewsService { 
    public static final String ACTION_SHOW_CODE = "org.fedorahosted.freeotp.widget.ACTION_SHOW_CODE"; 
    public static final String EXTRA_CODE_POSITION = "EXTRA_CODE_POSITION"; 

    @Override 
    public RemoteViewsFactory onGetViewFactory(Intent intent) { 
     final OtpListWidgetViewsFactory factory = new OtpListWidgetViewsFactory(getApplicationContext()); 
     boolean shouldShowCode = ACTION_SHOW_CODE.equals(intent.getAction()); 
     if (shouldShowCode) { 
      int codePosition = intent.getIntExtra(EXTRA_CODE_POSITION, 0); 
      factory.setCodePositionToShow(codePosition); 
     } 
     return factory; 
    } 
} 

的RemoteViewFactory:

public class OtpListWidgetViewsFactory implements RemoteViewsService.RemoteViewsFactory { 

    private final Context context; 
    private final TokenPersistence persistence; 
    private int showCodePosition; 
    private boolean shouldShowCode; 

    public OtpListWidgetViewsFactory(final Context context) { 
     this.context = context; 
     persistence = new TokenPersistence(context); 
    } 

    @Override 
    public int getCount() { 
     return persistence.length(); 
    } 

    @Override 
    public RemoteViews getViewAt(int position) { 
     final Token token = persistence.get(position); 
     final RemoteViews row = new RemoteViews(context.getPackageName(), R.layout.widget_row); 

     try { 
      Bitmap b = Picasso.with(context).load(token.getImage()).get(); 
      if (b == null) { 
       row.setImageViewResource(R.id.widget_image, R.drawable.logo); 
      } else { 
       row.setImageViewBitmap(R.id.widget_image, b); 
      } 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 

     final String code; 
     if (shouldShowCode && showCodePosition == position) { 
      code = token.generateCodes().getCurrentCode(); 
     } else { 
      code = "------"; 
     } 
     row.setTextViewText(R.id.widget_code, code); 
     row.setTextViewText(R.id.widget_issuer, token.getIssuer()); 
     row.setTextViewText(R.id.widget_label, token.getLabel()); 

     final Intent intent = new Intent(); 
     intent.putExtra(OtpListWidgetService.EXTRA_CODE_POSITION, position); 
     row.setOnClickFillInIntent(R.id.widget_row_container, intent); 
     return row; 
    } 

    public void setCodePositionToShow(int codePosition) { 
     shouldShowCode = true; 
     showCodePosition = codePosition; 
    } 

    @Override 
    public long getItemId(int position) { 
     return position; 
    } 

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

    @Override 
    public void onCreate() { 
     // no-op 
    } 

    @Override 
    public void onDataSetChanged() { 
     // no-op 
    } 

    @Override 
    public void onDestroy() { 
     // no-op 
    } 

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

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

Wha牛逼現在正在發生的事情(它會頂端更新佈局之後,並保存滾動位置):

enter image description here

回答

0

而不是調用一個新Service更新ListView的佈局,你應該打個電話給

appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetId, R.id.list_widget); 

WidgetProvider,並傳遞數據到你RemoteViewsFactory通過共享的對象或字段。