【问题标题】:How come position information isn't being passed to my fragments?为什么位置信息没有传递给我的片段?
【发布时间】:2014-09-21 08:28:44
【问题描述】:

我有一个Activity,它在很大程度上未修改为选项卡式活动的默认 Android Studio 示例。它的FragmentPagerAdapter 被修改为显示所有 50 个美国,并有 50 个相应的选项卡显示它们的名称。这一直有效,直到片段被销毁,但重新创建时,不会告诉它在哪个选项卡上。为什么会发生这种情况?

以下是我认为可能导致问题的所有方法:

public class MainQuizActivity extends Activity implements ActionBar.TabListener {

    ...

    public class SectionsPagerAdapter extends FragmentPagerAdapter {

        ...

        @Override
        public Fragment getItem(int position) {
            // getItem is called to instantiate the fragment for the given page.
            // Return a PlaceholderFragment (defined as a static inner class below).
            return
                questionFragments[position] == null
                    ? questionFragments[position] = QuestionFragment.newInstance(position)
                    : questionFragments[position];
        }

        ...
    }

    ...
}

...

public class QuestionFragment extends Fragment {

    ...

    public static QuestionFragment newInstance(int stateIndex) {
        System.out.println("Creating new instance for state #" + stateIndex);
        QuestionFragment fragment = new QuestionFragment();
        Bundle args = new Bundle();
        args.putInt(States.BUNDLE_KEY, stateIndex);
        fragment.setArguments(args);
        return fragment;
    }

    ...

    @Override
    public View onCreateView(
        LayoutInflater inflater,
        ViewGroup container,
        Bundle savedInstanceState) {
        System.out.println("~onCreateView");
        View rootView = inflater.inflate(
            R.layout.fragment_main_quiz, container, false);

        webView = (WebView)rootView.findViewById(R.id.webView);
        initState(savedInstanceState);

        return rootView;
    }

    private void initState(Bundle args) {
        if (state == null) {
            System.out.println("Bundle: " + args);
            if (args == null)
                args = getArguments();
            System.out.println("Bundle is now: " + args);
            int stateIndex = args.getInt(States.BUNDLE_KEY);
            System.out.println("Gonna be state #" + stateIndex);
            state = States.values()[stateIndex];
            System.out.println("Gonna be " + state);
        }
        else
            System.out.println("State already exists! (yay!)");

        String path = state.getImageURL();
        System.out.println("Opening image at " + path);

        webView.loadUrl(path);
        webView.setBackgroundColor(0x00000000);
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        System.out.println("~onCreate");
        super.onCreate(savedInstanceState);
        if (webView == null)
            webView = (WebView)(getActivity().findViewById(R.id.webView));
        System.out.println("onCreate: webView == " + webView);
        System.out.println("onCreate: bundle == " + savedInstanceState);

        if (webView != null
            && savedInstanceState != null)
        initState(savedInstanceState);
    }

    ...

}

我用密钥States.BUNDLE_KEY(即"STATE")将它保存在捆绑包中,但第二次提供的捆绑包中没有该密钥。出于调试目的,我用空的方法覆盖了所有处理加载和卸载的 on* 方法,例如:

@Override public void onResume(){
    System.out.println("~onResume");
    super.onResume();}

当然,我还投入了更多的调试输出。

我希望我录制的这个视频有助于说明问题:http://youtu.be/cmbR_2rvpX4

视频的控制台转储位于此粘贴箱中:http://pastebin.com/rxAP7qda

而且,如果这一切仍然没有帮助,这是它的 githttps://github.com/Supuhstar/US-State-Quiz-App


即使在这一切之后,我仍然觉得我没有提供正确的信息。如果您认为这可以做得更好,请要求更少或更多。

【问题讨论】:

  • 您还没有实现任何逻辑来保存/恢复Activity已保存状态下的选项卡选择...
  • 没有任何理由在onCreate()onCreateView() 中调用initState(savedInstanceState);(仅使用onCreateView())。此外,您永远不应该通过getActivity.findViewById() 查找片段的视图,特别是如果您使用该片段的多个实例(就像您一样)。
  • 好的,我该怎么做才能解决这个问题?
  • 删除片段的 onCreate 回调并对我在此处所做的片段进行更改 gist.github.com/luksprog/92720adc1b2f26390f5a 。看看进展如何。
  • @Luksprog 这解决了我所有的问题!把它作为答案!

标签: android android-fragments tabview


【解决方案1】:

您没有在QuestionFragment 中正确初始化事物。首先,不需要在onCreate()onCreateView() 回调中调用initState(savedInstanceState); 方法。在onCreateView() 中调用它并完全删除onCreate() 方法:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    System.out.println("~onCreateView");
    View rootView = inflater.inflate(R.layout.fragment_main_quiz, container, false);

    webView = (WebView)rootView.findViewById(R.id.webView);
    guessSpinner = (Spinner)getActivity().findViewById(R.id.guess_spinner);
    initState();
    initGuesser();
    return rootView;
}

您的initState(savedInstanceState) 方法对于它应该做什么也有点太复杂了:

private void initState() {
     Bundle args = getArguments();
     if (args == null) {
        throw new IllegalArgumentException("The arguments should be valid!");
     }
     System.out.println("Bundle is now: " + args);
     int stateIndex = args.getInt(States.BUNDLE_KEY); 
     System.out.println("Gonna be state #" + stateIndex);
     state = States.values()[stateIndex];
     System.out.println("Gonna be " + state);
     String path = state.getImageURL();
     System.out.println("Opening image at " + path);

     webView.loadUrl(path);
     webView.setBackgroundColor(getResources().getColor(R.color.transparent));
}

【讨论】:

  • 完美!谢谢:3
猜你喜欢
  • 1970-01-01
  • 2018-09-09
  • 2015-03-30
  • 2019-06-14
  • 1970-01-01
  • 2020-01-16
  • 1970-01-01
  • 1970-01-01
  • 2015-08-29
相关资源
最近更新 更多