【问题标题】:Delayed panning after map in gallery was moved away by a dialog画廊中的地图被对话框移开后延迟平移
【发布时间】:2014-02-02 20:46:32
【问题描述】:

我在画廊中有一张地图,还有其他页面。 当我用触摸手势滑动图库页面时,一切正常。 但是,当我使用对话框上的按钮将地图移开,然后滑回地图时,地图不再平滑地跟随平移手势。而是伴随着明显的延迟。 一旦我再次使用对话框隐藏地图并关闭对话框,例如使用后退按钮,行为恢复正常。

为了重现它,我已经尽可能地精简了代码。

图库包含一个 DummyView,然后是一个 MapView,最后是一个 DummyView 作为页面。 DummyView 和 GalleryView 作为本地类添加到 Activity。

public class MainActivity extends FragmentActivity {

private static final int REQUEST_CODE_RECOVER_PLAY_SERVICES = 0;
private Gallery gallery;
private MapView mapView;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_map_in_gallery);
    final View[] views = new View[3];
    views[0] = new DummyView(this, "Page 1");
    views[1] = mapView = new MapView(this);
    views[2] = new DummyView(this, "Page 3");
    gallery = (Gallery) findViewById(R.id.gallery);
    BaseAdapter adapter = new ArrayAdapter<View>(this, 0, views) {
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            return views[position];
        }
    };
    gallery.setAdapter(adapter);
    // Let every page cover the whole screen
    gallery.setUnselectedAlpha(1);
    gallery.setSpacing(30);
}

@Override
protected void onResume() {
    super.onResume();
    checkPlayServices();
};

@Override
/** Define the dialog, which appears, when the Page-Button is pressed and
 * which allows to page in the gallery instead of swiping.
 */
protected Dialog onCreateDialog(int id) {
    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setTitle("Page");
    builder.setPositiveButton("->", new OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            page(+1);
        }
    });
    builder.setNegativeButton("<-", new OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            page(-1);
        }
    });
    return builder.create();
}

private void page(int increment) {
    int count = gallery.getAdapter().getCount();
    int nextPos = gallery.getSelectedItemPosition() + increment;
    if (nextPos >= count) {
        nextPos = 0;
    } else if (nextPos < 0) {
        nextPos = count - 1;
    }
    gallery.setSelection(nextPos);
}

private boolean checkPlayServices() {
    int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
    if (status != ConnectionResult.SUCCESS) {
        if (GooglePlayServicesUtil.isUserRecoverableError(status)) {
            showErrorDialog(status);
        } else {
            Toast.makeText(this, "This device is not supported.",
                    Toast.LENGTH_LONG).show();
            finish();
        }
        return false;
    }
    return true;
}

void showErrorDialog(int code) {
    GooglePlayServicesUtil.getErrorDialog(code, this,
            REQUEST_CODE_RECOVER_PLAY_SERVICES).show();
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    switch (requestCode) {
    case REQUEST_CODE_RECOVER_PLAY_SERVICES:
        if (resultCode == RESULT_CANCELED) {
            Toast.makeText(this, "Google Play Services must be installed.",
                    Toast.LENGTH_SHORT).show();
            finish();
        }
        return;
    }
    super.onActivityResult(requestCode, resultCode, data);
}

public void onButtonClick1(View v) {
    showDialog(0); // Only one dialog defined
}

public void onButtonClick2(View v) {
    mapView.togglePanOrSlide();
}
}

class DummyView extends View {

private String text;
private Paint paint;

/** Simple view which draws a text in the center of the screen. */
public DummyView(Context context, String text) {
    super(context);
    this.text = text;
    paint = new Paint();
    paint.setColor(Color.WHITE);
    paint.setTextSize(20);
}

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    canvas.drawText(text, getWidth() / 2, getHeight() / 2, paint);
}

}

class MapView extends RelativeLayout {

/** Switches the map gestures off, to allow sliding the map in the gallery. */
private boolean panAllowed;

public MapView(Context context) {
    super(context);
    inflate(context, R.layout.map_fragment, this);
}

public void togglePanOrSlide() {
    panAllowed = !panAllowed;
}

@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
    if (!panAllowed) {
        // Catch the event from the map, so the gallery will slide the page
        // instead.
        return true;
    }
    return super.onInterceptTouchEvent(event);
}

}

这是编码中夸大的两种布局:

activity_map_in_gallery.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >

<Button
    android:id="@+id/button1"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:onClick="onButtonClick1"
    android:text="Open Paging Dialog" />

<Button
    android:id="@+id/button2"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:onClick="onButtonClick2"
    android:text="Pan Map &lt;-> Slide Page" />

<RelativeLayout
    android:layout_width="fill_parent"
    android:layout_height="0dip"
    android:layout_weight="1" >

    <Gallery
        android:id="@+id/gallery"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_gravity="center"
        android:background="@android:drawable/alert_dark_frame" />
</RelativeLayout>

</LinearLayout>

和map_fragment.xml:

<?xml version="1.0" encoding="utf-8"?>
<!-- Merged into a RelativeLayout-Extension -->
<merge xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >

<fragment
    android:id="@+id/map"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    class="com.google.android.gms.maps.SupportMapFragment" />

</merge>

该布局在图库顶部添加了两个按钮。第一个打开一个对话框,允许在画廊中来回翻页。 第二个按钮切换地图行为。它可以被平移,也可以向左或向右滑动其整页。 当使用第一个按钮将地图翻开,然后使用滑动手势向后滑动时,就会出现问题。

第二个按钮允许关闭地图平移,因此地图对通常的画廊滑动作出反应。当使用滑动手势来回翻动地图时,之后平移没有问题(再次按下第二个按钮后)。

任何想法,为什么会发生这种情况,以及如何避免它?

【问题讨论】:

    标签: android google-maps-android-api-2 android-maps-v2


    【解决方案1】:

    片段事务在对话框关闭之前执行,这会导致奇怪的行为。

    不要直接执行片段事务,而是将其发布到 Handler 上。一旦对话框关闭,就会执行片段事务。

    试试下面的代码。我应用了与我的SO answer 之一相同的逻辑。

        private void page(int increment) {
            int count = gallery.getAdapter().getCount();
            int nextPos = gallery.getSelectedItemPosition() + increment;
            if (nextPos >= count) {
                nextPos = 0;
            } else if (nextPos < 0) {
                nextPos = count - 1;
            }
            final int finalNextPos = nextPos;
    
            Handler handler = new Handler();
            handler.post(new Runnable() {
    
                @Override
                public void run() {
                    gallery.setSelection(finalNextPos);
                }
    
            });
        }
    

    【讨论】:

    • 这确实有帮助——至少在大多数情况下是这样。当一次又一次地尝试时,我仍然有地图变得顽固的情况。我找不到任何模式。但是还是比不使用 Handler 好很多。
    猜你喜欢
    • 2014-03-22
    • 2023-03-14
    • 2017-10-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多