Search code examples
androidandroid-fragmentsandroid-fragmentactivity

FragmentActivity creates more than one Fragments cause problems


I instantiate a FragmentActivity (FA1), which shows articles in it's Fragments (F1) (using ViewPager). Every article Fragment has an instance of an extra Class (W), a WebManager, which saves the ID of the article. If I click on an image in the article, the WebViewClient will create another FragmentActivity (FA2) (with the article ID saved in the bundle), which shows images in it's Fragments (F2).

Following is happened:

FA1 build three F1: A3, A2, A1 (in this order). Every F1 instantiate a W with it's ID (A3: ID = A3, A2: ID = A2, A1: ID = A1). Also, ID is overwritten and it's value is A3 everytime. If I click on an image in A2, the W would create FA2 with ID = A3, not A2!

What could I do to save the instance of W for exactly this F1, I clicked on? Don't know what to do :(

Hope I illustrate the scenario correct (in english), asked this question in a german forum too...

--edit--

F1:

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
...
    articleID = args.getString("articleID");//set in FA1, will be overwriten
    WebView webView = ((WebView) rootView.findViewById(R.id.articleFragment));
    WebManagerArticle wm = WebManagerArticle.getInstance(activity, Integer.parseInt(articleID));
    webView.setHttpAuthUsernamePassword(Constants.HOST, "", Constants.HTTP_USER, Constants.HTTP_PASSWORD);
    webView.setWebViewClient(wm.getArticleWebViewClient());
...
return rootView;
}

WebManagerArticle:

public class WebManagerArticle extends WebManager
{
    private static WebManagerArticle instance = null;
    private static int id = -1;
    private static ArticleWebViewClient webViewClient = null;
    private WebManagerArticle()
    {
        super();
        webViewClient = new ArticleWebViewClient();
    }

    public static WebManagerArticle getInstance(Activity a, int articleId)
    {
        if (instance == null)
        {
            instance = new WebManagerArticle();
        }
        activity = a;
        id = articleId;
        return instance;
    }

    public ArticleWebViewClient getArticleWebViewClient(){return webViewClient;}

    private class ArticleWebViewClient extends WebViewClient
    {
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url)
        {
            ...//HERE
            Intent intent = new Intent(activity, ImagePageSliderActivity.class);
            intent.putExtra("imagePath", imagePath); //get imagePath from url with pattern matching
            intent.putExtra("articleID", id);
            activity.startActivity(intent);
            ...
            return true;
        }
        @Override
        public void onReceivedHttpAuthRequest(WebView view, HttpAuthHandler handler, String host, String realm)
        {
            handler.proceed(Constants.HTTP_USER, Constants.HTTP_PASSWORD);
        }
    }
}

ImagePageSlideActivity

public class ImagePageSliderActivity extends SherlockFragmentActivity
{
    public Context context;
    public int articleID;
    public int pages;
    private int startPosition;
    public ArrayList<String> imagePaths;
    private ViewPager viewPager;

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

        setContentView(R.layout.activity_article_page_slider);

        String startImagePath = getIntent().getStringExtra("imagePath");
        // here's the wrong article ID!!!
        articleID = getIntent().getIntExtra("articleID", -1);

        // pages get From Database
        // startPosition get From Database
        // imagePaths get from database

        viewPager = (ViewPager) findViewById(R.id.articlePager);
        PagerAdapter pagerAdapter = new ScreenSlidePagerAdapter(
                getSupportFragmentManager());
        viewPager.setAdapter(pagerAdapter);
        viewPager.setCurrentItem(startPosition);
    }

    @Override
    public void onBackPressed()
    {
        if (viewPager.getCurrentItem() == startPosition)
        {
            super.onBackPressed();
        } else if (viewPager.getCurrentItem() > startPosition)
        {
            viewPager.setCurrentItem(viewPager.getCurrentItem() - 1);
        } else if (viewPager.getCurrentItem() < startPosition)
        {
            viewPager.setCurrentItem(viewPager.getCurrentItem() + 1);
        }
    }

    private class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter
    {
        public ScreenSlidePagerAdapter(FragmentManager fm){super(fm);}

        @Override
        public Fragment getItem(int position)
        {
            Fragment fragment = new ImagePageFragment();

            Bundle args = new Bundle();
            args.putString("imagePath", imagePaths.get(position));

            fragment.setArguments(args);
            return fragment;
        }

        @Override
        public int getCount()
        {
            return pages;
        }
    }
}

Solution

  • Don't make WebManagerArticle a singleton and also don't just make its fields static because they will share the state of the last Fragment initialized. When the ViewPager creates the first page fragment the WebManagerArticle will be created along with the proper id. When the second page fragment is constructed the WebManagerArticle is already built and setting the fields on it will override the previous data stored for the first fragment. And the same happens for the last fragment, that's why you get the only the id for the third fragment.