Google Maps API v2가 포함 된 ViewPager : 신비한 블랙 뷰


95

새로운 Google지도 API v2 조각을 뷰 페이저에 통합했습니다. 지도 조각에서 스크롤하면 검은 색보기가 인접한 조각과 겹칩니다. 누군가 해결 했습니까?

편집 : 스크린 샷

여기에 이미지 설명 입력

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

둘 이상의 장치에서 발생합니까? ViewPager 및지도 구현의 코드 줄 몇 줄이 문제를 더 잘 이해하는 데 도움이 될 수 있습니다.
Adinia

예, 시도한 모든 장치에서 발생합니다 : samsung, htc, android 4.0, 2.3 등. 내 앱에지도를 통합했고 호출기와지도 만있는 깔끔한 작은 앱에 동일한 결과를 얻었습니다.
Pepe

@Pepe, 당신은 어떻게 GoogleMap물건 을 얻 ViewPager습니까? 몇 주 동안이 문제를 해결했습니다. 질문을 잘 이해하지 못했다면 내 질문을 찾으면 내 게시물을 찾을 수 있습니다. 답장 해주세요.
azizbekian

나는 screen record문제가 발생하지 않는 것처럼 보일 때 그것을 추가하고 싶습니다 .
theblang 2014-08-21

답변:


115

ViewPager내부 a 위에 투명한 배경이있는 다른 뷰를 배치하여 전환 후 검은 색 표면이 남겨지는 것을 막을 수있었습니다 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
큰! 때로는 페이저를 이동하는 동안 검은 색보기의 일부가 나타나기 때문에 완벽하지 않습니다. 그러나 이제는 더 이상 화면에 남아 있지 않습니다. 감사! (이 해킹에 대한 설명을해야합니까?)
페페

7
별로. 확대 / 축소 및 위치 컨트롤이지도 표면 상단에있는 위치에 검은 색 흔적이 나타나지 않았으므로지도 전체를 덮기 위해보기를 상단에 배치하고 작동했습니다. 완벽하지 않다는 데 동의합니다. 검정색 배경이 GLSurfaceView 창의 일부인 것 같습니다. code.google.com/p/gmaps-api-issues/issues/detail?id=4639
Jeff Gilfelt

5
내 ViewPager 문제를 해결 한 것 같습니다. 감사합니다.하지만 비슷한 문제가있는 것 같습니다. SlideMenu (G + / Yahoo와 같은 왼쪽 메뉴)와 같은 문제가있는 것 같습니다. 동일한 작업을 수행합니다. SlideMenu 구현을 수정하는 데 대해 어떤 생각이 있습니까?
Chrispix

@Chrispix는 컨테이너에 애니메이션을 적용하지 않고 사이드 메뉴에서만 애니메이션을 사용합니다.
meh

1
필자는이 작업과 아래의 프로그래밍 솔루션을 수행했지만 앱이 포 그라운드에있는 동안 작동하지만 앱이 닫혀 있고 계속 실행되고 다시 돌아갈 때지도가 여전히 상단에 유지됩니다.
L7ColWinters

43

SlidingMenu 및 ViewPager에서 동일한 문제가 발생했습니다. 지도 조각의 컨트롤 버튼이 왼쪽 아티팩트에서 검은 색이 아니라는 것을 알았습니다. onCreateView()방법을 재정 의하여 문제를 해결했습니다.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;
}

SlidingMenu에도 사용합니다. 그러나 나는 깜박임 문제 (슬라이딩 애니메이션)가 있으며 받아 들일 수 없으며 끔찍해 보입니다. 당신도 가지고 있습니까? HTC One S에서 테스트했습니다. 흥미로운 점은 SlidingMenu를 닫을 때가 아니라 오프닝 애니메이션에서만이 문제가 발생합니다
Michał K

어떤 수정도 나를 위해 일하지 않았습니다. 나는 Michal K와 실질적으로 동일한 문제가 있습니다. SlidingMenu를 사용하고 연속적인 속도로 천천히 열거 나 닫아도 문제가 없습니다. 창을 열거 나 뒤로 눌러 창을 닫으면지도가 적절한 위치로 돌아 오는 곳에서 슬라이드가 끝날 때까지 빈 공간을 남기고지도가 약간 지연되는 것처럼 보입니다.
qubz

@qubz : '슬라이딩 메뉴'에 대해지도가 아닌 메뉴를 애니메이션으로 만들어보세요. 지도가 움직이지 않는 경우 문제가 해결되었습니다.
meh

@meh : SlidingMenu를 열거 나 닫는 동안지도가 움직일 수 있습니다. 이동이란 CameraUpdate를 의미합니다. UX를 ​​방해 할 수 있지만 애니메이션을 일시 중지 할 수 있는지 살펴 보겠습니다.
qubz

@Lubos Horacek : 샘플 코드를 게시 해 주시겠습니까? Null 포인터 예외 오류가 발생합니다.
avinash

7

Google은 이에 대한 수정 사항을 발표했지만 4.1 이상에만 해당됩니다 (새 버전의 PlayServices를 다운로드 할 필요가 없으며 서버 측 플래그를 사용함).

문제를 우회하기 위해 제가 사용하는 방법은 다음과 같습니다. 4.1 이상인 기기에서 CPU주기를 낭비하지 않도록합니다.

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

