Android fragments onListItemClick中的子片段在viewPager中的行为异常

Android fragments onListItemClick中的子片段在viewPager中的行为异常,android-fragments,android-viewpager,android-listfragment,onbackpressed,Android Fragments,Android Viewpager,Android Listfragment,Onbackpressed,我有3个ListFragments由一个viewPager处理(由FragmentAdapter管理)——它们工作得非常好。现在,当用户单击ListFragment#1中的项目时,将打开一个包含详细信息的新片段。它的行为方式如下: 仅单击列表项两次即可打开DetailFragment,但调试显示第一次单击确实进入了DetailFragment,但没有显示视图(视图仍然显示当前的ListFragment) 第二次单击后,DetailFragment确实显示了它的布局,但没有显示其中的元素(如Tex

我有3个ListFragments由一个viewPager处理(由FragmentAdapter管理)——它们工作得非常好。现在,当用户单击ListFragment#1中的项目时,将打开一个包含详细信息的新片段。它的行为方式如下:

  • 仅单击列表项两次即可打开DetailFragment,但调试显示第一次单击确实进入了DetailFragment,但没有显示视图(视图仍然显示当前的ListFragment)

  • 第二次单击后,DetailFragment确实显示了它的布局,但没有显示其中的元素(如TextView等)

  • 如果用户在显示DetailFragment时“意外”滑动屏幕,则viewPager会将其设置为第二个ListFragment!只有在按DetailFragment视图上的后退键时,viewPager才会“重置”为正确的ListFragment。当然,如果用户在DetailFragment中滑动,则viewPager的下一个ListFragment应该出现,并且应该删除DetailFragment

  • 感谢您提供的任何技巧,帮助您在Android的奇形怪状的碎片和视图世界中混淆视听:)

    公共类PlanetFragment扩展了ListFragment{
    充气机;
    列表视图列表;
    ArrayList PlanetList阵列;
    HashMap平面图;
    活动;
    语境;
    @凌驾
    CreateView上的公共视图(布局、充气机、视图组容器、捆绑包保存状态){
    视图v=充气机。充气(R.layout.playout\u选项卡\u布局,容器,错误);
    充气机=(LayoutFlater)GetLayoutFlater(savedInstanceState);
    activity=getActivity();
    context=PlanetFragment.this.getActivity();
    字符串dbTableName=“Table_”;
    SQLiteHelper info=newsqlitehelper(getActivity().getBaseContext());
    info.open();
    ArrayList datafromSQL=info.getData(dbTableName);
    如果(!datafromSQL.isEmpty()){
    planetListArray=新的ArrayList();
    
    对于(int i=0;i当您单击一个列表项时,您确实在构建一个新的细节片段,并告诉片段管理器用该片段替换标记“frag”。但是,您并不是在告诉视图寻呼机切换到该片段

    @Override
    public void onListItemClick(ListView l, View v, int position, long id) {
        super.onListItemClick(l, v, position, id);
        HashMap<String, String> item = planetListArray.get(position);
    
        Bundle bundle = new Bundle();
        bundle.putSerializable("itemMap", item);
        bundle.putInt("position", position);
        PlanetActivity pa = (PlanetActivity) activity;
        DetailFragment frag = pa.getDetailFragment();
        frag.setArguments(bundle);
        pa.setCurrentItem(1);
    }
    
    因为您已经有了指向活动的反向指针,所以可以使用findViewById查找视图寻呼机,然后调用viewPager.setCurrentItem

    我认为,在列表片段中构造新的详细信息片段可能是自找麻烦。当您使用FragmentPagerAdapter时,适配器通常会构造片段。我会让适配器生成片段,然后在OnlistItem中单击查找现有的详细信息片段并调用met来实现这一点使用新数据对其进行配置。但也许只有setCurrentItem可以解决您的问题

    编辑

    首先,我将编写FragmentPagerAdapter,这样您就可以使用getItem获取现有片段,而无需每次创建一个新片段

    public class PlanetFragmentAdapter extends FragmentPagerAdapter {
        private Fragment [] fragments = new Fragments[3];
    
        public PlanetFragmentAdapter(FragmentManager fm) {
            super(fm);
        }
    
        @Override
        public int getCount() {
            return 3;
        }
    
        @Override
        public Fragment getItem(int position) {
            Fragment fragment = fragments[position];
    
            if (fragment == null) {
                switch (position) {
                    case 0:
                        fragment = new PlanetFragment();
                        break;
                    case 1:
                        fragment = new DetailFragment();
                        break;
                    case 2:
                        fragment = new MysteryFragment();
                        break;
                }
                fragments[position] = fragment;
            }
            return fragment;
        }
    }
    
    还可以在活动中添加函数来处理片段:

    public void setPage(int position) {
        viewPager.setCurrentItem(position);
    }
    
    public DetailFragment getDetailFragment() {
        return (DetailFragment) viewPager.getItem(1); // now it doesn't create a new instance
        // you could also use getSupportFragmentManager().findFragmentById() here
    }
    
    现在,当您单击列表片段中的某个项目时,您可以获取现有的详细信息片段,对其进行配置,并将ViewPager设置为显示详细信息片段

    @Override
    public void onListItemClick(ListView l, View v, int position, long id) {
        super.onListItemClick(l, v, position, id);
        HashMap<String, String> item = planetListArray.get(position);
    
        Bundle bundle = new Bundle();
        bundle.putSerializable("itemMap", item);
        bundle.putInt("position", position);
        PlanetActivity pa = (PlanetActivity) activity;
        DetailFragment frag = pa.getDetailFragment();
        frag.setArguments(bundle);
        pa.setCurrentItem(1);
    }
    
    @覆盖
    public void onListItemClick(列表视图l、视图v、整数位置、长id){
    super.onListItemClick(左、右、位置、id);
    HashMap item=planetListArray.get(位置);
    Bundle=新Bundle();
    bundle.putSerializable(“itemMap”,item);
    bundle.putInt(“位置”,位置);
    平面触觉pa=(平面触觉)活动;
    DetailFragment frag=pa.getDetailFragment();
    frag.setArguments(bundle);
    pa.第(1)项;
    }
    
    Hi Bruce非常感谢您的清晰解释!我按照您的建议尝试设置viewPager的当前项,但效果几乎相同。如果我让适配器完成这项工作,这非常合理,我将如何设置子项?目前我有一个switch语句。例如:case 0:fragment=new PlanetFragment();案例1和案例2为其他两位家长。我将在何处定义子片段?谢谢!