FragmentStatePagerAdapter创建的Fragment中,Fragment getView()方法总是返回null

9
我一直在阅读关于Fragment的内容。发现其他人遇到了检索Fragment视图时返回null的问题,但没有答案可以解决我的问题。我想要做的是创建一个图片库。我有一个包含图片视图的Fragment。为了显示这些Fragment,我使用了一个android.support.v4.view.ViewPager。而为了提供ViewPager,我使用了一个android.support.v4.app.FragmentStatePagerAdapter。
问题在于,当所有东西都构建好并且图片被显示时,我想要将当前显示的图片保存到磁盘上。所以我需要获取当前Fragment的ImageView,但我无法获取它,因为fragment.getView()总是返回null,与Fragment相关联的Activity也为null,我无法弄清楚为什么会这样。以下是一些代码,看看是否有人能够帮助:
这是我的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;
    }
}

这是我的适配器:

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);
    }
}

这是主要活动,注意带有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);
    }
}

抱歉这里的内容有些冗长,我已经尽可能清理了一切,但我想呈现所有的播放部分。有人能猜出正在发生什么吗?

提前感谢。

1个回答

32

我需要获取当前片段的ImageView,但无法获取,因为fragment.getView()总是为空,与片段相关联的Activity也为空,我无法弄清原因。

这是因为你期望_iva.getItem(index);返回ViewPager用于指定索引对应页面的Fragment。这不会发生,因为ViewPager已经调用了getItem方法获取所需的片段,在你的调用之后,你得到一个新的ImageViewURLFragment实例,该实例与Activity未关联(getActivity()返回null),且其视图尚未创建。

由于您使用了FragmentStatePagerAdapter,请尝试使用以下代码以获取当前可见的Fragment

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

在搜索了一些更多的信息后,我想问一下你是怎么得到这个关于instantiateItem的信息的。我的意思是,我已经读到过这个适配器可以重用片段而不是每次创建一个新的,但是你在哪里找到的信息表明我们可以直接调用instantiateItem并且它会返回一个先前的片段实例而不是一个新的呢?另一方面,你如何为PageView获取当前项?谢谢。 - Notbad
1
@Notbad,如果你看一下FragmentStatePagerAdapter的源代码,你会发现instantiateItem方法要么返回一个缓存的Fragment,要么返回一个新的Fragment。当你正在查找当前Fragment时,它将是缓存版本。而另一方面,你如何在PageView中实现这个(获取当前项目)?我不明白你在问什么。要从FragmentStatePagerAdapter中获取当前的Fragment,你可以使用我在答案中提供的代码。 - user
好的,谢谢。我认为阅读Android源代码是这种事情的常见做法。再次感谢您的回答。 - Notbad
3
太好了!谢谢您提供我一行代码,这正是我一直在寻找的。Fragment fragment = _vp.getAdapter().instantiateItem(_vp, index);(注:该行代码为Java代码,意为获取ViewPager控件中指定index位置对应的Fragment对象) - thandasoru
1
运行良好,甚至超出了这个问题的范围。👍 - Shark
谢谢!我花了一整天的时间找错了,我不知道getItem()会返回一个新的片段实例。愉快编码! - Mikhail Valuyskiy

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