私は組み込みのアクションバーを使用しています。 私はデータを取得中にアニメーションローダーをアクションバーに表示し、そうでないときは「更新」アイコンを表示したいと思います。私が見つけた簡単な方法は、2つのメニュー項目を使用し、1つを表示するか、もう一方を非表示にしてから反対に表示することです。だからここに私のメニューです:アクションバーのアイテムを表示/非表示にするAndroid(3.0+)
<item android:id="@+id/menuItemRefresh"
android:title="Refresh"
android:showAsAction="always"
android:icon="@drawable/ic_menu_refresh"
android:visible="false" />
<item android:id="@+id/menuItemProgress"
android:actionLayout="@layout/progress"
android:showAsAction="always"
android:visible="true" />
私は私のメニューに不確定なプログレスバーの回転を作成する方法を見つけ出すていなかったので、私は(あなたが見ることができるように)actionLayoutを使用しています。ここでは、対応するactionLayoutです:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:id="@+id/layoutProgress" >
<ProgressBar
android:id="@+id/menuItemRefresh"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_marginLeft="13dp"
android:layout_marginRight="13dp" />
</LinearLayout>
マイアクティビティ:私は、アプリケーションを実行すると
public class MainActivity extends Activity implements OnItemClickListener
{
Handler handler;
MenuItem menuItemProgress;
MenuItem menuItemRefresh;
int currentPage;
List<CloudAppItem> items;
boolean currentlyLoading = false;
ListView listView;
FilesAdapter filesAdapter;
LinearLayout emptyView;
@Override
public void onCreate(Bundle savedInstanceState)
{
Log.i("MainActivity", "Started");
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
setHandler();
setListing();
loadItems();
}
@Override
protected void onResume()
{
super.onResume();
if (isFirstRun() && haveCredentialsChanged())
{
setFirstRun(false);
}
if (isFirstRun())
{
firstRun();
}
else if (haveCredentialsChanged())
{
setCredentialsChanged(false);
loadFiles(true, 0);
}
else
{
loadFiles(false, 0);
}
}
@Override
public Object onRetainNonConfigurationInstance()
{
return items;
}
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu, menu);
this.menuItemProgress = menu.findItem(R.id.menuItemProgress);
this.menuItemRefresh = menu.findItem(R.id.menuItemRefresh);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item)
{
switch (item.getItemId())
{
case R.id.menuItemPreferences:
startActivity(new Intent(MainActivity.this, PreferencesActivity.class));
break;
case R.id.menuItemRefresh:
loadFiles(true, 0);
break;
}
return false;
}
private boolean isFirstRun()
{
return Prefs.getPreferences(this).getBoolean(Prefs.FIRST_RUN, true);
}
private void firstRun()
{
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("First run");
builder.setCancelable(false);
builder.setPositiveButton("ok", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which)
{
startActivity(new Intent(MainActivity.this, PreferencesActivity.class));
}
});
AlertDialog alert = builder.create();
alert.show();
}
private void setFirstRun(boolean b)
{
Prefs.getPreferences(this).edit().putBoolean(Prefs.FIRST_RUN, b).commit();
}
private boolean haveCredentialsChanged()
{
return Prefs.getPreferences(this).getBoolean(Prefs.CREDENTIALS_CHANGED, false);
}
private void setCredentialsChanged(boolean b)
{
Prefs.getPreferences(this).edit().putBoolean(Prefs.CREDENTIALS_CHANGED, b).commit();
}
private void setListing()
{
listView = (ListView) findViewById(R.id.listView);
emptyView = (LinearLayout) findViewById(R.id.emptyView);
listView.setOnItemClickListener(this);
listView.setEmptyView(emptyView);
}
@SuppressWarnings("unchecked")
private void loadItems()
{
Object obj = getLastNonConfigurationInstance();
if (obj != null)
{
items = (List<CloudAppItem>) obj;
MainActivity.this.handler.sendEmptyMessage(0);
}
else
{
if (!isFirstRun())
loadFiles(true, 0);
}
}
private void showProgressIcon(boolean show)
{
if(this.menuItemProgress != null && this.menuItemRefresh != null)
{
if(show)
{
this.menuItemProgress.setVisible(true);
this.menuItemRefresh.setVisible(false);
}
else
{
this.menuItemRefresh.setVisible(true);
// PROBLEM : LINE TRIGGERING ERROR
this.menuItemProgress.setVisible(false);
}
}
}
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3)
{
if(this.items.get(arg2).isFake())
{
filesAdapter.lastItemLoading = true;
filesAdapter.notifyDataSetChanged();
int page = (int)(this.items.size()/Integer.valueOf(Prefs.getPreferences(this).getString(Prefs.FILES_PER_REQUEST, "20")))+1;
loadFiles(false, page);
}
else
{
startActivity(new Intent(this, FileInfosActivity.class));
}
}
/**
* @param reload : clean the list before loading new items
* @param page : if 0, items are prepended, else, items are appended
*/
private void loadFiles(final boolean reload, final int page)
{
if (!currentlyLoading)
{
currentlyLoading = true;
showProgressIcon(true);
new Thread(new Runnable() {
@Override
public void run()
{
// REQUESTING WEB SERVICE HERE
MainActivity.this.handler.sendEmptyMessage(0);
}
}).start();
}
}
private void setHandler()
{
this.handler = new Handler() {
@Override
public void handleMessage(Message msg)
{
currentlyLoading = false;
if (filesAdapter == null)
{
filesAdapter = new FilesAdapter(MainActivity.this, MainActivity.this.items);
listView.setAdapter(filesAdapter);
}
else
{
filesAdapter.refill(MainActivity.this.items);
}
// PROBLEM : LINE TRIGGERING ERROR
showProgressIcon(false);
}
};
}
}
すべてが罰金や作業です。 電話機を回転させると問題が発生します。
スタックトレース:
FATAL EXCEPTION: main
java.lang.RuntimeException: Unable to start activity
ComponentInfo{com.quanturium.androcloud/com.quanturium.androcloud.MainActivity}:
java.lang.ClassCastException: android.view.AbsSavedState$1 cannot be cast to
android.widget.ProgressBar$SavedState
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1955)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1980)
at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3347)
at android.app.ActivityThread.access$700(ActivityThread.java:122)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1150)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4340)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.ClassCastException: android.view.AbsSavedState$1 cannot be cast to
android.widget.ProgressBar$SavedState
at android.widget.ProgressBar.onRestoreInstanceState(ProgressBar.java:1093)
at android.view.View.dispatchRestoreInstanceState(View.java:9876)
at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:2330)
at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:2330)
at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:2330)
at android.view.View.restoreHierarchyState(View.java:9854)
at com.android.internal.policy.impl.PhoneWindow.restoreHierarchyState(PhoneWindow.java:1625)
at android.app.Activity.onRestoreInstanceState(Activity.java:906)
at android.app.Activity.performRestoreInstanceState(Activity.java:878)
at android.app.Instrumentation.callActivityOnRestoreInstanceState(Instrumentation.java:1100)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1933)
... 12 more
actionLayout(@ + ID/menuItemProgress)は、問題を引き起こすようです。リフレッシュアイテム(@ + id/menuItemRefresh)ですべてが問題ありません。私は問題がどこにあるのかコメントとして書いた。私が「問題:」という行をコメントアウトすると、ローテーションがうまく機能します。
次回は必要なコードのみを掲示してください。 – CSchulz
これは、同じメニュー項目で進捗状況や更新を処理するためのここでの素晴らしいアプローチです。ありがとう! – brk3
Android 2.2では、進行状況バーを非表示にすると、次に表示されるときにアニメーション化されません –