ViewPager con Google Maps API v2: mysterious black view


He integrado el nuevo fragmento de la api v2 de Google maps en un buscapersonas de vista. Al desplazarse desde el fragmento del mapa, una vista negra se superpone a los fragmentos adyacentes. ¿Alguien lo ha resuelto?

Editar: captura de pantalla

introduzca la descripción de la imagen aquí

public static class PagerAdapter extends FragmentPagerAdapter{

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

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

    @Override
    public Fragment getItem(int position) {

        Fragment pageFragment;

        switch (position) {
        case 0:
            pageFragment = new TabAFragment();
            break;

        case 1:
            pageFragment = new TabBFragment();
            break;

        case 2:
            pageFragment = SupportMapFragment.newInstance();
            break;

        default:
            pageFragment = null;
            break;
        }

        return pageFragment;
    }
}
Author: Pepe, 2012-12-12

9 answers

Pude evitar que la superficie negra se quedara atrás después de la transición colocando otra vista con un fondo transparente en la parte superior del ViewPager dentro de un FrameLayout:

<FrameLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <android.support.v4.view.ViewPager
        android:id="@+id/fragment_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
    </android.support.v4.view.ViewPager>

    <!-- hack to fix ugly black artefact with maps v2 -->
    <FrameLayout 
        android:layout_width="match_parent"
        android:layout_height="match_parent" 
        android:background="@android:color/transparent" />

</FrameLayout>
 113
Author: Jeff Gilfelt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-12-17 08:04:25

Tuvo el mismo problema con SlidingMenu y ViewPager. Noté que los botones de control en map fragment no son negros en el artefacto left behind. Resolví el problema anulando el método onCreateView() de MapFragment (SupportMapFragment)

@Override
public View onCreateView(LayoutInflater inflater, 
                         ViewGroup view, 
                         Bundle savedInstance) {

    View layout = super.onCreateView(inflater, view, savedInstance);
    FrameLayout frameLayout = new FrameLayout(getActivity());
    frameLayout.setBackgroundColor(
        getResources().getColor(android.R.color.transparent));
    ((ViewGroup) layout).addView(frameLayout,
        new ViewGroup.LayoutParams(
            LayoutParams.FILL_PARENT, 
            LayoutParams.FILL_PARENT
        )
    );
    return layout;
}
 43
Author: Lubos Horacek,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-11-07 17:55:32

Google lanzó una solución para esto, pero solo para 4.1+ (No es necesario descargar una nueva versión de PlayServices, usaron una bandera del lado del servidor)

Esto es lo que estoy usando para evitar el problema: garantiza que no desperdicie ningún ciclo de CPU en dispositivos > = 4.1

public class FixMapFragment extends SupportMapFragment {

    @Override
    public View onCreateView(LayoutInflater inflater, 
                             ViewGroup container, 
                             Bundle savedInstanceState) {

        View view = super.onCreateView(inflater, container, savedInstanceState);

        // Fix for black background on devices < 4.1
        if (android.os.Build.VERSION.SDK_INT < 
            android.os.Build.VERSION_CODES.JELLY_BEAN) {
            setMapTransparent((ViewGroup) view);
        }
        return view;
    }

    private void setMapTransparent(ViewGroup group) {
        int childCount = group.getChildCount();
        for (int i = 0; i < childCount; i++) {
            View child = group.getChildAt(i);
            if (child instanceof ViewGroup) {
                setMapTransparent((ViewGroup) child);
            } else if (child instanceof SurfaceView) {
                child.setBackgroundColor(0x00000000);
            }
        }
    }
}
 7
Author: Tspoon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-11-07 17:59:32

Mi solución: hacer uso de la nueva interfaz de instantáneas desde GoogleMap y mostrar una instantánea del mapa mientras se desplaza por la página.

Aquí está mi código para configurar la instantánea (está en el mismo fragmento que map, llamado FragmentMap.java):

public void setSnapshot(int visibility) {
    switch(visibility) {
    case View.GONE:
        if(mapFragment.getView().getVisibility() == View.VISIBLE) {
            getMap().snapshot(new SnapshotReadyCallback() {
                @Override
                public void onSnapshotReady(Bitmap arg0) {
                    iv.setImageBitmap(arg0);
                }
            });
            iv.setVisibility(View.VISIBLE);
            mapFragment.getView().setVisibility(View.GONE);
        }
        break;
    case View.VISIBLE:
        if(mapFragment.getView().getVisibility() == View.GONE) {
            mapFragment.getView().setVisibility(View.VISIBLE);
            iv.setVisibility(View.GONE);
        }
        break;
    }
}

Donde "MapFragment" es mi SupportedMapFragment y "iv" es una ImageView (hágalo match_parent).

Y aquí estoy controlando el pergamino:

