为什么使用SupportFragmentManager添加片段的顺序很重要?

3
我正在创建一个 AuthenticationActivity,为用户提供通过 Facebook、Twitter 或特定应用程序进行登录的选项。在按照 Facebook Android SDK 文档中写得很好的 tutorial Use Facebook Login 后,我成功实现了 Facebook 的身份验证。
不幸的是,当我添加 Twitter Fragment 以提供类似的登录功能时,遇到了问题。突然间,Facebook 登录按钮无法改变状态,我的 Facebook 身份验证也无法完全完成,尽管我可以看到身份验证回调被返回。
在反复尝试后,我最终决定通过 SupportFragmentManager 更改 AuthenticationActivity 添加片段的顺序。当我这样做时,Facebook 再次开始工作,但 Twitter 片段却出现了问题。
getSupportFragmentManager()
    .beginTransaction()
    .add(android.R.id.content, twitterFragment)
    .add(android.R.id.content, facebookFragment)
    .commit();

这让我感觉更糟了,没有让我感觉更好。我承认我不完全理解碎片,但为什么添加碎片的顺序会产生这种影响,这让我非常困惑。不管先加哪个都不起作用,但第二个添加的会起作用。值得注意的是,我正在使用和它的碎片实现。
以下是我的活动和碎片代码:
认证活动(AuthenticationActivity)
public class AuthenticationActivity extends SherlockFragmentActivity {

    private FacebookFragment facebookFragment;
    private TwitterFragment twitterFragment;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        if (savedInstanceState == null) {
            addFragments();
        } else {
            restoreFragments();
        }
    }

    private void addFragments() {
        facebookFragment = new FacebookFragment();
        twitterFragment = new TwitterFragment();

        // TODO the order of this MATTERS if Facebook isn't last
        // Facebook auth breaks and vice versa.
        getSupportFragmentManager()
            .beginTransaction()
            .add(android.R.id.content, twitterFragment)
            .add(android.R.id.content, facebookFragment)
            .commit();
    }

    private void restoreFragments() {
        facebookFragment = (FacebookFragment) getSupportFragmentManager()
            .findFragmentById(android.R.id.content);
        twitterFragment = (TwitterFragment) getSupportFragmentManager()
            .findFragmentById(android.R.id.content);
    }
}

Facebook片段(大部分基于SDK文档示例

public class FacebookFragment extends SherlockFragment {

    private UiLifecycleHelper uiHelper;
    private static final String TAG = FacebookFragment.class.getSimpleName();

    private Session.StatusCallback callback = new Session.StatusCallback() {
        @Override
        public void call(Session session, SessionState state,
            Exception exception) {
            onSessionStateChange(session, state, exception);
        }
    };

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.authentication, container, false);

        LoginButton facebookButton
            = (LoginButton) view.findViewById(R.id.facebookButton);
        facebookButton.setFragment(this);

        return view;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        uiHelper = new UiLifecycleHelper(getActivity(), callback);
        uiHelper.onCreate(savedInstanceState);
    }

    @Override
    public void onResume() {
        super.onResume();

        Session session = Session.getActiveSession();
        if (session != null && (session.isOpened() || session.isClosed())) {
            onSessionStateChange(session, session.getState(), null);
        }

        uiHelper.onResume();
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        uiHelper.onActivityResult(requestCode, resultCode, data);
    }

    @Override
    public void onPause() {
        super.onPause();
        uiHelper.onPause();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        uiHelper.onDestroy();
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        uiHelper.onSaveInstanceState(outState);
    }

    private void onSessionStateChange(Session session, SessionState state,
        Exception exception) {
        if (state.isOpened()) {
            Log.i(TAG, "Logged in...");
        } else if (state.isClosed()) {
            Log.i(TAG, "Logged out...");
        } else {
            Log.i(TAG, "unknown state " + state);
        }
    }
}

TwitterFragment

public class TwitterFragment extends SherlockFragment {

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.authentication, container, false);

        Button twitterButton = (Button) view.findViewById(R.id.twitterButton);
        twitterButton.setOnClickListener(twitterClickListener);

        return view;
    }

    private OnClickListener twitterClickListener = new OnClickListener() {
        public void onClick(View v) {
            Context context = v.getContext();

            Intent intent = new Intent(context, TwitterLoginActivity.class);
            context.startActivity(intent);
        }
    };
}

为什么通过SupportFragmentManger添加上述片段的顺序很重要?

两个片段都填满整个屏幕吗?你能更清楚地说明哪里出了问题吗?按钮没有显示,不能被点击等等... - Warpzit
1个回答

0
 private void restoreFragments() {
        facebookFragment = (FacebookFragment) getSupportFragmentManager()
            .findFragmentById(android.R.id.content);
        twitterFragment = (TwitterFragment) getSupportFragmentManager()
            .findFragmentById(android.R.id.content);
    }

你需要为每个片段分配不同的id,否则对于给定的id,你将始终得到相同的片段。我猜你会得到第一个声明/添加的片段,但这取决于实现方式。(你可能会遇到类转换异常)。

要解决这个问题,为它们分配不同的id并将它们添加到不同的占位符中。

.beginTransaction()
            .add(R.id.twitter_fragment, twitterFragment)
            .add(R.id.facebook_fragment, facebookFragment)
            .commit();

这需要其他的改变,但希望你能达成目标。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接