Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/221.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
Java 在backstack中添加新片段时调用两次onBackStackChanged()_Java_Android_Android Fragments_Android View_Fragmentmanager - Fatal编程技术网

Java 在backstack中添加新片段时调用两次onBackStackChanged()

Java 在backstack中添加新片段时调用两次onBackStackChanged(),java,android,android-fragments,android-view,fragmentmanager,Java,Android,Android Fragments,Android View,Fragmentmanager,所以,我注意到了一个有趣的问题。当我以编程方式添加新片段时,从OnBackbackChangedListener调用OnBackbackChanged方法两次,但只能调用一次。以下是我的活动代码: import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; import android.support.v7.app.AppCompa

所以,我注意到了一个有趣的问题。当我以编程方式添加新片段时,从OnBackbackChangedListener调用OnBackbackChanged方法两次,但只能调用一次。以下是我的活动代码:

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;

public class MainActivity extends AppCompatActivity implements FragmentManager.OnBackStackChangedListener{

    private FragmentManager fragmentManager;
    private Button button1;
    private Button button2;
    private Button button3;

    private Fragment defaultFragment;
    private Fragment previousFragment;
    private Fragment currentFragment;
    private String currentFragmentTag;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        button1 = (Button) findViewById(R.id.button);
        button2 = (Button) findViewById(R.id.button2);
        button3 = (Button) findViewById(R.id.button3);

        button1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showFragment(new FragmentOne(), FragmentOne.TAG);
            }
        });

        button2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showFragment(new FragmentTwo(), FragmentTwo.TAG);
            }
        });

        button3.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showFragment(new FragmentThree(), FragmentThree.TAG);
            }
        });

        setupFragmentManager();

    }

    private void setupFragmentManager() {
        fragmentManager = getSupportFragmentManager();
        fragmentManager.addOnBackStackChangedListener(this);


        FragmentOne fragmentOne = new FragmentOne();
        defaultFragment = fragmentOne;  // fragment for default

        currentFragmentTag = FragmentOne.TAG;
        currentFragment = fragmentOne;

        fragmentManager.beginTransaction()
                .add(R.id.fragments_container, currentFragment, currentFragmentTag)
                .addToBackStack(currentFragmentTag)
                .commit();
    }

    public void showFragment(Fragment fragment, String fragmentTag) {
        previousFragment = currentFragment;
        currentFragment = fragment;
        fragmentManager.beginTransaction()
                .hide(previousFragment)
                .add(R.id.fragments_container, fragment, fragmentTag)
                .addToBackStack(fragmentTag)
                .commit();
    }

    @Override
    public void onBackStackChanged() {
        Log.d("MY_TAG" , "onBackStackChangedListener - " + fragmentManager.getBackStackEntryCount() );

        if (fragmentManager.getBackStackEntryCount() > 0) {    
            String fragmentTag = fragmentManager.getBackStackEntryAt(fragmentManager.getBackStackEntryCount() - 1).getName();
            currentFragment = fragmentManager.findFragmentByTag(fragmentTag);
        } else {
            currentFragment = defaultFragment;
        }

// some code...
    }

    @Override
    public void onBackPressed() {
        if (fragmentManager.getBackStackEntryCount() == 1) { 
            finish();
        } else {
            super.onBackPressed();
        }
    }
}
和片段类:

public class FragmentOne extends Fragment {

    public static final String TAG = FragmentOne.class.getSimpleName();

    private Context context;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {


        context = getActivity();
        View topLevelView = LayoutInflater.from(context).inflate(R.layout.fragment_layout, container, false);

        TextView textView = (TextView) topLevelView.findViewById(R.id.fragment_Text);

        textView.setText("This is FRAGMENT ONE");

        return topLevelView;
    }

}
碎片2和碎片3与碎片1相同

当我启动我的应用程序时,在日志中我看到:

onBackStackChangedListener - 1
onBackStackChangedListener - 1
按下按钮(显示下一个片段)后,我看到:

还有一个:

onBackStackChangedListener - 3
onBackStackChangedListener - 3
改变

.add(R.id.fragments_container, currentFragment, currentFragmentTag)

这并不能解决问题


但这很奇怪。为什么我的OnBackbackChangedListener在添加片段后多次调用own方法?

简直不敢相信这会发生。创建了一个类似的项目并深入到调试器中。原来这是新支持库中的一个bug。有一个

切换回
25.0.0
将按预期工作

compile 'com.android.support:appcompat-v7:25.0.0'
compile 'com.android.support:support-v4:25.0.0'


虽然没有在中提到,但已经提到,该问题在
25.4.0
中得到了解决,这很好只是一个更新。谷歌最终发布了25.4.0版,解决了这个问题

只是,现在支持的内容是从Google的Maven存储库中获取的:

maven { url 'https://maven.google.com' }

因此,您可以开始使用所有内容的新版本,并从SDK管理器中卸载本地支持存储库。

否,当我删除第行:.hide(previousFragment)-它无法解决问题。在添加第一个(默认)片段时没有隐藏方法。因此,这个问题并不取决于隐藏方法。实际上与您的问题无关,但您可以将View.OnClickListener接口直接实现到活动,并且对于每个按钮,
button.setOnClickListener(this)
,然后在活动中只需要一个
onClick
方法,并使用switch语句查找单击的视图,并从单个实现运行逻辑,而不是在每次有需要单击行为的视图时定义它。
compile 'com.android.support:appcompat-v7:25.0.0'
compile 'com.android.support:support-v4:25.0.0'
maven { url 'https://maven.google.com' }