2013-08-09 4 views
1

Я знаю, что есть тонны ответов на SO для этого, но я не могу заставить его работать так, как хотелось бы. У меня есть SherlockFragment, содержащий ListView, который заполнен некоторыми данными, извлекаемыми из файла. Я добавил кнопку обновления в Fragment, идея состоит в том, что при нажатии на нее она извлекает любые изменения в файле и при необходимости добавляет их в представление. Я также добавил популярную библиотеку PullToRefresh.Обновить ListView в Фрагменте после перезагрузки данных

К сожалению, при перезагрузке фрагмента (например, при вращении устройства) ничего не меняется. Я вижу новые данные. Я читал о notifyDataSetChanged(), но он не работает для меня. Единственное, что я получил работая звонит mPager.notifyDataSetChanged() от моего основного класса FragmentActivity и имеющий следующий набор в моем ViewPager адаптер:

@Override 
public int getItemPosition(Object object) { 
    return POSITION_NONE; 
} 

Это совершающего то, что я хочу, но это не очень гладкий об этом, и вы можете видеть, как это заставляет перезарядить. В настоящее время я использую PullToRefresh, и он резко отключает его от страницы, и, откровенно говоря, он просто выглядит плохо. Если честно, мне нужно позвонить onCreateView моего фрагмента из моей AsyncTask, перезагружая данные.

При необходимости я отправлю код, их просто много, поэтому я не хочу публиковать ничего лишнего.

О, и, пожалуйста, обратите внимание, что я пробовал notifyDataSetChanged() в onPostExecute() моей задачи.

Спасибо за любые рекомендации.

+1

может быть, вы могли бы использовать 'Observer Pattern', где ваш фрагмент является слушателем и субъект является вашим AsyncTask, почти так же, как вы это сделали, но более изящным способом, и, может быть, просто, может быть, вы не увидите перезагрузку принуждения (я не уверен в этом). – JosephChilberry

+0

@JosephChilberry Это довольно неприятная проблема, я нашел решение менее заметным (см. Ниже через минуту), но он все еще не идеален. – whitfin

ответ

1

Я нашел способ обойти это, но это не идеально, поэтому я не буду принимать это, если произойдет что-то лучшее.

Потому что после возвращения в мой фрагмент onResume() называется (этот ответ также довольно специфичен для моего проекта), я сделал следующее:

@Override 
public void onResume(){ 
    super.onResume(); 
    // Make the adapter again 
    adapter = new FeedListAdapter(this, feed); 
    // Set it to the list again 
    list.setAdapter(adapter); 
} 

Это обновит список (плохо) и все еще довольно заметно , хотя, если я использую кнопку вместо PullToRefresh, это не так.

Мое решение (как бы оно ни плохо) вместе с PullToRefresh заключается в том, чтобы вставить его в обработчик с задержкой триггера, чтобы разрезанная секция «Обновить» исчезла до ее запуска.

@Override 
public void onResume(){ 
    super.onResume(); 
    new Handler().postDelayed(new Runnable() { 
     public void run() { 
      adapter = new FeedListAdapter(this, feed); 
      list.setAdapter(adapter); 
     } 
    }, 500); 
} 

Опять же, это довольно специфический для моего проекта и очень странным образом делать это, так что любой «идеальный» ответ, пожалуйста, поделитесь :)

EDIT: Был еще вопрос с ним будучи немного нервным с PullToRefresh, поэтому мое решение было ждать в новом потоке, пока PullToRefresh скрыта снова, а затем восстановить список (это грязно, но это работает так, что угодно):

@Override 
public void onResume(){ 
    super.onResume(); 
    // Start a new thread 
    new Thread(new Runnable() { 
     @Override 
     public void run() { 
      try { 
       // Wait until the PullToRefresh is hidden 
       synchronized(this){ 
        wait(190); 
       } 
      } catch(InterruptedException ex) { } 
      // Post a new runnable 
      threadHandler.post(new Runnable(){ 
       public void run(){ 
         // Recreate the adapter from the new feed 
         adapter = new FeedListAdapter(FeedListActivity.this, feed); 
         // Set the recreated adapter 
         list.setAdapter(adapter); 
        } 
       }); 
      } 
     }).start(); 
    } 
} 

EDIT 2:

Только что заметил, что я пропустил что-то очевидное. Я только что изменил свой list.onRefreshComplete(); для представления PullToRefresh до моего onResume(), и за ним позаботилась нервозность.Тем не менее, я думаю, что выше решение является более впечатляющим: р

Так что мой код:

@Override 
public void onResume(){ 
    super.onResume(); 
    // Recreate the adapter from the new feed 
    adapter = new FeedListAdapter(this, feed); 
    // Set the recreated adapter 
    list.setAdapter(adapter); 
    // The list has finished refreshing 
    list.onRefreshComplete(); 
} 
+1

это нормально, если он работает, но я бы предпочел «шаблон наблюдателя» над «обработчиком», если вам нужен пример подхода, который я прокомментировал здесь, это: http://stackoverflow.com/questions/17350950/loading-listener- screen-while-data-downloads-from-server/17353548 # 17353548 дайте мне знать, если вам нужен более «конкретный» пример. – JosephChilberry

+0

@JosephChilberry Спасибо за пример, я пробую этот метод сейчас – whitfin

+0

, пожалуйста, дайте мне знать, если это вам поможет. – JosephChilberry

Смежные вопросы