Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/196.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 刷新SwipeRefreshLayout时,不会立即提交显示和隐藏片段(不会发生)_Android_Android Fragments_Tabs_Instagram_Fragmentmanager - Fatal编程技术网

Android 刷新SwipeRefreshLayout时,不会立即提交显示和隐藏片段(不会发生)

Android 刷新SwipeRefreshLayout时,不会立即提交显示和隐藏片段(不会发生),android,android-fragments,tabs,instagram,fragmentmanager,Android,Android Fragments,Tabs,Instagram,Fragmentmanager,所以基本上我所做的工作与Instagram应用程序非常相似,在Instagram应用程序中有许多选项卡,用户可以毫不延迟地切换到任何选项卡,无论发生什么事情,例如刷新、重新加载等。它还使用“上一步”按钮返回到以前保留的选项卡 为了实现这一点,我使用了FragmentManager和FragmentTransaction来显示和隐藏代表每个选项卡的每个片段。我没有使用replace或attach/detach,因为它们会破坏上一个选项卡的视图层次结构 我的实现运行得很好,只是没有提交显示和隐藏片段

所以基本上我所做的工作与Instagram应用程序非常相似,在Instagram应用程序中有许多选项卡,用户可以毫不延迟地切换到任何选项卡,无论发生什么事情,例如刷新、重新加载等。它还使用“上一步”按钮返回到以前保留的选项卡

为了实现这一点,我使用了
FragmentManager
FragmentTransaction
来显示和隐藏代表每个选项卡的每个片段。我没有使用
replace
attach
/
detach
,因为它们会破坏上一个选项卡的视图层次结构

我的实现运行得很好,只是没有提交显示和隐藏片段(我非常怀疑这是一个正确的说法,但到目前为止,我是这样理解流程的。),或者当
SwipeRefreshLayout
刷新片段时(要隐藏),不会立即发生添加到
FragmentManager
的时间晚于要显示的时间

我的实现遵循如下规则。假设我们有4个选项卡,我的MainActivity显示第一个选项卡,比如FirstFragment,用户选择第二个选项卡,SecondFragment。因为以前从未添加过SecondFragment,所以我使用
FragmentTransaction将其添加到
FragmentManager
。添加
并使用
FragmentTransaction.hide
隐藏第一个片段。如果用户再次选择第一个选项卡,因为FirstFragment之前已添加到
FragmentManager
,它不会添加,而是只显示FirstFragment,只隐藏SecondFragment。在这两个选项卡之间进行选择会很顺利

但当用户“刷新”SecondFragment的
SwipeRefreshLayout
并选择第一个选项卡时,
FragmentTransaction
等待SecondFragment的刷新完成并提交(?)实际事务。奇怪的是,事务立即以相反的方式提交,从FirstFragment的刷新到SecondFragment

因为这是按照添加到
FragmentManager
的顺序发生的,所以我怀疑添加的顺序是否会影响片段的backbackback,并且可能存在类似UI线程优先级的东西,因此它会强制片段事务在稍后添加的片段的UI转换完成后发生。但我只是没有足够的线索来解决这个问题。我曾尝试在
FragmentTransaction
上附加/分离和反备份,但无法解决问题。我尝试了
FragmentTransaction.commit
FragmentTransaction.committeAllowingStateLoss
,但都没有解决问题

这些是我的MainActivity的示例代码

private ArrayList<Integer> mFragmentsStack; // This is simple psuedo-stack which only stores
                                            // the order of fragments stack to collaborate
                                            // when back button is pressed.
private ArrayList<Fragment> mFragmentsList;

@Override
protected void onCreate() {
    mFragmentsStack = new ArrayList<>();
    mFragmentsList = new ArrayList<>();
    mFragmentsList.add(FirstFragment.newInstance());
    mFragmentsList.add(SecondFragment.newInstance());
    mFragmentsList.add(ThirdFragment.newInstance());
    mFragmentsList.add(FourthFragment.newInstance());
    mMainTab = (MainTab) findViewById(R.id.main_tab);
    mMainTab.setOnMainTabClickListener(this);

    int currentTab = DEFAULT_TAB;

    mFragmentsStack.add(currentTab);
    getSupportFragmentManager().beginTransaction().add(R.id.main_frame_layout,
            mFragmentsList.get(currentTab), String.valueOf(currentTab)).commit();
    mMainTab.setCurrentTab(currentTab);
}

