Cambio de la imagen de fondo del fragmento actual en viewpager

Tengo 4 fragmentos en un viewpager. Y FragmentStatePagerAdapter dentro de la actividad donde está mi viewpager. El método newInstance () de FragmentStatePagerAdapter toma como ID de diseño de parámetros, por lo que cada fragmento tiene su propio diseño:

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

Aquí está 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; } } 

Y 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> 

y uno de los parámetros 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" > 

// algunas otras vistas de niños

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

// algunas otras vistas de niños

 </RelativeLayout> 

Ahora, en algún momento de mi programa, quiero cambiar la imagen de fondo del diseño del fragmento actual. Y traté de hacerlo así:

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

Pero la línea " ((BitmapDrawable)page.getView().getBackground()).getBitmap().recycle(); " devuelve NullPointerException porque page.getView().getBackground() es null. ¿Qué estoy haciendo mal o cómo puedo cambiar la imagen de fondo? PS por alguna razón el tipo page.getView () es NoSaveStateFrameLayout, no RelativeLayout como uno esperaría

Solución:–

en realidad su problema es que está reciclando bitmap es decir, que está liberando ese mapa de bits y los datos de píxeles así, obviamente obtendrá el nulo.!

Ya se menciona en los documentos api de Android: – introduzca la descripción de la imagen aquí

Sólo tienes que hacer esto:

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

Funciona entonces .. Disfrute ..!

En primer lugar, no guarde una lista de fragmentos en su adaptador. Los adaptadores de buscapersonas deben ser servidos con datos a través de un método personalizado y luego su getItem() debe usarlo para crear Fragmentos. En lugar de aleatorizar los diseños en getItem() hacerlo en su lista de artículos (ver código a continuación) antes de pasarlo al adaptador. No anule el destroyItem() initialiseItem() o destroyItem() . Además, no tiene que mantener referencia a FragmentManager . Puede implementar su adaptador de esta manera:

Cree una clase personalizada que contenga sus datos.

 public class MyItem { private int layout; private int bitmap; public MyItem(layout, bitmap) { this.layout = layout; this.bitmap = bitmap; } //implement getters and setters } 

Siguiente implementar adaptador como este:

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

Luego, en el método getItem() , inicializa los fragmentos basados ​​en esos datos. A continuación, cree el método para actualizar los elementos que está actualizando la posición proporcionada y, a continuación, invalidar el adaptador. No olvide implementar getItemPosition() , hace que ViewPager invalide todos los elementos, también aquellos que ya están creados.

Por último, puede actualizarlo en su actividad de la siguiente manera:

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

La implementación de su fragmento se vería así:

 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; } } 
  • Cómo agregar la página dinámicamente en FragmentStatePagerAdapter
  • Android FragmentStatePagerAdapter devuelve pantalla en blanco al recargar fragmentos de medio
  • FragmentStatePagerAdapter fuga de memoria (fragmentos anidados con viewpager)
  • Diferencia entre FragmentPagerAdapter y FragmentStatePagerAdapter
  • ViewPager + FragmentStatePageAdapter: ¿qué significa esta advertencia "no actualizada en línea"?
  • Guardar / Actualizar los datos de EditText del fragmento en un FragmentStatePagerAdapter
  • Destruye el elemento del adaptador de ViewPager después de cambiar la orientación de la pantalla
  • Desplazamiento Dirección en ViewPager
  • Quitar todos los fragmentos de ViewPager poblados por FragmentStatePagerAdapter
  • Android: intenta invocar el método virtual 'void android.support.v4.app.Fragment.setMenuVisibility (boolean)' en una referencia de objeto nulo
  • Fragmento getView () siempre devuelve null para Fragments creado por un FragmentStatePagerAdapter
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.