pager.setOnPageChangeListener(new OnPageChangeListener() {
        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
            if(position == 0 && positionOffsetPixels > 0 || position == 1 && positionOffsetPixels > 0) {
                ((FragmentMap)adapter.getRegisteredFragment(1)).setSnapshot(View.GONE);
            } else if(position == 1 && positionOffsetPixels == 0) {
                ((FragmentMap)adapter.getRegisteredFragment(1)).setSnapshot(View.VISIBLE);
            }
        }
        @Override
        public void onPageScrollStateChanged(int arg0) {}
        @Override
        public void onPageSelected(int arg0) {}
    });

Mi fragmento con mapa (FragmentMap) está en la posición 1, así que necesidad de controlar el desplazamiento de la posición 0 a 1 y de la posición 1 a 2 (la primera cláusula if). "getRegisteredFragment () "es una función en mi FragmentPagerAdapter personalizado, en el que tengo un SparseArray (Fragmento) llamado"registeredFragments".

Así que, cada vez que te desplazas hacia o desde tu mapa, siempre ves una instantánea de él. Esto funciona muy bien para mí.

 6
Author: Namenlos,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-08-14 11:14:05

Tuve el mismo problema de pantalla negra en el desplazamiento de la vista de lista, estaba usando fragmento de mapa con vista de lista en la misma pantalla he resuelto este problema con el uso de la propiedad mágica en xml donde estoy hablando de vista de lista solo tenemos que poner android:scrollingCache="false". mi problema se ha solucionado pruebe esta propiedad para detener el retraso y el parpadeo en sus mapas.

 4
Author: Priyank Bhojak,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-04-22 09:48:50

No has dado muchos detalles, así que solo hay tanto que puedo sugerir. Tuve un problema similar que la pantalla parpadeaba entre las vistas en el buscapersonas. Resultó ser que el MapView se inflaba al intercambiar entre páginas la primera vez.

Para ser claros, tenía 3 páginas en mi buscapersonas y mi mapa era la última página.

Para resolver esto encontré que establecer el número de páginas fuera de pantalla a 2 (esto funcionó en el caso anterior) que cuando mi fragmento comenzó cargó todas las vistas en una vez.

Véase http://developer.android.com/reference/android/support/v4/view/ViewPager.html#setOffscreenPageLimit (int)

 2
Author: Graham Smith,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-12-23 05:21:21

Hay una solución más a este problema. Estoy mostrando MapFragment dentro de otro fragmento. El MapFragment se añade dinámicamente al FrameLayout.

La solución es usar FrameLayout.setVisibility (View.Visible) y FrameLayout.setVisibility (View.Gone) en abrir y cerrar eventos de menú deslizante. Dosent requiere una vista adicional para ser añadido. Y el área negra ha desaparecido por completo.

getSlidingMenu().setOnOpenListener(
        new OnOpenListener() {
            @Override
            public void onOpen() {
                frameLayout.setVisibility(View.GONE);
            }
        });

getSlidingMenu().setOnClosedListener(
        new OnClosedListener() {

            @Override
            public void onClosed() {
                frameLayout.setVisibility(View.VISIBLE);
            }
        });
 0
Author: JehandadK,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-03-02 09:17:47

Ninguno de los métodos anteriores funcionó para mí, ni siquiera otros que he encontrado en otros lugares. Finalmente, elegí una solución parcial. Escucho los cambios de página a través del OnPageChangeListener de ViewPager, y oculto el mapa cuando su página comienza a desplazarse, y del mismo modo lo muestro de nuevo cuando deja de desplazarse. También he añadido una vista blanca que se mostrará al desplazarse.

 0
Author: azyoot,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-05-29 22:32:18

Simplemente copia mi fragmento de mapa personalizado a tu proyecto. Y si tienes líneas negras con ScrollView en la parte superior e inferior configuradas para tu android ScrollView:fadingEdge = "none"

public class CustomMapFragment extends SupportMapFragment {
private OnActivityCreatedListener onActivityCreatedListener;

public CustomMapFragment() {
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup view, Bundle savedInstance) {
    View layout = super.onCreateView(inflater, view, savedInstance);

    FrameLayout frameLayout = new FrameLayout(getActivity());
    frameLayout.setBackgroundColor(getResources().getColor(android.R.color.transparent));
    ((ViewGroup) layout).addView(frameLayout,
            new ViewGroup.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
    return layout;
}

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    if (getOnActivityCreatedListener() != null)
        getOnActivityCreatedListener().onCreated();
}

public OnActivityCreatedListener getOnActivityCreatedListener() {
    return onActivityCreatedListener;
}

public void setOnActivityCreatedListener(
        OnActivityCreatedListener onActivityCreatedListener) {
    this.onActivityCreatedListener = onActivityCreatedListener;
}

public interface OnActivityCreatedListener {
    void onCreated();
}

}

 -2
Author: user2728452,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-09-27 07:06:37