当前片段在viewpager不断变化的背景图片 [英] Changing background image of current fragment in viewpager

查看:116
本文介绍了当前片段在viewpager不断变化的背景图片的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个viewpager 4个片段。而FragmentStatePagerAdapter在我的viewpager是活动里面。 FragmentStatePagerAdapter的newInstance()方法的参数布局ID,因此每个片段都有它自己的布局:

I have 4 fragments in a viewpager. And FragmentStatePagerAdapter inside the activity where my viewpager is. FragmentStatePagerAdapter's newInstance() method takes as parameter layout id, therefore each fragment has it's own layout:

ViewPager pager;

public class MainActivity extends FragmentActivity{
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);     
        pager = (ViewPager) findViewById(R.id.viewPager);
        pager.setAdapter(new MyPagerAdapter(getSupportFragmentManager()));}

    private static class MyPagerAdapter extends FragmentStatePagerAdapter {
       FragmentManager fm;
       SparseArray<Fragment> registeredFragments = new SparseArray<Fragment>();

        public MyPagerAdapter(FragmentManager fm) {
            super(fm);
            this.fm = fm;
        }

        @Override
        public Fragment getItem(int pos) {
        if(pos!=0){
            pos = pos%4;
        }
            Fragment frag;
            switch(pos) {
            case 0: frag = FirstFragment.newInstance(R.layout.fire_room_wall1);
                    return frag;
            case 1: frag = FirstFragment.newInstance(R.layout.fire_room_wall2);
                    return frag;
            case 2: frag = FirstFragment.newInstance(R.layout.fire_room_wall3);
                    return frag;
            case 3: frag = FirstFragment.newInstance(R.layout.fire_room_wall3);
                    return frag;
            default: return FirstFragment.newInstance(R.layout.fire_room_wall1);
            }
        }

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

             @Override
                public Object instantiateItem(ViewGroup container, int position) {
                    Fragment fragment = (Fragment) super.instantiateItem(container, position);
                    registeredFragments.put(position, fragment);
                    return fragment;
                }

                @Override
                public void destroyItem(ViewGroup container, int position, Object object) {
                    registeredFragments.remove(position);
                    super.destroyItem(container, position, object);
                }

                public Fragment getRegisteredFragment(int position) {
                    return registeredFragments.get(position);
                }
    }
}

下面是FirstFragment:

Here is FirstFragment:

public class FirstFragment extends Fragment{

     @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            int layout = getArguments().getInt("layout");
            View v = inflater.inflate(layout, container, false);    
            return v;
        }

        public static FirstFragment newInstance(int layout) {

            FirstFragment f = new FirstFragment();
            Bundle b = new Bundle();
            b.putInt("layout", layout);
            f.setArguments(b);
            return f;
        }
}

和activity_main.xml:

And activity_main.xml:

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity" >
<FrameLayout android:layout_width="match_parent"
    android:layout_height="match_parent">
<android.support.v4.view.ViewPager
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/viewPager"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    />
<com.example.viewpagerfragement.CustomView android:id="@+id/customView"
        android:layout_width="fill_parent" android:layout_height="fill_parent" />
</FrameLayout>
</RelativeLayout>

和中的newInstance参数fire_room_wall1.xml之一:

and one of the newInstance parameters fire_room_wall1.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
     android:background="@drawable/wall_nobrainjar"
     android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:id="@+id/first" >

//一些其他的子视图

//some other child views

     <ImageView
        android:id="@+id/zoomed_image"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:visibility="gone"/>

//一些其他的子视图

//some other child views

</RelativeLayout>

现在我在程序某些时候,我想改变当前片段的布局的背景图像。我试图做这样的:

Now at some point in my program I want to change background image of the current fragment's layout. And I attempted to do it like this:

  int i = pager.getCurrentItem();
    Fragment page = ((MyPagerAdapter)pager.getAdapter()).getRegisteredFragment(i);
    ((BitmapDrawable)page.getView().getBackground()).getBitmap().recycle();
    page.getView().setBackgroundResource(R.drawable.wall3_nopaperball);

