当前位置: 首页 > 知识库问答 >
问题:

导航抽屉ViewPager片段,ViewPager不会销毁嵌套片段

卢志强
2023-03-14

我的应用程序有两个项目的导航抽屉:一个ViewPager(在一个片段内)和支持Map碎片。

ViewPager使用FragmentStatePagerAdapter并getItem(int位置)返回两个片段。

当我打开抽屉菜单并选择“项目1”(支持MapFrature)时,另一个碎片(ViewPager在其中)执行onDestroy()方法,但此方法不会破坏适配器创建的碎片,所以当我再次选择“项目0”时,我的应用程序创建的ViewPager与它的两个项目和其他两个片段的ViewPager没有删除。

当我选择“项目1”然后选择“项目0”时,这个问题会创建sames片段。。。所以碎片的数量增加了。

当ViewPager的容器片段执行onDestroy时,它如何删除这些片段?

我的代码

主要活动

public class Main extends SherlockFragmentActivity {

//Nombre de los elementos de la lista
private String[] mTitles;   
private DrawerLayout mDrawerLayout;
private ActionBarDrawerToggle mDrawerToggle;
private ListView mDrawerList;

private int currentPosition;

@Override
public void onCreate(Bundle savedInstanceState){
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main_navigation_drawer);

    //Inicialmente no hay ninguna opcion
    currentPosition = -1;

    mDrawerLayout = (DrawerLayout)findViewById(R.id.drawer_layout);
    mDrawerList = (ListView)findViewById(R.id.left_drawer);
    mDrawerToggle = new ActionBarDrawerToggle(
            this, 
            mDrawerLayout,
            R.drawable.ic_drawer, 
            R.string.drawer_open, 
            R.string.drawer_close) {

        /** Called when a drawer has settled in a completely closed state. */
        public void onDrawerClosed(View view) {
            // creates call to onPrepareOptionsMenu()
            supportInvalidateOptionsMenu();
        }

        /** Called when a drawer has settled in a completely open state. */
        public void onDrawerOpened(View drawerView) {             
            // creates call to onPrepareOptionsMenu()
            supportInvalidateOptionsMenu();
        }
    };

    mTitles = getResources().getStringArray(R.array.navigation_drawer_options);

    //Asignamos el Adapter
    mDrawerList.setAdapter(new ArrayAdapter<String>(this,R.layout.drawer_list_item, mTitles));
    //Asignamos el listener
    mDrawerList.setOnItemClickListener(new DrawerItemClickListener());

    mDrawerLayout.setDrawerListener(mDrawerToggle);
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    getSupportActionBar().setHomeButtonEnabled(true);

    if (savedInstanceState == null) {
        selectItem(0);
    }
}

@Override
protected void onPostCreate(Bundle savedInstanceState) {
    super.onPostCreate(savedInstanceState);
    // Sync the toggle state after onRestoreInstanceState has occurred.
    mDrawerToggle.syncState();
}

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    mDrawerToggle.onConfigurationChanged(newConfig);
}

private class DrawerItemClickListener implements ListView.OnItemClickListener {

    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        selectItem(position);
    }
}

/** Swaps fragments in the main content view */
private void selectItem(int position) {
    // Create a new fragment and specify the planet to show based on position

    if(currentPosition != position){
        //Solo hacemos remplazo de fragment si la opcion selecionada no es la misma
        //que la que esta ya en pantalla
        Fragment fragment = null;
        String fragmentName = "";
        boolean attach = true;

        switch (position) {
            case 0:
                fragmentName = PagerFragment.class.getSimpleName();
                fragment = getSupportFragmentManager().findFragmentByTag(fragmentName);
                if(fragment == null) {
                    fragment = new PagerFragment();
                    attach = false;
                }
                break;
            case 1:
                fragmentName = Map1Fragment.class.getSimpleName();
                fragment = getSupportFragmentManager().findFragmentByTag(fragmentName);
                if(fragment == null) {
                    fragment = new Map1Fragment();
                    attach = false;
                }
                break;      
            default:
                throw new IllegalArgumentException("Posicion no valida");
        }

        // Insert the fragment by replacing any existing fragment
        FragmentManager fragmentManager = getSupportFragmentManager();
        FragmentTransaction transaction = fragmentManager.beginTransaction();
        if(!attach){
            transaction.replace(R.id.content_frame, fragment);
        }else{
            transaction.attach(fragment);
        }
        transaction.commit();
    }
    currentPosition = position;
    // Highlight the selected item, update the title, and close the drawer
    mDrawerList.setItemChecked(position, true);     
    mDrawerLayout.closeDrawer(mDrawerList);
}

}

带有ViewPager的片段

