7

ActionBarSherlockViewPagerIndicatorを使用して、フラグメントをタブとして表示しています。それらの Fragments の 1 つが 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 を使用しています

編集:テストリポジトリを参照

4

3 に答える 3

3

これはコンテキストの問題だと思います。発生しているのはそのためBadTokenExceptionです。

この例外の背後には多くの可能性があります。

1)this実際に必要な場所YourActivity.thisまたは親アクティビティのコンテキストでコンテキスト参照として " " を使用している可能性があります。

また

2)log-cat私が推測していることから、Pop-upウィンドウを表示しようとしています。

問題は、ポップアップ ウィンドウの表示が早すぎる(つまり、Activityライフ サイクルが完了する前) ことです。そのため、アクティビティのライフ サイクルが完了するまで待ちます。

ポップアップの表示を延期するには、このリンクを参照してください。

要するに、この問題は以下のユースケースによるものです。

Toastアクティビティの参照が一部のコンポーネント ( 、など) に渡され、アクティビティが破棄されましたが、そのコンポーネントはまだ生きているか、破棄されたアクティビティのコンテキストを使用しようとしていalert dialogます。 pop-up

ですから、このような事態にならないように気をつけてください。

問題解決のヒントになれば幸いです。

于 2013-01-19T07:32:19.003 に答える
2

これはあなたの MainActivity です:

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

ご不明な点がございましたら、後でお尋ねください。

于 2013-01-23T02:57:26.643 に答える
1

これは私にとってはうまくいきましたが、副作用があるかどうかはわかりません。

これを Fragment の onCreate に追加します

setRetainInstance(true);

これを AndroidManifest.xml に、フラグメントを含むアクティビティに

android:configChanges="orientation"
于 2013-01-23T09:33:14.983 に答える