我在viewpager中有4个片段。和我的viewpager所在的活动里面的FragmentStatePagerAdapter。 FragmentStatePagerAdapter的newInstance()方法作为参数布局id,因此每个片段都有自己的布局:
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:
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:
<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:
<?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" >
//其他一些子视图
<ImageView
android:id="@+id/zoomed_image"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:visibility="gone"/>
//其他一些子视图
</RelativeLayout>
现在在我的程序的某个时刻,我想改变当前片段布局的背景图像。我试图这样做:
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().recycle();
”行返回NullPointerException,因为page.getView().getBackground()
为空。我做错了什么或如何更改背景图片?
附:由于某种原因,page.getView()的类型是NoSaveStateFrameLayout,而不是人们期望的RelativeLayout
答案 0 :(得分:0)
实际上你的问题是你正在回收位图,即你正在释放那个位图和像素数据,所以,显然你会得到null。!
在android api文件中已经提到过: -
你只需要这样做: -
int i = pager.getCurrentItem();
Fragment page = ((MyPagerAdapter)pager.getAdapter()).getRegisteredFragment(i);
Bitmap bitmapNeedTobeRecycled = ((BitmapDrawable)page.getView().getBackground()).getBitmap()
page.getView().setBackgroundResource(R.drawable.wall3_nopaperball);
bitmapNeedTobeRecycled.recycle();
然后工作..享受..!
答案 1 :(得分:0)
首先,不要在适配器中保留片段列表。寻呼机适配器应通过自定义方法提供数据,然后您的getItem()
应使用它来创建碎片。而是在getItem()
中随机化布局,然后在将其传递给适配器之前在项目列表上执行此操作(请参阅下面的代码)。请勿覆盖initialiseItem()
或destroyItem()
。此外,您不必继续引用FragmentManager
。您可以像这样实现您的适配器:
创建自定义类以保存数据。
public class MyItem {
private int layout;
private int bitmap;
public MyItem(layout, bitmap) {
this.layout = layout;
this.bitmap = bitmap;
}
//implement getters and setters
}
接下来实现这样的适配器:
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使所有项目无效,也包括已经创建的项目。
最后,您可以在活动中更新它:
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;
}
}