ViewPager với Google Maps API v2: chế độ xem màu đen huyền bí


95

Tôi đã tích hợp phân đoạn api v2 mới của google maps trong một máy nhắn tin xem. Khi cuộn từ mảnh bản đồ, một chế độ xem màu đen chồng lên các mảnh liền kề. Ai đó đã giải quyết?

Chỉnh sửa: ảnh chụp màn hình

nhập mô tả hình ảnh ở đây

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

Nó có xảy ra trên một thiết bị không? Có thể một vài dòng mã từ ViewPager của bạn và triển khai bản đồ có thể giúp hiểu rõ hơn vấn đề của bạn.
Adinia 12/12/12

Có, xảy ra trên tất cả các thiết bị tôi đã thử: samsung, htc, android 4.0, 2.3, v.v. Tôi đã tích hợp bản đồ trong ứng dụng của mình và trong một ứng dụng nhỏ gọn gàng chỉ có máy nhắn tin và bản đồ, với cùng một kết quả.
Pepe

@Pepe, bạn vui lòng cho biết, làm thế nào bạn lấy GoogleMapđối tượng từ ViewPager? Bị mắc kẹt trên này trong nhiều tuần. Nếu bạn không hiểu rõ câu hỏi, thì hãy tra cứu câu hỏi của tôi, bạn sẽ tìm thấy bài viết của tôi. Xin hãy trả lời.
azizbekian

Tôi muốn nói thêm rằng khi thực hiện một screen recordvấn đề dường như không xảy ra.
theblang

Câu trả lời:


115

Tôi có thể ngăn bề mặt đen bị bỏ lại sau quá trình chuyển đổi bằng cách đặt một chế độ xem khác có nền trong suốt ở phía trên ViewPagerbên trong một 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
Tuyệt quá! Nó không hoàn hảo, bởi vì đôi khi trong khi di chuyển máy nhắn tin xuất hiện một phần của chế độ xem màu đen. Nhưng bây giờ nó không còn ở trên màn hình nữa. Cảm ơn! (làm bạn có bất kỳ lời giải thích cho hack này?)
Pepe

7
Không hẳn vậy. Tôi chỉ nhận thấy nơi các điều khiển thu phóng và vị trí nằm trên bề mặt bản đồ, vệt đen không xuất hiện, vì vậy tôi đặt một chế độ xem trên cùng để bao quát toàn bộ bản đồ và nó hoạt động. Tôi đồng ý rằng nó không hoàn hảo - nền đen dường như là một phần của cửa sổ GLSurfaceView code.google.com/p/gmaps-api-issues/issues/detail?id=4639
Jeff Gilfelt 17/12/12

5
Có vẻ như nó đã khắc phục sự cố ViewPager của tôi. Cảm ơn bạn, nhưng có vẻ như tôi gặp sự cố tương tự với SlideMenu (menu bên trái như G + / Yahoo), đang làm điều tương tự .. Bạn có suy nghĩ gì về việc sửa lỗi triển khai SlideMenu không?
Chrispix 19/12/12

@Chrispix không tạo hoạt ảnh cho vùng chứa, chỉ sử dụng hoạt ảnh trên menu bên, nó đã sửa nó cho tôi.
meh,

1
Ive làm điều này và dưới đây giải pháp chương trình, họ làm việc trong khi ứng dụng là ở mặt trước nhưng khi ứng dụng được đóng lại và vẫn đang chạy và bạn quay trở lại để nó ở lại bản đồ phía trên vẫn còn ..
L7ColWinters

43

Gặp sự cố tương tự với SlidingMenu và ViewPager. Tôi nhận thấy rằng các nút điều khiển trong mảnh bản đồ không có màu đen trong phần tạo tác bị bỏ lại. Tôi đã giải quyết vấn đề bằng cách ghi đè onCreateView()phương thứcMapFragment (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;
}

