Google Maps API v2 ile ViewPager: gizemli siyah görünüm


95

Yeni google maps api v2 parçasını bir görünüm çağrı cihazına entegre ettim. Harita parçasından kaydırırken, siyah bir görünüm bitişik parçaların üzerine gelir. Birisi çözdü mü?

Düzenleme: ekran görüntüsü

görüntü açıklamasını buraya girin

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

Birden fazla cihaz mı oluyor? Belki ViewPager'dan birkaç kod satırı ve harita uygulaması sorununuzu daha iyi anlamanıza yardımcı olabilir.
Adinia

Evet, denediğim tüm cihazlarda oluyor: samsung, htc, android 4.0, 2.3, vb. Haritayı uygulamama ve aynı sonucu yalnızca çağrı cihazı ve haritayla temiz bir küçük uygulamaya entegre ettim.
Pepe

@Pepe, GoogleMapden nasıl nesne alırsın ViewPager? Haftalarca buna takılıp kaldım. Soruyu iyi anlamadıysanız, soruma bakın, yazımı bulacaksınız. Lütfen cevap verin.
azizbekian

Bunu yaparken bir screen recordsorun yaşanmıyor gibi göründüğünü eklemek istiyorum .
theblang

Yanıtlar:


115

İçerinin üstüne şeffaf bir arka plana sahip başka bir görünüm yerleştirerek geçişten sonra siyah yüzeyin geride kalmasını durdurabildim ViewPagera 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>

1
Harika! Mükemmel değildir, çünkü bazen çağrı cihazı hareket ederken siyah görüntünün bir parçası olarak görünür. Ama artık ekranda kalmıyor. Teşekkürler! (bu hack için herhangi bir açıklamanız var mı?)
Pepe

7
Pek sayılmaz. Yakınlaştırma ve konum kontrollerinin harita yüzeyinin üst kısmında nerede oturduğunu fark ettim, siyah iz görünmedi, bu yüzden tüm haritayı kapsayacak şekilde üste bir görünüm yerleştirdim ve işe yaradı. Mükemmel olmadığını kabul ediyorum - siyah arka plan GLSurfaceView penceresinin bir parçası gibi görünüyor code.google.com/p/gmaps-api-issues/issues/detail?id=4639
Jeff Gilfelt

5
ViewPager sorunumu çözmüş gibi görünüyor. Teşekkürler, ama benzer bir sorunum var gibi görünüyor SlideMenu (G + / Yahoo gibi sol menü), aynı şeyi yapıyor .. Bir SlideMenu uygulamasını düzeltme konusunda herhangi bir fikriniz var mı?
Chrispix

@Chrispix kapsayıcıyı canlandırmayın, animasyonu sadece yan menüde kullanın, benim için düzeltti.
meh

1
Bunu ve aşağıdaki programatik çözümü yaptım, uygulama ön
plandayken

43

SlidingMenu ve ViewPager ile aynı sorunu yaşadım. Harita parçasındaki kontrol düğmelerinin artefaktın solunda siyah olmadığını fark ettim. onCreateView()Yöntemini geçersiz kılarak sorunu çözdümMapFragment (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;
}

SlidingMenu için de kullanıyorum. Ama titreyen bir sorun var (kayan animasyonla) ve bu kabul edilemez, berbat görünüyor. Sende var mı HTC One S üzerinde test ettim. İlginç olan, bu sorunu yalnızca açılış animasyonuyla yaşıyorum, SlidingMenu'yu kapatırken değil
Michał K

Düzeltmelerin hiçbiri benim için işe yaramadı. Hemen hemen Michal K ile aynı sorunu yaşıyorum. SlidingMenu kullanarak ve sürekli bir hızda yavaşça açıp kapatıyorum ve sorun yok. Pencereyi kapatmak için fırlatıp açın veya geri bastırın ve harita, haritanın uygun konumuna döndüğü yerde slayt bitene kadar boş bir alan bırakarak biraz geride kalmış gibi görünür.
qubz

@qubz: 'Kayan menü' hakkında haritayı değil menüyü canlandırmayı deneyin. Harita hareket etmiyorsa benim için sorunu çözdü.
meh

@meh: SlidingMenu'yu açarken / kapatırken harita hareket ediyor olabilir. Taşınarak CameraUpdate'i kastediyorum. UX'i engelleyecek olsa da animasyonu duraklatıp duraklatamayacağımı göreceğim.
qubz

@Lubos Horacek: Lütfen bir örnek kod gönderebilir misiniz? Boş işaretçi istisnası hatası alıyorum ..
avinash

7

Google bunun için bir düzeltme yayınladı, ancak yalnızca 4.1+ (PlayServices'in yeni bir sürümünü indirmenize gerek yok, bir sunucu tarafı işareti kullandılar)

Sorunu atlamak için kullandığım şey şu - Cihazlarda herhangi bir CPU döngüsünü boşa harcamamanızı sağlar> = 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);
            }
        }
    }
}

: Sana şöyle sınıfına atıfta tahmin FixMapFragment mapFragment = (FixMapFragment) fragmentManager.findFragmentById(R.id.map);ve düzeni dosyasında: <fragment android:id="@+id/map" android:name="com.example.fragments.FixMapFragment" .... Yine de harita anlayabildiğim kadarıyla titriyor (Android 4.0.4).
JJD