public class PagerFragment extends SherlockFragment{

private ViewPager viewPager;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                Bundle savedInstanceState) {
    Log.d("PagerFragment", "onCreateView");
    return inflater.inflate(R.layout.application_tus, container, false);
}

@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        Log.d("PagerFragment", "onViewCreated");
        viewPager = (ViewPager) view.findViewById(R.id.viewpager);
        viewPager.setAdapter(new ViewPagerAdapter(getSherlockActivity(), getFragmentManager()));

        TitlePageIndicator titleIndicator = (TitlePageIndicator)view.findViewById(R.id.titles_viewpager);
        titleIndicator.setViewPager(viewPager,0);

}
}

FragmentStatePagerAdapter

public class ViewPagerAdapter extends FragmentStatePagerAdapter{

public static final int NUM_PAGES = 2;
public static final int [] titles = { R.string.st1, R.string.st2};

private Context context;

public ViewPagerAdapter(Context context, FragmentManager fragmentManager) {
    super(fragmentManager);
    this.context = context;
}

@Override
public Fragment getItem(int position) {
    Log.d("ViewPagerAdapter", "GetItem(" + position+")");
    switch (position) {
        case 0:
            return new FavoritesFragment();         
        case 1:
            return new LinesFragment();     
        default:
            throw new IllegalArgumentException("Error");
    }
}

@Override
public int getCount() {
    return NUM_PAGES;
}

@Override
public CharSequence getPageTitle(int position) {
    return context.getString(titles[position]);
}

}

共有1个答案

虞承泽
2023-03-14

我终于解决了我的问题。

创建FragmentStatePagerAdapter时,我使用了新的ViewPagerAdapter(getSherlockActivity(),getFragmentManager())。我最终使用了getChildFragmentManager(),它成功了!

 类似资料:
  • 我正在编写一个应用程序,它有一个导航抽屉,并且使用嵌套片段。导航抽屉几乎是按照Android文档创建的——它可以工作。我希望导航抽屉始终可见,这就是为什么我有一个活动,我只是交换片段。其中一个片段是ViewPager,它又有自己的片段作为页面。 导航是这样分层的: 其中片段是,子片段是它的页面。当我刚从抽屉转到时,所有内容都正常工作,但我不知道如何直接切换到给定页面(嵌套片段)。 处理导航抽屉点击

  • 根据谷歌的文档: 现在可以在片段中嵌入片段。这对于各种情况都很有用,在这些情况下,您需要将动态和可重用的UI组件放置到本身是动态和可重用的UI组件中。例如,如果使用ViewPager创建左右滑动并占用大部分屏幕空间的片段,现在可以将片段插入每个片段页面。要嵌套片段,只需对要添加片段的片段调用getChildFragmentManager()。这将返回一个FragmentManager,您可以像通常

  • 首先,我想说的是,我对android开发和gradle都是新手。不适用于java。我有一个支持2.3.6的项目,现在正在使用支持库将其迁移到4.4。我也在使用Gradle,到目前为止,它工作得很好。 我现在使用导航抽屉在应用程序片段之间导航,这些片段过去是活动。抽屉中的一个片段包含列表中某个项目的listview和detail视图。当用户单击列表中的项目并显示其详细信息时,抽屉片段切换其视图。 虽

  • 我目前正在为我的Android应用程序使用导航抽屉。在我的第一个片段中,有一个片段使用Facebook的Graph API加载数据。因此,当我的应用程序第一次加载时,它首先进入第一个片段。 然后,我使用导航抽屉单击另一个片段并查看它。 最后,我重用导航抽屉返回第一个片段并查看它。 我面临的问题是,我如何继续利用已经创建过一次的片段,而不是在选择导航抽屉项时重新创建它。我的片段切换代码如下所示。 我

  • 我希望能够使用导航抽屉,并根据导航中的选择在不同片段之间进行更改。 我正在使用Android Studio,基本上我所做的是这样的: 使用内置模板“导航抽屉活动”创建了一个新项目 创建了一个空白片段 然后我更改了onNavigationDrawerItemSelected方法中的一些代码。 我的程序崩溃了,给了我很多我不理解的错误。我做错了什么?

  • 问题内容: 我实现了带有ViewPager和TabsAdapter的ActionBarSherlock。它运作良好,但是现在我试图从另一个表中的“标签1”中加载的框架中“推送”。 该行为应类似于: 我的应用程序中有3个选项卡,启动时会看到第一个选项卡,其中有一个带有按钮的片段 按下第一个选项卡上的按钮,应替换第一个选项卡上的片段,并显示另一个片段 我试图实现这一点,但是在更换时有一个黑色的片段。