Tôi cũng sử dụng nó cho SlidingMenu. Nhưng tôi gặp vấn đề nhấp nháy (với hoạt ảnh trượt) và nó không thể chấp nhận được, trông thật tệ. Bạn cũng có nó? Tôi đã thử nghiệm trên HTC One S. là gì thú vị, tôi chỉ có vấn đề này với các hình ảnh động mở và không phải khi đóng SlidingMenu
Michał K

Không có bản sửa lỗi nào phù hợp với tôi. Tôi thực tế đã gặp vấn đề tương tự như Michal K. Sử dụng SlidingMenu và mở hoặc đóng chậm ở tốc độ liên tục và không có vấn đề gì. Nhấn mở hoặc nhấn trở lại để đóng cửa sổ và có vẻ như bản đồ bị trễ một chút để lại một khoảng trống cho đến khi trang trình bày kết thúc nơi bản đồ trở về vị trí thích hợp của nó.
qubz

@qubz: Về 'menu trượt', hãy thử tạo hiệu ứng cho menu chứ không phải bản đồ. Nó đã giải quyết vấn đề cho tôi, nếu bản đồ không di chuyển.
meh

@meh: Bản đồ có thể đang di chuyển khi tôi đang mở / đóng SlidingMenu. Bằng cách di chuyển, ý tôi là CameraUpdate. Tôi sẽ xem liệu mình có thể tạm dừng hoạt ảnh hay không, mặc dù điều này sẽ cản trở trải nghiệm người dùng.
qubz

@Lubos Horacek: Bạn có thể vui lòng đăng mã mẫu không. Tôi đang gặp lỗi ngoại lệ con trỏ Null ..
avinash

7

Google đã phát hành bản sửa lỗi cho vấn đề này, nhưng chỉ dành cho 4.1+ (Bạn không cần tải xuống phiên bản PlayServices mới, họ đã sử dụng cờ phía máy chủ)

Đây là những gì tôi đang sử dụng để khắc phục sự cố - Đảm bảo bạn không lãng phí bất kỳ chu kỳ CPU nào trên thiết bị> = 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);
            }
        }
    }
}

Tôi đoán bạn tham khảo các lớp như sau: FixMapFragment mapFragment = (FixMapFragment) fragmentManager.findFragmentById(R.id.map);và trong file layout: <fragment android:id="@+id/map" android:name="com.example.fragments.FixMapFragment" .... Mặc dù vậy, bản đồ vẫn nhấp nháy theo những gì tôi có thể nói (Android 4.0.4).
JJD

@JJD Tôi có một mapview bị chập chờn, có cách nào để giải quyết điều đó không?
Rat-a-tat-a-tat Ratatouille

@ Rat-a-tat-a-tatRatatouille Không có giải pháp nào đáng tin cậy để tránh chế độ xem bản đồ bị nhấp nháy theo như tôi biết.
JJD

Tôi không biết liệu những gì tôi đã làm bây giờ có đúng hay không nhưng nó hoạt động. tôi đặt khả năng hiển thị của mapview thành ẩn và sau đó vài giây đặt lại khả năng hiển thị của mapviews về hiển thị. giảm nhấp nháy.
Rat-a-tat-a-tat Ratatouille,

6

Giải pháp của tôi: sử dụng giao diện ảnh chụp nhanh mới từ GoogleMap và hiển thị ảnh chụp nhanh của bản đồ trong khi cuộn trang.

Đây là mã của tôi để thiết lập ảnh chụp nhanh (nó nằm trong cùng một đoạn với bản đồ, được gọi là 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;
    }
}

Trong đó "mapFragment" là SupportedMapFragment của tôi và "iv" là ImageView (đặt nó là match_parent).

Và ở đây tôi đang kiểm soát cuộn:

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

Đoạn mảnh với bản đồ (FragmentMap) của tôi ở vị trí 1, vì vậy tôi cần điều khiển cuộn từ vị trí 0 đến 1 và từ vị trí 1 đến 2 (mệnh đề if đầu tiên). "getRegisteredFragment ()" là một hàm trong FragmentPagerAdapter tùy chỉnh của tôi, trong đó tôi có SparseArray (Fragment) được gọi là "registerFragment".

