2013-04-10 4 views
6

私はこの問題を長い時間前に気づいたことがありますが、今は私が明らかにそれを再現するデモを準備できました。問題は、2.1エミュレータと私のICS 4.0.3デバイスでのプレゼンテーションです。破損したアクションバーの外観

私はAsyncTaskを持っています。これは、アクションバーの不確定な進捗状況を表示し、invalidateOptionsMenuを呼び出すことによってメニューを再初期化できます。これにより、更新アイコンが非表示になります。これは、私がlistViewデータモデルを変更し、アダプタでnotifyDataSetChangedを呼び出すまでは正常に動作しています。そのようなアクションの後、Actionbarは壊れたビューを持つかもしれません。

予想ビュー: image

ブロークン・ビュー(最後の項目は永遠に消えるか、空白はいくつかのケースでのinstedを追加): image image

原因コードはonPostExecute

@Override 
     protected void onPostExecute(Void result) 
     { 
      super.onPostExecute(result); 
      for (int i = 0; i < 10; i++) 
      { 
       adapter.items.add(i); 
      } 
      adapter.notifyDataSetChanged(); 
      activity.stopLoading(); 
     } 
... 
    void stopLoading() 
    { 
     if (loaders.decrementAndGet() == 0) 
     { 
      setSupportProgressBarIndeterminateVisibility(false); 
      invalidateOptionsMenu(); 
     } 
    } 
です

これはなぜ起こっているのでしょうか。ほとんどの場合、リストビューアダプタ(oおそらくいくつかのビューの更新)?もし私が行を削除するadapter.notifyDataSetChanged();デモでアクションバーが壊れることはありません。また、別の理由で(正確にすべての問題の原因を特定することはできません)ので、しかし、実際のアプリケーションでは、それが壊れている可能性があり、問題を実証

プロジェクト:http://goo.gl/ZbMTU

オープンActionBarSherlock問題:https://github.com/JakeWharton/ActionBarSherlock/issues/887

UPD: をこの問題を掘り起こしてください。回避策が存在する)(正確にadapter.notifyDataSetChangedないようだ

を無効表情を引き起こしますが、データセットのために待機しているAdapterView.AdapterDataSetObserverによってrequestLayoutコールがリストビューでイベントを変更し、私は中invalidateOptionsMenuとsetSupportProgressBarIndeterminateVisibilityを呼び出すことができますhandler.post。しかし、それは、遅延handler.postでfragment.setHasOptionsMenuを呼び出すFragmentPagerAdapterのカスタム実装さえ使用することを余儀なくされます。

私が望むのは、ビューとアクションバーを無効にすることなく無効化する最も効率的な方法を見つけることです。あなたはdoInBackgroundでこれをしなかった理由を私は理解していない

+0

あなたはsupportIvalidateOptionsMenu()ではないInvalidateOptionsMenu() – Greensy

+0

私はどこにでもそれを制御することはできませんのようなそれは、本当の原因ではありません呼び出す必要があります。たとえば、Fragment.setMenuVisibleの – httpdispatch

答えて

0

のThread.sleep(randomSleep)。

しかし、 "LoadingTask"クラスでは、問題が解決されることを "doInBackground"の行にコメントします。

は、以下を参照してください。

 @Override 
     protected Void doInBackground(Void... params) 
     { 
//   int randomSleep = (int) (Math.random() * 1000); 
//   try 
//   { 
//    Thread.sleep(randomSleep); 
//   } catch (InterruptedException e) 
//   { 
//    // TODO Auto-generated catch block 
//    e.printStackTrace(); 
//   } 
      return null; 
     } 
+0

では、doInBackgroundは実際の作業のシミュレーション用です。通常、それは時間がかかるネットワーク関連の操作です。 – httpdispatch

関連する問題