我正在使用内置的操作栏。我想在获取数据时在操作栏中显示一个动画加载器,并在不显示时显示一个“刷新”图标。我发现的简单方法是使用 2 个菜单项并显示一个/隐藏另一个,然后反之。所以这是我的菜单:
<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 )一切正常。我写了问题所在的评论。当我注释掉“问题:”行时,旋转效果很好。