Fragment getView() always returning null for Fragments created by a FragmentStatePagerAdapter

Notbad picture Notbad · Feb 9, 2013 · Viewed 14.9k times · Source

I have been reading a lot about fragments. Have found other people having problems retrieving fragments view because null was always returned but no answer solved my problem. What I'm trying to do is create a image gallery. I have a Fragment that holds a image view. To show the fragments I use a android.support.v4.view.ViewPager. And to feed the ViewPager I use a android.support.v4.app.FragmentStatePagerAdapter.

The problem is that when everything is build and the images are shown I want to save the current shown image to disk. So I need to get the current fragment imageview but I can't because fragment.getView() always is null, the activity associated with the fragment is null too and I can't figure out why is it. Here some code to see if anyone could help here:

This is my Fragment:

public class ImageViewURLFragment extends Fragment 
{
    String _url;

    @Override
    public View onCreateView(LayoutInflater inflater,
            ViewGroup container, Bundle savedInstanceState) 
    {
        // The last two arguments ensure LayoutParams are inflated
        // properly.
        View rootView = new ImageViewURL(getActivity(), _url);

        return rootView;
    }

    public void setImageURL(String imgURL)
    {
        _url=imgURL;
    }
}

And this my adapter:

public class ImageViewURLCustomAdapter extends FragmentStatePagerAdapter 
{
    List<String> _urls=new ArrayList<String>();

    public ImageViewURLCustomAdapter(FragmentManager fm) 
    {
        super(fm);
    }

    @Override
    public Fragment getItem(int i) 
    {
        ImageViewURLFragment fragment = new ImageViewURLFragment();
        fragment.setImageURL(_urls.get(i));

        return fragment;
    }

    public String getItemUrl(int i)
    {
        return _urls.get(i);
    }

    @Override
    public int getCount() {
        return _urls.size();
    }

    @Override
    public CharSequence getPageTitle(int position) {
        return "OBJECT " + (position + 1);
    }

    public void addImageURL(String url)
    {
        _urls.add(url);
    }
}

And this is the main activity, notice the comment with the get:

public class MainActivity extends FragmentActivity 
{
    ImageViewURLCustomAdapter _iva=null;
    ViewPager _vp=null;

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

        _iva = new ImageViewURLCustomAdapter(
                        getSupportFragmentManager());
        _iva.addImageURL("http://upload.wikimedia.org/wikipedia/commons/b/b4/Saturn_(planet)_large.jpg");
        _iva.addImageURL("http://planetthreesixty.com/sites/default/files/planet.jpg");

        _vp = (ViewPager) findViewById(R.id.viewpager);
        _vp.setAdapter(_iva);
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) 
    {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) 
    {
        if(item.getItemId()==R.id.saveToSD)
        {
            int index= _vp.getCurrentItem();
            Fragment fragment=_iva.getItem(index);

            //THis is where I need to get fragment view, but always returns null
                    View view= fragment.getView();
            ImageView iv=(ImageView)view.findViewWithTag("imageView");
            Bitmap bmp=iv.getDrawingCache();


        }


        return super.onOptionsItemSelected(item);
    }
}

Sorry for the long sources, I have cleaned everything I could, but I wanted to present all playing parts. Could anybody guess what is hapenning?

Thanks in advance.

Answer

user picture user · Feb 9, 2013

So I need to get the current fragment imageview but I can't because fragment.getView() always is null, the activity associated with the fragment is null too and I can't figure out why is it.

That is happening because you're expecting _iva.getItem(index); to return the Fragment that the ViewPager uses for the page corresponding to the specified index. That will not happen as the ViewPager has already called the getItem method to get the fragments it needs and after your call the getItem method you get a new ImageViewURLFragment instance. This new instance isn't tied to the Activity(getActivity() returns null) and its view wasn't created.

As you use a FragmentStatePagerAdapter try the code below to get the currently visible Fragment:

if (item.getItemId()==R.id.saveToSD) {
     int index = _vp.getCurrentItem();
     Fragment fragment = _vp.getAdapter().instantiateItem(_vp, index);
     //...