我正在使用ActionBarSherlock和ViewPagerIndicator将片段显示为标签。其中一个片段将项添加到ActionBar:
private String[] mapNames;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
// init an String array `mapNames` which is used when populating submenu
// ...
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.fragment_maps, menu);
SubMenu mapNamesMenu = menu.findItem(R.id.map_names).getSubMenu();
mapNamesMenu.clear();
for (int i=0; i<mapNames.length; i++) {
mapNamesMenu.add(1, i, Menu.NONE, mapNames[i]);
}
super.onCreateOptionsMenu(menu, inflater);
}
并在res/menu/fragment_maps.xml
我有
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/map_names"
android:title="Maps"
android:icon="@drawable/maps_32"
android:showAsAction="always|withText">
<menu>
<item android:id="@+id/placeholder_maps" />
</menu>
</item>
</menu>
在旋转手机之前,一切正常。方向更改后,此菜单变得不可访问(单击图标时没有任何反应)。然后,如果我再次旋转手机,我会收到此错误:
FATAL EXCEPTION: main
android.view.WindowManager$BadTokenException: Unable to add window -- token null is not valid; is your activity running?
at android.view.ViewRoot.setView(ViewRoot.java:532)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:177)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91)
at android.view.Window$LocalWindowManager.addView(Window.java:424)
at android.widget.PopupWindow.invokePopup(PopupWindow.java:912)
at android.widget.PopupWindow.showAsDropDown(PopupWindow.java:824)
at com.actionbarsherlock.internal.widget.IcsListPopupWindow.show(IcsListPopupWindow.java:226)
at com.actionbarsherlock.internal.view.menu.MenuPopupHelper.tryShow(MenuPopupHelper.java:129)
at com.actionbarsherlock.internal.view.menu.MenuPopupHelper.show(MenuPopupHelper.java:102)
at com.actionbarsherlock.internal.view.menu.ActionMenuPresenter.onSubMenuSelected(ActionMenuPresenter.java:273)
at com.actionbarsherlock.internal.view.menu.MenuBuilder.dispatchSubMenuSelected(MenuBuilder.java:263)
at com.actionbarsherlock.internal.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:892)
at com.actionbarsherlock.internal.view.menu.ActionMenuView.invokeItem(ActionMenuView.java:510)
at com.actionbarsherlock.internal.view.menu.ActionMenuItemView.onClick(ActionMenuItemView.java:145)
at android.view.View.performClick(View.java:2494)
at android.view.View$PerformClick.run(View.java:9122)
at android.os.Handler.handleCallback(Handler.java:587)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:130)
at android.app.ActivityThread.main(ActivityThread.java:3806)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
at dalvik.system.NativeStart.main(Native Method)
任何想法如何解决?我正在使用Android 2.3.6
修改:请参阅test repository
答案 0 :(得分:3)
我认为,这是一个上下文问题。这就是BadTokenException
正在发生的原因。
此例外背后有很多可能性:
1)您可能正在使用“this
”作为实际需要YourActivity.this
或父活动上下文的某个地方的上下文引用。
或强>
2)从我猜测的log-cat
开始,您正试图显示Pop-up
窗口。
问题可能是,您过早显示弹出窗口(即在Activity
生命周期完成之前)。
所以等到活动生命周期结束。
要推迟显示弹出窗口,您可以参考此link。
简而言之,这个问题是由以下用例引起的:
活动的引用被传递给某个组件(例如
Toast
,alert dialog
,pop-up
等),活动已被销毁但是 该组件仍然存在或试图使用被破坏的活动 上下文。
所以要确保没有这样的情况。
希望你能给你一些解决问题的暗示。
答案 1 :(得分:2)
这是您的主要活动:
public class BaseSampleActivity extends SherlockFragmentActivity {
TestFragmentAdapter mAdapter;
ViewPager mPager;
PageIndicator mIndicator;
protected ListFragment mFrag;
@Override
public void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.themed_titles);
//This adapter can load as many fragment as you want with different content, see later
mAdapter = new TestFragmentAdapter(getSupportFragmentManager());
mPager = (ViewPager)findViewById(R.id.pager);
mPager.setAdapter(mAdapter);
mPager.setCurrentItem(1);
mIndicator = (TitlePageIndicator)findViewById(R.id.indicator);
mIndicator.setViewPager(mPager);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
//This show how to set up a Searhbar
SearchView searchView = new SearchView(getSupportActionBar().getThemedContext());
searchView.setQueryHint("Procure pelo nome");
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
// TODO Auto-generated method stub
// Intent search = new Intent(getApplicationContext(), SearchableActivity.class);
// search.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
// search.putExtra("query", query);
// startActivity(search);
return true;
}
@Override
public boolean onQueryTextChange(String newText) {
// TODO Auto-generated method stub
return false;
}
});
menu.add("Search")
.setIcon(R.drawable.ic_search_inverse)
.setActionView(searchView)
.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM | MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW);
//This is how to set up a SubMenu
SubMenu subMenu1 = menu.addSubMenu("Action Item");
subMenu1.add(0, 1, 0, "Sample");
subMenu1.add(0, 2, 0, "Menu");
subMenu1.add(0, 3, 0, "Sair");
MenuItem subMenu1Item = subMenu1.getItem();
subMenu1Item.setIcon(R.drawable.ic_title_share_default);
subMenu1Item.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_ACTION_WITH_TEXT);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
//This is a switch case to do when the SubMenu is clicked.
case 1:
Toast.makeText(BaseSampleActivity.this, "Now "+item.getItemId(), Toast.LENGTH_SHORT).show();
return true;
case 2:
Toast.makeText(BaseSampleActivity.this, "Now = "+item.getItemId(), Toast.LENGTH_SHORT).show();
return true;
case 3:
Toast.makeText(BaseSampleActivity.this, "Now = "+item.getItemId(), Toast.LENGTH_SHORT).show();
return true;
}
return super.onOptionsItemSelected(item);
}
}
这是你的FragmentPagerAdapter:
class TestFragmentAdapter extends FragmentPagerAdapter implements IconPagerAdapter {
//Here you set up the title of each fragment, its in portuguese.
protected static final String[] CONTENT = new String[] { "CATEGORIAS", "PRINCIPAL", "AS MELHORES", };
protected static final int[] ICONS = new int[] {
R.drawable.perm_group_calendar,
R.drawable.perm_group_camera,
R.drawable.perm_group_device_alarms,
};
private int mCount = CONTENT.length;
public TestFragmentAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {Fragment f = null;
switch(position){
case 0:
{
//Here you can set up a lot of diferent fragment content, here I just created a simple //arraylistfragment
f = new ArrayListFragment();
// set arguments here, if required
Bundle args = new Bundle();
args.putInt(ArrayListFragment.ARG_position, position);
f.setArguments(args);
break;
}
case 1:
{
f = new ArrayListFragment();
// set arguments here, if required
Bundle args = new Bundle();
f.setArguments(args);
break;
}
case 2:
{
f = new ArrayListFragment();
// set arguments here, if required
Bundle args = new Bundle();
f.setArguments(args);
break;
}
default:
throw new IllegalArgumentException("not this many fragments: " + position);
}
return f;
}
@Override
public int getCount() {
return mCount;
}
@Override
public CharSequence getPageTitle(int position) {
return TestFragmentAdapter.CONTENT[position % CONTENT.length];
}
@Override
public int getIconResId(int index) {
return ICONS[index % ICONS.length];
}
public void setCount(int count) {
if (count > 0 && count <= 10) {
mCount = count;
notifyDataSetChanged();
}
}
}
我刚刚做了一个简单的示例,您可以轻松了解如何实现ActionBarSherlock和ViewPagerIndicator。
我想把它上传到github,但是需要一段时间才能理解如何去做,也许你可以稍后教我。
然后我在4shared上传这个。 http://www.4shared.com/rar/zOWrvmyu/ViewpagerandSherlock.html
如果您有任何疑问,请稍后再问我。
答案 2 :(得分:1)
这对我有用,但我不知道是否有一些副作用。
将此添加到Fragment的onCreate
setRetainInstance(true);
这是AndroidManifest.xml到包含Fragment的Activity
android:configChanges="orientation"