// This is custom interface.
@Override
public void onTabClick(int oldPosition, int newPosition) {
    if (oldPosition != newPosition) {
        FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();

        // First hide the old tab.
        fragmentTransaction.hide(mFragmentsList.get(oldPosition));

        // Recalculate the fragment stack.
        if (mFragmentsStack.contains(newPosition)) {
            mFragmentsStack.remove((Integer) newPosition);
        }
        mFragmentsStack.add(newPosition);

        // Add new fragment if it's not added before, or show new fragment which was already hidden.
        Fragment fragment = getSupportFragmentManager().findFragmentByTag(String.valueOf(newPosition));
        if (fragment != null) {
            fragmentTransaction.show(fragment);
        } else {
            fragmentTransaction.add(R.id.main_frame_layout, mFragmentsList.get(newPosition),
                    String.valueOf(newPosition));
        }

        // Commit the transaction.
        fragmentTransaction.commitAllowingStateLoss();
    }
}

// It mimics the tab behavior of Instagram Android application.
@Override
public void onBackPressed() {
    // If there's only one fragment on stack, super.onBackPressed.
    // If it's not, then hide the current fragment and show the previous fragment.
    int lastIndexOfFragmentsStack = mFragmentsStack.size() - 1;
    if (lastIndexOfFragmentsStack - 1 >= 0) {
        FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
        fragmentTransaction.hide(mFragmentsList.get(mFragmentsStack.get(lastIndexOfFragmentsStack)));
        fragmentTransaction.show(mFragmentsList.get(mFragmentsStack.get(lastIndexOfFragmentsStack - 1)));
        fragmentTransaction.commitAllowingStateLoss();
        mMainTab.setCurrentTab(mFragmentsStack.get(lastIndexOfFragmentsStack - 1));
        mFragmentsStack.remove(lastIndexOfFragmentsStack);
    } else {
        super.onBackPressed();
    }
}
private ArrayList mffragmentsstack;//这是一个简单的psuedo堆栈,它只存储
//碎片堆栈协作的顺序
//当按下后退按钮时。
私有数组列表MFFragmentsList;
@凌驾
受保护的void onCreate(){
mffragmentsstack=newarraylist();
MFFragmentsList=新的ArrayList();
添加(FirstFragment.newInstance());
添加(SecondFragment.newInstance());
添加(ThirdFragment.newInstance());
添加(FourthFragment.newInstance());
mMainTab=(MainTab)findviewbyd(R.id.main_选项卡);
mMainTab.setOnMainTabClickListener(此);
int currentTab=默认的\u选项卡;
添加(当前选项卡);
getSupportFragmentManager().beginTransaction().add(R.id.main\u frame\u布局,
MFFragmentsList.get(currentTab),String.valueOf(currentTab)).commit();
mMainTab.setCurrentTab(currentTab);
}
//这是自定义接口。
@凌驾
public void onTabClick(int oldPosition,int newPosition){
如果(旧位置!=新位置){
FragmentTransaction FragmentTransaction=getSupportFragmentManager().beginTransaction();
//首先隐藏旧标签。
fragmentTransaction.hide(MFFragmentsList.get(oldPosition));
//重新计算片段堆栈。
if(MFFragmentSSTACK.contains(新位置)){
mffragmentsstack.remove((整数)newPosition);
}
MFFragmentsStack.add(新位置);
//如果之前没有添加新片段,则添加新片段,或者显示已隐藏的新片段。
Fragment Fragment=getSupportFragmentManager().findFragmentByTag(String.valueOf(newPosition));
if(片段!=null){
fragmentTransaction.show(fragment);
}否则{
fragmentTransaction.add(R.id.main\u frame\u布局,MFFragmentsList.get(newPosition),
字符串.valueOf(newPosition));
}
//提交事务。
fragmentTransaction.commitAllowingStateLoss();
}
}
//它模仿Instagram Android应用程序的选项卡行为。
@凌驾
public void onBackPressed(){
//若堆栈上只有一个片段,则super.onBackPressed。
//如果不是,则隐藏当前片段并显示上一个片段。
int lastIndexOffFragmentsStack=MFFragmentsStack.size()-1;
如果(LastIndexOffFragmentsStack-1>=0){
FragmentTransaction FragmentTransaction=getSupportFragmentManager().beginTransaction();
fragmentTransaction.hide(MFFragmentsList.get(MFFragmentsStack.get(LastIndexOffFragmentsStack));
fragmentTransaction.show(MFFragmentsList.get(MFFragmentsStack.get(lastIndexOffFragmentsStack-1));
fragmentTransaction.commitAllowingStateLoss();
mMainTab.setCurrentTab(mfFragmentsStack.get(lastIndexOffFragmentsStack-1));
MFFragmentsStack.移除(LastIndexOffFragmentsStack);
}否则{
super.onBackPressed();
}
}

只是面临着相同的问题,但唯一的区别是——我正在切换工具栏按钮上的片段。 我已经设法摆脱了我
@Override
public void onHiddenChanged(boolean hidden) {
    super.onHiddenChanged(hidden);
    if (hidden) {
        yourSwipeRefreshLayout.setRefreshing(false);
    }
}