Android 如何在“查看寻呼机”选项卡中切换列表片段和详细信息片段?

Android 如何在“查看寻呼机”选项卡中切换列表片段和详细信息片段?,android,android-fragments,android-viewpager,Android,Android Fragments,Android Viewpager,我正在尝试在视图寻呼机的第一个选项卡中实现片段的切换。我尝试了这里找到的方法,它使用第一个选项卡中的根片段,然后切换子片段。但当在第二个子片段中出现屏幕旋转时,应用程序会切换回第一个子片段,除此之外,它看起来像是一个黑客 我试着寻找其他的方法,但找到了几十个看起来很混乱的答案。 来自的解释似乎正确,但我不完全理解。以下是该链接的解释和代码: 这种方法是通过覆盖getItem(…)方法以及getItemPosition(Object Object)来切换显示在FragmentPagerAdapte

我正在尝试在视图寻呼机的第一个选项卡中实现片段的切换。我尝试了这里找到的方法,它使用第一个选项卡中的根片段,然后切换子片段。但当在第二个子片段中出现屏幕旋转时,应用程序会切换回第一个子片段,除此之外,它看起来像是一个黑客

我试着寻找其他的方法,但找到了几十个看起来很混乱的答案。 来自的解释似乎正确,但我不完全理解。以下是该链接的解释和代码:

这种方法是通过覆盖
getItem(…)
方法以及
getItemPosition(Object Object)
来切换显示在
FragmentPagerAdapter
中的片段,该片段在每次调用
viewPager.getAdapter().notifyDataSetChanged()
时都会被调用。例如:

