在操作栏中显示/隐藏项目 Android (3.0+)
我正在使用内置操作栏。 我想在获取数据时在操作栏中显示一个动画加载程序,并在不获取数据时显示“刷新”图标。我发现的简单方法是使用 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) 一切正常。我在问题所在的地方写了评论。当我注释掉“问题:”行时,轮换效果很好。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
Android 似乎无法恢复视图的保存状态。
发生这种情况是因为您有两个具有相同 ID 的视图。由于它们不属于同一类,因此转换失败并崩溃。
这
是你的问题。
Android doesn't seem to be able to restore your view's saved state.
This happens because you have two views with the same ID. Since they are not of the same class, the cast fails and crashes.
and
This is your problem.
我遇到了同样的问题,并通过将以下内容添加到 AndroidManifest.xml 中的活动声明中来解决它:
此页面引导我找到了解决方案。希望这有帮助。
I had the same problem and solved it by adding the following to my activity declaration in
AndroidManifest.xml
:This page led me to the solution. Hope this helps.