ViewPager с API Карт Google v2: таинственный черный вид

Я включил новый api v2-фрагмент google-карт в представлении пейджера. При прокрутке с фрагмента карты черный вид перекрывает смежные фрагменты. Кто-то решил?

Изменить: снимок экрана

enter image description here

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

Ответ 1

Я смог остановить черную поверхность, оставшуюся после перехода, разместив другой вид с прозрачным фоном поверх ViewPager внутри 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>

Ответ 2

Была та же проблема с 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;
}

Ответ 3

Google выпустила исправление для этого, но только для 4.1+ (вам не нужно загружать новую версию PlayServices, они использовали флаг на стороне сервера)

Вот то, что я использую, чтобы обойти проблему. Обеспечивает, чтобы вы не тратили впустую циклы процессора на устройствах >= 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);
            }
        }
    }
}

Ответ 4

Мое обходное решение: используйте новый интерфейс моментального снимка из 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, в котором у меня есть SparseArray (фрагмент), называемый зарегистрированными фрагментами.

Итак, всякий раз, когда вы переходите на или с вашей карты, вы всегда видите ее снимок. Это очень хорошо для меня.

Ответ 5

У меня была такая же проблема с черным экраном при прокрутке списка, я использовал фрагмент карты с просмотром списка на одном экране. Я решил эту проблему с использованием магического свойства в xml, где я список говорящего списка, мы должны установить android: scrollingCache = "false" .my проблема исправлена. Попробуйте это свойство, чтобы остановить отставание и мерцание на ваших картах.

Ответ 6

Вы не дали подробностей, поэтому я могу только предложить. У меня была аналогичная проблема, что экран мерцал между представлениями в пейджере. Это оказалось, что mapView раздувается при первом обмене между страницами.

Чтобы быть ясным, у меня было 3 страницы в моем пейджере, и моя карта была последней страницей.

Чтобы решить эту проблему, я обнаружил, что при установке количества отключенных экранных страниц до 2 (это работало в случае выше), когда мой фрагмент начал загружать все просмотры сразу.

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

Ответ 7

Есть еще одно решение этой проблемы. Я показываю 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);
            }
        });

Ответ 8

Ни один из вышеперечисленных методов не работал у меня, даже других, которых я нашел в другом месте. Наконец, я выбрал частичное решение. Я слушаю изменения страницы через ViewPager onPageChangeListener и скрываю карту, когда ее страница начинает прокрутку, а также снова показывать ее, когда она перестает прокручиваться. Я также добавил белый вид, который будет отображаться при прокрутке.

Ответ 9

Просто скопируйте мой пользовательский фрагмент карты в ваш проект. И если у вас черные линии с 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();
}

}