Vì vậy, bất cứ khi nào bạn cuộn đến hoặc từ bản đồ của mình, bạn luôn nhìn thấy ảnh chụp nhanh của nó. Điều này làm việc rất tốt cho tôi.


Các câu trả lời khác không phù hợp với tôi - đây là câu trả lời duy nhất có hiệu quả. Cảm ơn!
alice_silver_man

4

Tôi đã gặp vấn đề màn hình đen tương tự khi cuộn chế độ xem danh sách, tôi đang sử dụng phân mảnh bản đồ với chế độ xem danh sách trong cùng một màn hình. Tôi đã giải quyết vấn đề này bằng cách sử dụng thuộc tính ma thuật trong xml , nơi tôi đang nói chế độ xem danh sách chỉ cần chúng ta đặt android: scrollingCache = "false" . Sự cố của tôi đã được khắc phục, hãy thử thuộc tính này để ngăn chặn độ trễ và nhấp nháy trong bản đồ của bạn.


2

Bạn chưa đưa ra nhiều chi tiết nên tôi chỉ có thể gợi ý rất nhiều. Tôi đã gặp sự cố tương tự là màn hình nhấp nháy giữa các chế độ xem trong máy nhắn tin. Hóa ra là mapView bị thổi phồng khi hoán đổi giữa các trang lần đầu tiên.

Để rõ ràng, tôi có 3 trang trong máy nhắn tin và bản đồ của tôi là trang cuối cùng.

Để giải quyết vấn đề này, tôi thấy rằng đặt số trang tắt màn hình thành 2 (điều này hoạt động trong trường hợp trên) mà khi phân đoạn của tôi bắt đầu, nó sẽ tải tất cả các chế độ xem cùng một lúc.

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


Cảm ơn, nhưng không hiệu quả. Vấn đề là phần màn hình được bản đồ che phủ, khi thay đổi thành mảnh khác, vẫn là màu đen, che mất chế độ xem của mảnh khác này.
Pepe

hmmm thú vị. Tôi sẽ phải suy nghĩ về điều này.
Graham Smith

Tôi không thể tìm thấy setOffscreenPageLimit trên trang đó yu liên quan đến
mplungjan

0

Có một giải pháp nữa cho vấn đề này. Tôi đang hiển thị MapFragment trong một phân đoạn khác. MapFragment được thêm động vào FrameLayout.

Giải pháp là sử dụng frameLayout.setVisibility (View.Vible) và frameLayout.setVisibility (View.Gone) trên các sự kiện mở và đóng của menu trượt. Nó đòi hỏi phải có thêm một lượt xem. Và vùng đen mất hẳn.

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

Không có phương pháp nào ở trên hiệu quả với tôi, thậm chí không có phương pháp nào khác mà tôi đã tìm thấy ở nơi khác. Cuối cùng, tôi đã chọn giải pháp từng phần. Tôi lắng nghe các thay đổi trên trang qua onPageChangeListener của ViewPager và ẩn bản đồ khi trang của nó bắt đầu cuộn và tương tự như vậy, hiển thị lại khi nó ngừng cuộn. Tôi cũng đã thêm Chế độ xem màu trắng để hiển thị khi cuộn.


Nó có thể được mở rộng hơn nữa để chụp hình ảnh hiện tại của Chế độ xem thành một bitmap, sau đó hiển thị nó trên Chế độ xem ảnh trong khi máy nhắn tin đang cuộn. Bằng cách đó, người dùng sẽ không nhận thấy vụ hack đằng sau nó. Tuy nhiên, tôi thấy việc tính toán này hơi quá đắt vì nó sẽ làm chậm phản hồi của giao diện người dùng đối với thao tác vuốt.
azyoot

-2

Chỉ cần sao chép đoạn bản đồ tùy chỉnh của tôi vào dự án của bạn. Và nếu bạn có các đường màu đen với ScrollView ở trên cùng và dưới cùng được đặt thành ScrollView android: fadeEdge = "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();
}

}

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.