54 votes

Le déplacement de MapFragment (SurfaceView) provoque le scintillement de l'arrière-plan noir

Je suis en train de mettre en œuvre de nouveaux Android de Google Maps API (v2). Toutefois, il ne semble pas aller bien avec SlidingMenu. Comme vous le savez, MapFragment mise en œuvre est basée sur SurfaceView. Le problème est que l' SurfaceView n'est pas comme le déplacer - je veux dire de le placer dans les points de vue:

Lorsque vous le déplacez, il laisse un trou noir dans le lieu de ses pixels à l'origine portées. Il ressemble à quelque chose comme cela.

Ce problème peut être partiellement résolu par la spécification d'un arrière-plan transparent sur l' SurfaceView ou même le fait de placer une transparence View - dessus d'elle. Je ne peux pas comprendre si c'est seulement pour moi les résultats sont inacceptables, ou si j'ai un problème différent qui lui donne une apparence à quoi il ressemble.

Pour voir à quoi il ressemble, s'il vous plaît regarder CETTE VIDÉO.

(désolé pour la qualité, mais le problème peut être vu facilement de toute façon)

Lorsqu'un normal listview (l'orange de l'écran) est retiré lors de l'ouverture d' SlidingMenu, l'animation est fluide et agréable. Mais dès que l' MapFragment s'affiche, il y a un peu bizarre rafraîchissant/scintillement/problème de synchronisation sur la carte.

Testé sur HTC One S et le Samsung Galaxy ACE.


Mon super-duper-idée folle de le résoudre: à chaque fois que l'animation d'ouverture commence, prendre une capture d'écran de l' MapFragment (il devrait être possible avec SurfaceView) et le poser sur la durée de l'animation. Mais je ne sais vraiment pas comment faire... La prise de capture d'écran d'une carte n'est pas possible, mais peut-être que quelqu'un aura inspiré.

Ou peut-être désactiver redessiner la carte d'une autre manière, je ne sais pas.


Mise à JOUR:

Trouvé cette.

Il semble que SurfaceView peut être modifié à TextureView pour supprimer ces restrictions. Mais depuis MapFragment est basé sur SurfaceView, je ne sais pas si elle peut être réalisée.

Une autre mise à jour Il semble que ce problème a été résolu sur les périphériques 4.1+. Ils ont juste utilisé TextureView. mais sur les versions antérieures, nous avons encore à utiliser des solutions de contournement.

14voto

Daniel Schuler Points 952

Bien sûr, la bonne solution sera de Google pour résoudre le problème (voir Android Maps V2 question 4639: http://code.google.com/p/gmaps-api-issues/issues/detail?id=4639).

Cependant, un de mes collègues de travail a suggéré une simple extension de la carte au-delà de son conteneur. Si nous prolongeons le fragment de carte au-delà de la région visible de son conteneur, comme suit:

android:layout_marginLeft="-40dp"
android:layout_marginRight="-40dp"

nous pouvons réduire/éliminer le scintillement. Les appareils récents (par exemple, le Galaxy Nexus) montrent pas de scintillement après ce hack, et les appareils plus anciens (par exemple LG Optimus V) réduire le scintillement. Nous devons étendre les marges sur les deux côtés de sorte que les fenêtres d'informations sont centrées quand ils sont sélectionnés.


Mise à jour: Ce problème a été résolu par Google sur Août. 28, mais j'imagine qu'il doit être encore roulée dans un communiqué.

6voto

Erick Martinez Points 101

Vous pouvez utiliser cette bibliothèque

https://github.com/NyxDigital/NiceSupportMapFragment/

cela fonctionne bien pour moi.

4voto

Ryan Points 1188

Voici une idée folle, ne déplacez pas le MapView ;-)

C'est-à-dire, créez une largeur plein écran MapView derrière votre application dans un FrameLayout. Placez ensuite vos vues en haut et faites un trou dans MapView dans la position que vous souhaitez afficher. Lorsque vous vous déplacez, vous devez mettre à jour la position de la carte pour rester synchronisé afin que l'utilisateur puisse voir la même section de la carte, mais cette mise à jour devrait être améliorée par rapport au déplacement d'une vue de surface.

3voto

Ben Max Rubinstein Points 1512

Eh bien, Citant Dianne Hackborn (un Androïde cadre de l'ingénieur)

La surface d'affichage est en fait DERRIÈRE votre fenêtre, et un trou percé dans la fenêtre pour que vous puissiez le voir. Vous pouvez mettre les choses sur le dessus de votre fenêtre, mais rien dans votre fenêtre peut apparaître derrière elle. Post Original

Cette architecture est en partie pourquoi vous voyez ces scintille.

Un scintillement parfois apparaissent en raison de la double tampons: Android codage blog explique plus loin.

Vous pouvez également essayer et sous-classe de l' SurfaceView de l'essayer et de dessiner l'arrière-plan de manière différente. Je n'ai pas vu un exemple de ce qui ne change pas le z-index pour que de la haut. Découvrez ce DONC, après les

Sinon, je recommande seulement obtenir l' SurfaceHolder après votre point de vue est centré (essayer de le faire d'une situation temporaire jusqu'alors) et la suppression de la SurfaceView , tandis que pas au point et à l'écran.

2voto

Breeno Points 81

Dans mon scénario, j'ai eu un premier Fragment, ce qui d'un clic sur un bouton échangé dans un deuxième fragment avec un MapFragment à l'intérieur. J'ai remarqué que ce scintillement, ne s'est produite la première fois que vous échangez le fragment - popping la pile de retour, et d'échanger dans un autre fragment du même type n'a pas de provoquer un scintillement.

Donc, pensant qu'il avait quelque chose à voir avec l'ajout d'un premier SurfaceView à la fenêtre, j'ai essayé d'ajouter un vide instance d'une SurfaceView à mon chargés initialement fragment, derrière c'est la vue principale. Et bingo, plus de scintillement lors de l'animation dans le fragment suivant!

Je sais que c'est pas la solution la plus propre, mais ça fonctionne. Le Google MapFragment (ou SupportMapFragment dans mon cas) fonctionne toujours très bien, comme le solde non utilisé SurfaceView est dans le fragment précédent.

Je dois ajouter que je suis à l'aide de l'API v2.

Mise À Jour @VenomVendor

J'ai ajouter le vide SurfaceView pour le premier fragment d'être montré, à l'indice 0 - behind de la vue principale. Dans mon cas, la Maison fragment est le fragment précédent à celui qui contient les Cartes Google maps fragment, ne sais pas si ce qui compte:

import android.view.SurfaceHolder;
import android.view.SurfaceView;

public class HomeFragment extends FragmentBase {
private SurfaceView sview;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_home, container, false);

    //this fixes google maps surface view black screen animation issue
    sview = new SurfaceView(getActivity());
    sview.setZOrderOnTop(true);    // necessary
    SurfaceHolder holder = sview.getHolder();
    holder.setFormat(PixelFormat.TRANSPARENT);

    container.addView(sview, 0);
    ...
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X