ViewPager พร้อม Google Maps API v2: มุมมองสีดำลึกลับ


95

ฉันได้รวมส่วนใหม่ของ google maps 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

คำตอบ:


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
เยี่ยมมาก! มันไม่สมบูรณ์แบบเพราะบางครั้งในขณะที่กำลังเคลื่อนเพจเจอร์จะปรากฏส่วนหนึ่งของมุมมองสีดำ แต่ตอนนี้มันไม่ได้อยู่ในหน้าจออีกต่อไป ขอบคุณ! (คุณมีคำอธิบายเกี่ยวกับการแฮ็กนี้หรือไม่)
Pepe

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 เวอร์ชันใหม่พวกเขาใช้แฟล็กฝั่งเซิร์ฟเวอร์)

นี่คือสิ่งที่ฉันใช้เพื่อหลีกเลี่ยงปัญหา - มั่นใจได้ว่าคุณจะไม่เสียรอบ CPU บนอุปกรณ์> = 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);
            }
        }
    }
}

ฉันเดาว่าคุณอ้างอิงคลาสดังนี้: FixMapFragment mapFragment = (FixMapFragment) fragmentManager.findFragmentById(R.id.map);และในไฟล์เลย์เอาต์: <fragment android:id="@+id/map" android:name="com.example.fragments.FixMapFragment" .... แม้ว่าแผนที่จะยังคงกะพริบอยู่เท่าที่ฉันบอกได้ (Android 4.0.4)
JJD

@JJD ฉันมี mapview ที่กะพริบมีวิธีแก้ไหม?
Rat-a-tat-a-tat Ratatouille

@ Rat-a-tat-a-tatRatatouille ไม่มีวิธีแก้ปัญหาที่เชื่อถือได้เพื่อหลีกเลี่ยงการกะพริบของมุมมองแผนที่เท่าที่ฉันรู้
JJD

ฉันไม่รู้ว่าสิ่งที่ฉันทำตอนนี้ถูกต้องหรือไม่ แต่ได้ผล ฉันตั้งค่าการมองเห็น mapview เป็นมองไม่เห็นและหลังจากนั้นไม่กี่วินาทีก็ตั้งค่าการมองเห็นแผนที่วิวกลับเป็นมองเห็นได้ ลดการสั่นไหว
Rat-a-tat-a-tat Ratatouille

6

วิธีแก้ปัญหาของฉัน: ใช้ประโยชน์จากอินเทอร์เฟซภาพรวมใหม่จาก GoogleMapและแสดงภาพรวมของแผนที่ขณะเลื่อนหน้า

นี่คือรหัสของฉันในการตั้งค่า snapshot (อยู่ในส่วนเดียวกับแผนที่เรียกว่า 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-clause แรก) "getRegisteredFragment ()" เป็นฟังก์ชันใน FragmentPagerAdapter แบบกำหนดเองของฉันซึ่งฉันมี SparseArray (Fragment) ที่เรียกว่า "registerFragments"

ดังนั้นเมื่อใดก็ตามที่คุณเลื่อนไปมาหรือจากแผนที่คุณจะเห็นภาพรวมของแผนที่นั้นเสมอ สิ่งนี้ได้ผลดีสำหรับฉัน


คำตอบอื่น ๆ ไม่ได้ผลสำหรับฉัน - นี่เป็นคำตอบเดียวที่ได้ผล ขอบคุณ!
alice_silver_man

4

ฉันมีปัญหาหน้าจอสีดำเหมือนกันในการเลื่อนดูรายการฉันใช้ส่วนแผนที่กับมุมมองรายการในหน้าจอเดียวกันฉันได้แก้ไขปัญหานี้ด้วยการใช้คุณสมบัติวิเศษใน xmlที่ฉันกำลังพูดถึงมุมมองรายการเพียงแค่เราต้องใส่android: scrollingCache = "false"ปัญหาของฉันได้รับการแก้ไขแล้วลองใช้คุณสมบัตินี้เพื่อหยุดการล้าหลังและการกะพริบในแผนที่ของคุณ


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

วิธีใดข้างต้นไม่ได้ผลสำหรับฉันแม้แต่วิธีอื่นที่ฉันพบจากที่อื่น สุดท้ายฉันเลือกวิธีแก้ปัญหาบางส่วน ฉันรับฟังการเปลี่ยนแปลงหน้าผ่าน onPageChangeListener ของ ViewPager และซ่อนแผนที่เมื่อหน้าเริ่มเลื่อนและในทำนองเดียวกันจะแสดงอีกครั้งเมื่อหยุดเลื่อน ฉันยังได้เพิ่มมุมมองสีขาวที่จะแสดงเมื่อเลื่อน


สามารถขยายเพิ่มเติมเพื่อจับภาพปัจจุบันของ View เป็นบิตแมปแล้วแสดงบน 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.