@JJD Titreyen bir harita görünümüm var, bunu çözmenin bir yolu var mı?
Rat-a-tat-a-tat Ratatouille

@ Rat-a-tat-a-tatRatatouille Bildiğim kadarıyla harita görünümünün titremesini önlemek için güvenilir bir çözüm yok.
JJD

Şimdilik yaptığım şeyin doğru olup olmadığını bilmiyorum ama işe yarıyor. Harita görünümü görünürlüğünü görünmez olarak ayarladım ve birkaç saniye sonra harita görünümlerinin görünürlüğünü tekrar görünür hale getirdim. titremeyi azaltır.
Rat-a-tat-a-tat Ratatouille

6

Çözümüm: GoogleMap'ten yeni anlık görüntü arayüzünü kullanın ve sayfayı kaydırırken haritanın anlık görüntüsünü görüntüleyin.

İşte anlık görüntüyü ayarlamak için kodum (bu, FragmentMap.java adı verilen haritayla aynı parçada):

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

Burada "mapFragment", SupportedMapFragment'ım ve "iv" bir ImageView'dur (bunu match_parent yapın).

Ve burada parşömeni kontrol ediyorum:

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

Haritalı parçam (FragmentMap) konum 1'de, bu nedenle kaydırmayı 0'dan 1'e ve 1'den 2'ye (ilk if cümlesi) kontrol etmem gerekiyor. "getRegisteredFragment ()", özel FragmentPagerAdapter ürünümdeki bir işlevdir ve burada "registeredFragments" adında bir SparseArray (Fragment) bulunur.

Böylece, haritanıza her kaydırdığınızda veya haritadan her zaman bir anlık görüntüsünü görürsünüz. Bu benim için çok iyi çalışıyor.


Diğer cevaplar benim için işe yaramadı - işe yarayan tek cevap bu. Teşekkürler!
alice_silver_man

4

Liste görünümünün kaydırılmasında aynı siyah ekran sorununu yaşadım, aynı ekranda liste görünümü ile harita parçasını kullanıyordum, bu sorunu xml'deki sihirli özelliğin kullanımıyla çözdüm ve burada konuştuğum liste görünümünde sadece android'i koymamız gerekiyor : scrollingCache = "false". sorunum çözüldü, haritalarınızda gecikme ve titremeyi durdurmak için bu özelliği deneyin.


2

Çok fazla ayrıntı vermediniz, bu yüzden önerebileceğim çok şey var. Çağrı cihazındaki görünümler arasında ekranın titremesine benzer bir sorun yaşadım. İlk kez sayfalar arasında geçiş yaparken şişen mapView olduğu ortaya çıktı.

Açık olmak gerekirse, çağrı cihazımda 3 sayfam vardı ve haritam son sayfaydı.

Bunu çözmek için, ekran dışı sayfaların sayısını 2'ye ayarlamanın (yukarıdaki durumda bu işe yaradı) parçam başladığında tüm görünümleri aynı anda yüklediğini buldum.

Bkz. Http://developer.android.com/reference/android/support/v4/view/ViewPager.html#setOffscreenPageLimit (int)


Teşekkürler ama işe yaramadı. Sorun, ekranın kapladığı bölümün, başka bir parçaya geçildiğinde, diğer parçanın görüntüsünü kaplayan siyah kalmasıdır.
Pepe

hmmm ilginç. Bunun üzerine bir düşüneceğim.
Graham Smith

SetOffscreenPageLimit'i o sayfada bulamıyorum yu bağlantı verdi
mplungjan

0

Bu soruna bir çözüm daha var. MapFragment'ı başka bir parça içinde gösteriyorum. MapFragment dinamik olarak FrameLayout'a eklenir.

Çözüm, kayan menünün açma ve kapama olaylarında frameLayout.setVisibility (View.Visible) ve frameLayout.setVisibility (View.Gone) kullanmaktır. Dozaj, ek bir görünüm gerektirir. Ve siyah alan tamamen yok oldu.

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

Yukarıdaki yöntemlerden hiçbiri benim için işe yaramadı, başka yerlerde bulduğum diğerleri bile. Son olarak kısmi bir çözüm seçtim. ViewPager'ın onPageChangeListener'ı aracılığıyla sayfa değişikliklerini dinliyorum ve sayfası kaymaya başladığında haritayı gizliyor ve aynı şekilde kaydırmayı bıraktığında tekrar gösteriyorum. Ayrıca kaydırırken görüntülenecek beyaz bir Görünüm ekledim.


Görünüm'ün geçerli görüntüsünü bir bit eşlem olarak yakalamak ve ardından çağrı cihazı kayarken bir ImageView'da görüntülemek için daha da genişletilebilir. Bu şekilde, kullanıcılar arkasındaki saldırıyı fark etmezler. Ancak, kullanıcı arayüzünün kaydırmaya tepkisini yavaşlatacağı için bu hesaplamayı biraz pahalı buldum.
azyoot

-2

Özel harita parçamı projenize kopyalamanız yeterli . Üstte ve altta ScrollView olan siyah çizgiler varsa, ScrollView android: fadingEdge = "yok"

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

}

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.