2012-04-11 4 views
0

(Извините за мои ошибки в правописании)Сочетание услуг, ProgressBar, Gridview (и его notifydatasetchanged) QuickAction-реализация идет не так

У меня есть проблема в комбинации некоторых вещей:

Я использую GridView для загрузки содержимого шоу из базы данных. onClick загружается файл, который можно просмотреть позже. Его около 20 МБ. Эта загрузка выполняется службой.

Каждый элемент в gridView содержит индикатор прогресса в макете. этот индикатор прогресса отображается только в том случае, если элемент загружается в фоновом режиме через службу.

Служба отправляет широковещательную рассылку о загрузке Progress, Intent содержит идентификатор элемента, чтобы найти его в данных адаптера для gridview.

BroadcastReceiver IST зарегистрирован в моей деятельности, чтобы получить обновление Progress (помните, одновременные загрузки возможны), которая вызывает функцию «setProgress» в GridView-адаптер

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(); 
     } 
    }   
} 

С этой точки все отлично работает.

Дополнительно im с использованием реализации QuickAction из http: // www. londatiga.net/it/how-to-create-quickaction-dialog-in-android/ (Пространства, потому что я не могу опубликовать более двух гиперссылок)

Теперь возникает проблема:

Иногда, я думаю, когда notifydatasetchanged вызывается и пользователь нажимает на элемент, quickaction отображается в неправильном положении.

Чтобы сделать это более ясным здесь две фотографии:

Первое это то, что должно произойти (в данном случае щелчок по первому элементу 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); 
} 

Может быть, у кого-то есть какие-то идеи или подсказки для меня, как я могу справиться с этой проблемой! Спасибо за миллион!

ответ

0

Я нашел решение для своей проблемы.

Решение состоит в том, что я реализую свой собственный ProgressBar, который теперь содержит BroadcastListerner и устанавливает прогресс для каждого элемента. Поэтому я могу изменить значение без необходимости называть «notifydatasetchanged». идеально подходит для моих нужд. Im все еще не удивляется, если это хорошее решение, но оно работает хорошо.

Вот код для ProgressBar:

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. В адаптере i я устанавливаю идентификатор моего содержимого, чтобы предоставить получателю данные только для того, чтобы установитьпрогресс, если он содержит правильный контент.

В конце концов, моя проблема решена, прогресс обновляется без необходимости вызова notifydatasetchanged. Да!

+0

Hello Mate, у меня есть несколько схожие требования. Можете ли вы указать, откуда я должен транслировать, чтобы я мог использовать его в своем классе customProgressbar. Я использую сервис для загрузки данных .... И мне нужно показать его статус так же, как и ваше требование. Пожалуйста, помогите ... –

+0

Привет, пожалуйста, помогите мне с моим предыдущим комментарием ... Как я могу установить идентификатор бумаги каждого штриха? с трудным временем выяснения ... –