public static class MyPagerAdapter extends FragmentStatePagerAdapter {
// Return a different fragment for position based on additional state tracked in a member variable
@Override
public Fragment getItem(int position) {
    // For a given position, return two different potential fragments based on a condition
}

// Force a refresh of the page when a different fragment is displayed
@Override
public int getItemPosition(Object object) {
    // this method will be called for every fragment in the ViewPager
    if (object instanceof SomePermanantCachedFragment) {
        return POSITION_UNCHANGED; // don't force a reload
    } else {
        // POSITION_NONE means something like: this fragment is no longer valid
        // triggering the ViewPager to re-build the instance of this fragment.
        return POSITION_NONE;
    }
}
}
假设我有
ListFragment
DetailFragment
,它们应该在第一个选项卡中切换

  • 在哪里调用
    viewPager.getAdapter().notifyDataSetChanged()
  • (…基于成员变量中跟踪的其他状态)如何实现这一点
  • SomePermanantCachedFragment
    在我的例子中指的是
    ListFragment

  • 例如,我也尝试过搜索github,但没有成功…

    如果PagerAdapter中的片段是动态的,那么应该使用动态FragmentPagerAdapter

    public class DynamicFragmentPagerAdapter extends PagerAdapter {
        private static final String TAG = "DynamicFragmentPagerAdapter";
      
        private final FragmentManager fragmentManager;
      
        public static abstract class FragmentIdentifier implements Parcelable {
            private final String fragmentTag;
            private final Bundle args;
          
            public FragmentIdentifier(@NonNull String fragmentTag, @Nullable Bundle args) {
                this.fragmentTag = fragmentTag;
                this.args = args;
            }
          
            protected FragmentIdentifier(Parcel in) {
                fragmentTag = in.readString();
                args = in.readBundle(getClass().getClassLoader());
            }
    
            @Override
            public void writeToParcel(Parcel dest, int flags) {
                dest.writeString(fragmentTag);
                dest.writeBundle(args);
            }
          
            protected final Fragment newFragment() {
                Fragment fragment = createFragment();
                Bundle oldArgs = fragment.getArguments();
                Bundle newArgs = new Bundle();
                if(oldArgs != null) {
                    newArgs.putAll(oldArgs);
                }
                if(args != null) {
                    newArgs.putAll(args);
                }
                fragment.setArguments(newArgs);
                return fragment;
            }
    
            protected abstract Fragment createFragment();
        }
      
        private ArrayList<FragmentIdentifier> fragmentIdentifiers = new ArrayList<>();
    
        private FragmentTransaction currentTransaction = null;
    
        private Fragment currentPrimaryItem = null;
    
        public DynamicFragmentPagerAdapter(FragmentManager fragmentManager) {
            this.fragmentManager = fragmentManager;
        }
    
        private int findIndexIfAdded(FragmentIdentifier fragmentIdentifier) {
            for (int i = 0, size = fragmentIdentifiers.size(); i < size; i++) {
                FragmentIdentifier identifier = fragmentIdentifiers.get(i);
                if (identifier.fragmentTag.equals(fragmentIdentifier.fragmentTag)) {
                    return i;
                }
            }
            return -1;
        }
    
        public void addFragment(FragmentIdentifier fragmentIdentifier) {
            if (findIndexIfAdded(fragmentIdentifier) < 0) {
                fragmentIdentifiers.add(fragmentIdentifier);
                notifyDataSetChanged();
            }
        }
    
        public void removeFragment(FragmentIdentifier fragmentIdentifier) {
            int index = findIndexIfAdded(fragmentIdentifier);
            if (index >= 0) {
                fragmentIdentifiers.remove(index);
                notifyDataSetChanged();
            }
        }
    
        @Override
        public int getCount() {
            return fragmentIdentifiers.size();
        }
    
        @Override
        public void startUpdate(@NonNull ViewGroup container) {
            if (container.getId() == View.NO_ID) {
                throw new IllegalStateException("ViewPager with adapter " + this
                        + " requires a view id");
            }
        }
    
        @SuppressWarnings("ReferenceEquality")
        @NonNull
        @Override
        public Object instantiateItem(@NonNull ViewGroup container, int position) {
            if (currentTransaction == null) {
                currentTransaction = fragmentManager.beginTransaction();
            }
            final FragmentIdentifier fragmentIdentifier = fragmentIdentifiers.get(position);
            // Do we already have this fragment?
            final String name = fragmentIdentifier.fragmentTag;
            Fragment fragment = fragmentManager.findFragmentByTag(name);
            if (fragment != null) {
                currentTransaction.attach(fragment);
            } else {
                fragment = fragmentIdentifier.newFragment();
                currentTransaction.add(container.getId(), fragment, fragmentIdentifier.fragmentTag);
            }
            if (fragment != currentPrimaryItem) {
                fragment.setMenuVisibility(false);
                fragment.setUserVisibleHint(false);
            }
            return fragment;
        }
    
        @Override
        public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
            if (currentTransaction == null) {
                currentTransaction = fragmentManager.beginTransaction();
            }
            currentTransaction.detach((Fragment) object);
        }
    
        @SuppressWarnings("ReferenceEquality")
        @Override
        public void setPrimaryItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
            Fragment fragment = (Fragment) object;
            if (fragment != currentPrimaryItem) {
                if (currentPrimaryItem != null) {
                    currentPrimaryItem.setMenuVisibility(false);
                    currentPrimaryItem.setUserVisibleHint(false);
                }
                fragment.setMenuVisibility(true);
                fragment.setUserVisibleHint(true);
                currentPrimaryItem = fragment;
            }
        }
    
        @Override
        public void finishUpdate(@NonNull ViewGroup container) {
            if (currentTransaction != null) {
                currentTransaction.commitNowAllowingStateLoss();
                currentTransaction = null;
            }
        }
    
        @Override
        public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
            return ((Fragment) object).getView() == view;
        }
    
        @Override
        public Parcelable saveState() {
            Bundle bundle = new Bundle();
            bundle.putParcelableArrayList("fragmentIdentifiers", fragmentIdentifiers);
            return bundle;
        }
    
        @Override
        public void restoreState(Parcelable state, ClassLoader loader) {
            Bundle bundle = ((Bundle)state);
            bundle.setClassLoader(loader);
            fragmentIdentifiers = bundle.getParcelableArrayList("fragmentIdentifiers");
        }
    }
    
    公共类DynamicFragmentPagerAdapter扩展了PagerAdapter{
    私有静态最终字符串标记=“DynamicFragmentPagerAdapter”;
    私人最终碎片管理人碎片管理人;
    公共静态抽象类FragmentIdentifier实现了Parcelable{
    私有最终字符串片段标记;
    私有最终包args;
    公共碎片标识符(@NonNull String fragmentTag,@null Bundle args){
    this.fragmentTag=fragmentTag;
    this.args=args;
    }
    受保护的碎片标识符(包裹中){
    fragmentTag=in.readString();
    args=in.readBundle(getClass().getClassLoader());
    }
    @凌驾
    公共无效写入包裹(包裹目的地,内部标志){
    目的写入限制(碎片标签);
    目的写入绑定(args);
    }
    受保护的最终片段newFragment(){
    Fragment Fragment=createFragment();
    Bundle oldArgs=fragment.getArguments();
    Bundle newArgs=新Bundle();
    if(oldArgs!=null){
    newArgs.putAll(oldArgs);
    }
    如果(args!=null){
    newArgs.putAll(args);
    }
    fragment.setArguments(newArgs);
    返回片段;
    }
    受保护的抽象片段createFragment();
    }
    私有ArrayList fragmentIdentifiers=新ArrayList();
    private FragmentTransaction currentTransaction=null;
    私有片段currentPrimaryItem=null;
    公共动态碎片页面编辑器(碎片管理器碎片管理器){
    this.fragmentManager=fragmentManager;
    }
    私有int findIndexIfAdded(FragmentIdentifier FragmentIdentifier){
    for(int i=0,size=fragmentIdentifiers.size();i=0){
    片段标识符。删除(索引);
    notifyDataSetChanged();
    }
    }
    @凌驾
    public int getCount(){
    返回fragmentIdentifiers.size();
    }
    @凌驾
    public void startUpdate(@NonNull ViewGroup container){
    if(container.getId()==View.NO\u ID){
    抛出新的IllegalStateException(“带适配器的ViewPager”+此
    +“需要视图id”);
    }
    }
    @SuppressWarnings(“引用相等”)
    @非空
    @凌驾
    公共对象实例化项(@NonNull视图组容器,int位置){
    如果(currentTransaction==null){
    currentTransaction=fragmentManager.beginTransaction();
    }
    final FragmentIdentifier FragmentIdentifier=FragmentIdentifier.get(位置);
    //我们已经有这个片段了吗?
    最终字符串名称=fragmentIdentifier.fragmentTag;
    Fragment Fragment=fragmentManager.findFragmentByTag(名称);
    if(片段!=null){
    currentTransaction.attach(片段);
    }否则{
    fragment=fragmentIdentifier.newFragment();
    currentTransaction.add(container.getId(),fragment,fragmentIdentifier.fragmentTag);
    }
    if(片段!=currentPrimaryItem){
    片段的可设置性(假);
    fragment.setUserVisibleHint(false);
    }
    返回片段;
    }
    @凌驾
    public void destructionItem(@NonNull视图组容器,int位置,@NonNull对象){
    如果(currentTransaction==null){
    currentTransaction=fragmentManager.beginTransaction();
    }
    分离((片段)对象);
    }
    @SuppressWarnings(“引用相等”)
    @凌驾
    public void setPrimaryItem(@NonNull视图组容器,int位置,@NonNull对象){
    Fragment=(Fragment)对象;
    if(片段!=currentPrimaryItem){
    如果(currentPrimaryItem!=null){
    当前优先级