0

(对不起我的拼写错误)

我在组合一些事情时遇到了问题:

我使用 GridView 从数据库下载节目内容。onClick 文件被下载,以后可以查看。它大约 20MB。此下载由服务完成。

gridView 中的每个项目在布局中都包含一个进度条。如果项目正在通过服务在后台下载,则仅显示此进度条。

Service 发送关于下载进度的广播,Intent 包含项目的 ID,以便在 gridview 的 Adapter 的数据中找到它。

在我的 Activity 中注册了 BroadcastReceiver 以获取进度更新(请记住,可以同时下载),它在 gridview-adapter 中调用函数“setProgress”

public void setProgress(long id, int progress)
{
   for (int i = 0;i < list.size();i++)
   {
      if (list.get(i).getId() == id)
      {
          list.get(i).setProgress(progress);
          notifyDataSetChanged();
      }
   }        
}

至此,一切正常。

此外,我使用来自 http://www 的 QuickAction 实现。londatiga.net/it/how-to-create-quickaction-dialog-in-android/(空格,因为我不能发布两个以上的超链接)

现在问题来了:

有时,我猜当 notifydatasetchanged 被调用并且用户点击一个项目时,快速操作显示在错误的位置。

为了更清楚,这里有两张图片:

第一个是应该发生的事情(在这种情况下,单击 gridview 的第一项) http://dl.dropbox.com/u/9031500/expected.png

第二张图片显示了有时会发生什么(仅当某些下载正在运行时,这就是为什么我猜它是因为“notifydatasetchanged”和视图的重建)。这也是对第一项的点击,不幸的是,快速操作显示在第四项: http ://dl.dropbox.com/u/9031500/wrong.png

这是我在呼吁快速行动的活动中的实现:

@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
    showQuickAction(view, position);
}

@Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
    showQuickAction(view, position);
    return true;
}


private void showQuickAction(View view, int position)
{
    RelativeLayout facsimile = (RelativeLayout) view.findViewById(R.id.lib_item_image_layout);
    Log.i(LOGTAG, "Position:"+position);
    currentPaper = TZReader.paperDao.load(libraryAdapter.getItemId(position));
    Log.i(LOGTAG,"Set CurrentPaper:"+currentPaper.getTitelWithDate());

    ActionItem downloadItem = new ActionItem(ACTION_ITEM_DOWNLOAD, "Download", getResources().getDrawable(R.drawable.ic_action_download));
    ActionItem readItem = new ActionItem(ACTION_ITEM_READ, "Lesen", getResources().getDrawable(R.drawable.ic_action_read));
    ActionItem deleteItem = new ActionItem(ACTION_ITEM_DELETE, "Löschen", getResources().getDrawable(R.drawable.ic_action_delete));
    ActionItem cancelItem = new ActionItem(ACTION_ITEM_CANCEL, "Abbrechen", getResources().getDrawable(R.drawable.ic_action_cancel));

    QuickAction mQuickAction = new QuickAction(this, QuickAction.HORIZONTAL);

    switch (currentPaper.getState())
    {
    case Paper.DOWNLOADED_READABLE:
        mQuickAction.addActionItem(readItem);
        mQuickAction.addActionItem(deleteItem);         
        break;
    case Paper.DOWNLOADED_BUT_UPDATE:
        mQuickAction.addActionItem(downloadItem);
        mQuickAction.addActionItem(deleteItem);
        break;
    case Paper.IS_DOWNLOADING:
        mQuickAction.addActionItem(cancelItem);
        break;
    case Paper.NOT_DOWNLOADED:
        mQuickAction.addActionItem(downloadItem);
        break;  
    }


    //Set listener for action item clicked
    mQuickAction.setOnActionItemClickListener(new QuickAction.OnActionItemClickListener() {         
        @Override
        public void onItemClick(QuickAction source, int pos, int actionId) {                        
            //here we can filter which action item was clicked with pos or actionId parameter
            switch(actionId)
            {
            case ACTION_ITEM_DOWNLOAD:
                Intent downloadIntent = new Intent(getApplicationContext(), DownloadService.class);
                downloadIntent.putExtra(DownloadService.PARAMETER_PAPER_DB_ID_LONG, currentPaper.getId());
                startService(downloadIntent);
                break;
            case ACTION_ITEM_READ:

                break;
            case ACTION_ITEM_DELETE:
                DeleteAlertDialogFragment newFragment = DeleteAlertDialogFragment.newInstance(currentPaper.getId());
                newFragment.setStyle(SherlockDialogFragment.STYLE_NO_TITLE,0);
                newFragment.show(getSupportFragmentManager(), "dialog");
                break;
            case ACTION_ITEM_CANCEL:
                break;                  
            }
        }
    });     



    mQuickAction.show(facsimile);   
}

也许有人对我有任何想法或提示我如何处理这个问题!提前一百万谢谢!

4

1 回答 1

0

我找到了解决我的问题的方法。

解决方案是我实现自己的 ProgressBar,它现在包含一个 BroadcastListerner 并设置每个项目的进度。所以我可以更改值而无需调用“notifydatasetchanged”。非常适合我的需要。我仍然不确定这是否是一个好的解决方案,但它运作良好。

这是进度条的代码:

public class ListeningProgressBar extends ProgressBar {

public ListeningProgressBar(Context context, AttributeSet attrs) {
    super(context, attrs);
}


final IntentFilter intentDownloadProgressFilter = new IntentFilter(DownloadService.DOWNLOAD_PROGRESS_BROADCAST);
private long paperId = 0;
private boolean isReceiverRegistered = false;

@Override
protected void onAttachedToWindow() {

    getContext().getApplicationContext().registerReceiver(downloadProgressBroadcastReceiver,intentDownloadProgressFilter);
    isReceiverRegistered = true;

    super.onAttachedToWindow();
}

@Override
protected void onDetachedFromWindow() {
    if (isReceiverRegistered)
    {
        getContext().getApplicationContext().unregisterReceiver(downloadProgressBroadcastReceiver);
        isReceiverRegistered = false;
    }
    super.onDetachedFromWindow();
}

private BroadcastReceiver downloadProgressBroadcastReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        long id = intent.getLongExtra(DownloadService.PARAMETER_PAPER_DB_ID_LONG, -1);
        int progressValue = intent.getIntExtra(DownloadService.PARAMETER_PAPER_PROGRESS_INT, 0);
        if (paperId == id)
        {
            setProgress(progressValue);
        }
    }
};

public long getPaperId() {
    return paperId;
}

public void setPaperId(long paperId) {
    this.paperId = paperId;
}

}

我只是将它用作我的 XML 布局中的普通自定义视图。在适配器中,我设置了我的内容的 id,以便为接收者提供数据,如果它是正确的内容,则只是为了设置进度。

最后,我的问题解决了,进度更新了,不需要调用notifydatasetchanged。是的!

于 2012-04-12T13:40:45.910 回答