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){
当前优先级