但行((BitmapDrawable)page.getView()的getBackground())。 getBitmap()循环(); 返回NullPointerException异常,因为 page.getView()的getBackground()为空。我做错了或者我如何改变背景图片? 附:出于某种原因page.getView()的类型NoSaveStateFrameLayout,不是RelativeLayout的作为一个希望

But the line "((BitmapDrawable)page.getView().getBackground()).getBitmap().recycle();" returns NullPointerException because page.getView().getBackground() is null. What I'm doing wrong or how can I change background image? P.S. for some reason page.getView()'s type is NoSaveStateFrameLayout, not RelativeLayout as one would expect

推荐答案

首先不保持片段的列表,您的适配器。寻呼机适配器应送达的数据通过自定义方法,然后你的的getItem()应该使用它来创建片段。在的getItem而是随机化布局()做你的项目清单(见下文code)如果您将它传递给适配器之前对。不要覆盖 initialiseItem() destroyItem()。你也不必继续参照 FragmentManager 。您可以实现这样的适配器:

First of all do not keep a list of fragments in your adapter. Pager adapters should be served with data through custom method and then your getItem() should use it to create Fragments. Instead randomising layouts in getItem() do it on your item list(see code below) before you pass it to adapter. Do not override initialiseItem() or destroyItem(). Also you do not have to keep reference to FragmentManager. You can implement your adapter like this:

创建自定义类来保存数据。

Create custom class to holds your data.

public class MyItem {
    private int layout;
    private int bitmap;

    public MyItem(layout, bitmap) {
        this.layout = layout;
        this.bitmap = bitmap;
    }

    //implement getters and setters
}

下实现这样的适配器:

Next implement adapter like this:

public static class MyPagerAdapter extends FragmentStatePagerAdapter {
    private List<MyItem> items = new ArrayList<MyItem>(0);

    public void setItems(List<MyItem> items) {
        this.items = items;
    }

    @Override
    public Fragment getItem(int pos) {
        MyItem item = items.get(pos);
        return FirstFragment.newInstance(item.getLayout(), item.getBitmap());
    }

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

    public void updateItemBitmap(int position, int bitmap) {
        MyItem myItem = items.get(position);
        myItem.setBitmap(bitmap);
        notifyDataSetChanged();
    }

    @Override
    public int getItemPosition(Object object) {
        return POSITION_NONE;
    }
}

然后在的getItem()方法,你初始化基于这些数据的片段。接下来的更新是更新提供的位置的项目创建方法,然后失效适配器。不要忘了执行 getItemPosition(),它使ViewPager将所有项目,也无效那些已经建立。

Then in getItem() method you initialise your fragments based on that data. Next create method for updating items which is updating provided position and then invalidate adapter. Don't forget to implement getItemPosition(), it makes ViewPager to invalidate all items, also those which are already created.

最后,你可以在这样的活动更新:

Finally, you can update it in your activity like this:

int i = pager.getCurrentItem();
((MyPagerAdapter)pager.getAdapter()).updateItemBitmap(i,R.drawable.wall3_nopaperball);

您片段实现是这样的:

public class FirstFragment extends Fragment{

     @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            int layout = getArguments().getInt("layout");
            int bitmap = getArguments().getInt("bitmap");
            View v = inflater.inflate(layout, container, false);
            v.setBackgroundResource(bitmap);    
            return v;
        }

        public static FirstFragment newInstance(int layout, int bitmap) {

            FirstFragment f = new FirstFragment();
            Bundle b = new Bundle();
            b.putInt("layout", layout);
            b.putInt("bitmap",bitmap);
            f.setArguments(b);
            return f;
        }
}

这篇关于当前片段在viewpager不断变化的背景图片的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