다음과 같이 클래스를 참조 FixMapFragment mapFragment = (FixMapFragment) fragmentManager.findFragmentById(R.id.map);하고 레이아웃 파일에서 <fragment android:id="@+id/map" android:name="com.example.fragments.FixMapFragment" .... 하지만 내가 알 수있는 한지도는 여전히 깜박입니다 (Android 4.0.4).
JJD 2013

@JJD 깜박이는 mapview가 있습니다. 해결 방법이 있습니까?
Rat-a-tat-a-tat Ratatouille 2014 년

@ Rat-a-tat-a-tatRatatouille 내가 아는 한지도보기의 깜박임을 피할 수있는 확실한 해결 방법은 없습니다.
JJD

내가 지금 한 일이 올바른지 여부는 모르지만 작동합니다. 맵뷰 가시성을 보이지 않음으로 설정 한 다음 몇 초 후에 맵뷰 가시성을 다시 가시성으로 설정했습니다. 깜박임을 줄입니다.
Rat-a-tat-a-tat Ratatouille 2014 년

6

내 해결 방법 : GoogleMap 의 새 스냅 샷 인터페이스를 사용 하고 페이지를 스크롤하는 동안지도의 스냅 샷을 표시합니다.

다음은 스냅 샷을 설정하는 코드입니다 (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;
    }
}

여기서 "mapFragment"는 내 SupportedMapFragment이고 "iv"는 ImageView입니다 (match_parent로 만듭니다).

그리고 여기에서 스크롤을 제어합니다.

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

맵 (FragmentMap)이있는 조각이 위치 1에 있으므로 위치 0에서 1로, 위치 1에서 2로 스크롤을 제어해야합니다 (첫 번째 if 절). "getRegisteredFragment ()"는 사용자 정의 FragmentPagerAdapter에있는 함수로, "registeredFragments"라는 SparseArray (Fragment)가 있습니다.

따라서지도로 또는지도에서 스크롤 할 때마다 항상 스냅 샷이 표시됩니다. 이것은 나를 위해 아주 잘 작동합니다.


다른 답변은 저에게 효과가 없었습니다. 이것이 유일한 답변입니다. 감사!
alice_silver_man 2014-08-13

4

목록보기 스크롤시 검은 색 화면 문제가 발생했습니다. 동일한 화면에서 목록보기와 함께지도 조각을 사용하고 있었는데 , xml 의 마법 속성을 사용하여이 문제를 해결했습니다 . scrollingCache = "false" .my 문제가 수정되었습니다.이 속성을 사용하여지도에서 지연 및 깜박임을 중지하십시오.


2

당신은 많은 세부 사항을 제공하지 않았으므로 내가 제안 할 수있는 것이 너무 많습니다. 호출기의보기간에 화면이 깜박이는 유사한 문제가 발생했습니다. 처음으로 페이지를 바꿀 때 mapView가 팽창하는 것으로 나타났습니다.

명확히하기 위해 호출기에 3 페이지가 있었고 내지도는 마지막 페이지였습니다.

이 문제를 해결하기 위해 화면 외부 페이지 수를 2로 설정하면 (위의 경우에 작동 함) 조각이 시작될 때 모든 뷰가 한 번에로드된다는 것을 알았습니다.

http://developer.android.com/reference/android/support/v4/view/ViewPager.html#setOffscreenPageLimit (int) 참조


고맙지 만 작동하지 않았습니다. 문제는지도로 덮힌 화면 부분이 다른 조각으로 변경 될 때이 다른 조각의 시야를 가리고 검은 색으로 남아 있다는 것입니다.
Pepe

흠 흥미 롭군요. 나는 이것에 대해 생각할 것이다.
Graham Smith

나는 유는 링크 해당 페이지에 setOffscreenPageLimit를 찾을 수 없습니다
mplungjan

0

이 문제에 대한 해결책이 하나 더 있습니다. 다른 조각 내에서 MapFragment를 표시하고 있습니다. MapFragment는 FrameLayout에 동적으로 추가됩니다.

해결책은 슬라이딩 메뉴의 열기 및 닫기 이벤트에 frameLayout.setVisibility (View.Visible) 및 frameLayout.setVisibility (View.Gone)을 사용하는 것입니다. 추가 할 추가보기가 필요하지 않습니다. 그리고 검은 부분은 완전히 사라졌습니다.

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

위의 방법 중 어느 것도 나를 위해 일하지 않았으며 다른 곳에서도 찾은 다른 방법도 없었습니다. 마지막으로 부분 솔루션을 선택했습니다. ViewPager의 onPageChangeListener를 통해 페이지 변경을 수신하고 페이지가 스크롤을 시작할 때지도를 숨기고 스크롤이 중지되면 다시 표시합니다. 스크롤 할 때 표시되는 흰색보기도 추가했습니다.


뷰의 현재 이미지를 비트 맵으로 캡처 한 다음 페이저가 스크롤되는 동안 ImageView에 표시하도록 더 확장 할 수 있습니다. 그렇게하면 사용자는 그 뒤에있는 해킹을 알아 차리지 못할 것입니다. 그러나이 계산은 스 와이프에 대한 UI의 응답 속도를 늦추기 때문에 너무 비싸다는 것을 알았습니다.
azyoot

-2

내 사용자 지정 맵 조각 을 프로젝트에 복사하기 만하면 됩니다 . 그리고 상단과 하단에 ScrollView가있는 검은 색 선이있는 경우 ScrollView android : 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();
}

}

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.