Mal*_*alo 36 android google-maps android-fragments
我想设置内垂直一个谷歌地图片段ScrollView,当我做的地图不垂直缩放,我怎么可以覆盖触摸事件监听器MapView上的监听器ScrollView?
这是我的xml代码:
<ScrollView android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:layout_above="@id/footer"
android:layout_below="@id/title_horizontalScrollView">
///other things
<fragment
android:id="@+id/map"
android:layout_width="fill_parent"
android:layout_height="300dp"
class="com.google.android.gms.maps.SupportMapFragment"
/>
//other things
Run Code Online (Sandbox Code Playgroud)
Alo*_*air 107
创建一个自定义的SupportMapFragmet,以便我们可以覆盖其触摸事件:
WorkaroundMapFragment.java
import android.content.Context;
import android.os.Bundle;
import android.widget.FrameLayout;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import com.google.android.gms.maps.SupportMapFragment;
public class WorkaroundMapFragment extends SupportMapFragment {
private OnTouchListener mListener;
@Override
public View onCreateView(LayoutInflater layoutInflater, ViewGroup viewGroup, Bundle savedInstance) {
View layout = super.onCreateView(layoutInflater, viewGroup, savedInstance);
TouchableWrapper frameLayout = new TouchableWrapper(getActivity());
frameLayout.setBackgroundColor(getResources().getColor(android.R.color.transparent));
((ViewGroup) layout).addView(frameLayout,
new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
return layout;
}
public void setListener(OnTouchListener listener) {
mListener = listener;
}
public interface OnTouchListener {
public abstract void onTouch();
}
public class TouchableWrapper extends FrameLayout {
public TouchableWrapper(Context context) {
super(context);
}
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mListener.onTouch();
break;
case MotionEvent.ACTION_UP:
mListener.onTouch();
break;
}
return super.dispatchTouchEvent(event);
}
}
}
Run Code Online (Sandbox Code Playgroud)
在上面的类中,我们通过使用扩展FrameLayout的TouchableWrapper类拦截触摸事件.还有一个自定义侦听器OnTouchListener将触摸事件分派给处理地图的主要活动MyMapActivity.当触摸事件发生时,将调用dispatchTouchEvent并且监听器mListener将处理它.
然后用x替换xml中的fragment类class="packagename.WorkaroundMapFragment"而不是com.google.android.gms.maps.SupportMapFragment
然后在您的活动初始化地图中,如下所示:
private GoogleMap mMap;
Run Code Online (Sandbox Code Playgroud)
在onCreate里面这样做:
// check if we have got the googleMap already
if (mMap == null) {
SupportMapFragment mapFragment = (WorkaroundMapFragment) getChildFragmentManager().findFragmentById(R.id.map);
mapFragment.getMapAsync(new OnMapReadyCallback() {
Override
public void onMapReady(GoogleMap googleMap)
{
mMap = googleMap;
mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
mMap.getUiSettings().setZoomControlsEnabled(true);
mScrollView = findViewById(R.id.scrollMap); //parent scrollview in xml, give your scrollview id value
((WorkaroundMapFragment) getChildFragmentManager().findFragmentById(R.id.map))
.setListener(new WorkaroundMapFragment.OnTouchListener() {
@Override
public void onTouch()
{
mScrollView.requestDisallowInterceptTouchEvent(true);
}
});
}
});
}
Run Code Online (Sandbox Code Playgroud)
更新:根据@ javacoder123的回答更新到getMapAsync的答案
小智 27
刚做CustomScrollView.class,
public class CustomScrollView extends ScrollView {
public CustomScrollView(Context context) {
super(context);
}
public CustomScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CustomScrollView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
final int action = ev.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
//Log.i("CustomScrollView", "onInterceptTouchEvent: DOWN super false" );
super.onTouchEvent(ev);
break;
case MotionEvent.ACTION_MOVE:
return false; // redirect MotionEvents to ourself
case MotionEvent.ACTION_CANCEL:
// Log.i("CustomScrollView", "onInterceptTouchEvent: CANCEL super false" );
super.onTouchEvent(ev);
break;
case MotionEvent.ACTION_UP:
//Log.i("CustomScrollView", "onInterceptTouchEvent: UP super false" );
return false;
default:
//Log.i("CustomScrollView", "onInterceptTouchEvent: " + action );
break;
}
return false;
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
super.onTouchEvent(ev);
//Log.i("CustomScrollView", "onTouchEvent. action: " + ev.getAction() );
return true;
}
}
Run Code Online (Sandbox Code Playgroud)
然后在xml中
<com.app.ui.views.CustomScrollView
android:id="@+id/scrollView"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
android:orientation="vertical">
</com.app.ui.views.CustomScrollView>
Run Code Online (Sandbox Code Playgroud)
如果xml beffore没有工作改变这个...
<com.myproyect.myapp.CustomScrollView
android:id="@+id/idScrollView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
android:descendantFocusability="beforeDescendants"
>
</com.myproyect.myapp.CustomScrollView>
Run Code Online (Sandbox Code Playgroud)
如何使用programmaticaly
CustomScrollView myScrollView = (CustomScrollView) findViewById(R.id.idScrollView);
Run Code Online (Sandbox Code Playgroud)
我使用谷歌地图侦听器来解决滚动视图中谷歌地图的滚动问题。
googleMap?.setOnCameraMoveStartedListener {
mapView.parent.requestDisallowInterceptTouchEvent(true)
}
googleMap?.setOnCameraIdleListener {
mapView.parent.requestDisallowInterceptTouchEvent(false)
}
Run Code Online (Sandbox Code Playgroud)
通过在您使用开始移动地图时使用它,它禁止父滚动,当您停止移动地图时,它允许滚动。
这是Alok Nair 回答的 Kotlin 版本,我不得不说我是相对较新的 Kotlin 代码编写者,感谢任何评论。
自定义 SupportMapFragmet:
class FocusMapFragment: SupportMapFragment() {
var listener: OnTouchListener? = null
lateinit var frameLayout: TouchableWrapper
override fun onAttach(context: Context) {
super.onAttach(context)
frameLayout = TouchableWrapper(context)
frameLayout.setBackgroundColor(ContextCompat.getColor(context, android.R.color.transparent))
}
override fun onCreateView(inflater: LayoutInflater, viewGroup: ViewGroup?, bundle: Bundle?): View? {
val layout = super.onCreateView(inflater, viewGroup, bundle)
val params = ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)
(layout as? ViewGroup)?.addView(frameLayout, params)
return layout
}
interface OnTouchListener {
fun onTouch()
}
inner class TouchableWrapper(context: Context): FrameLayout(context) {
override fun dispatchTouchEvent(event: MotionEvent?): Boolean {
when (event?.action) {
MotionEvent.ACTION_DOWN, MotionEvent.ACTION_UP -> listener?.onTouch()
}
return super.dispatchTouchEvent(event)
}
}
}
Run Code Online (Sandbox Code Playgroud)
然后更改xml中的fragment类:
android:name="packagename.FocusMapFragment"
Run Code Online (Sandbox Code Playgroud)
最后当你初始化地图时:
override fun onMapReady(googleMap: GoogleMap) {
this.googleMap = googleMap
(childFragmentManager.findFragmentById(R.id.mapView) as? FocusMapFragment)?.let {
it.listener = object: FocusMapFragment.OnTouchListener {
override fun onTouch() {
scrollView?.requestDisallowInterceptTouchEvent(true)
}
}
}
// ...
}
Run Code Online (Sandbox Code Playgroud)
我在 API 28 和 29 中测试了这段代码,我在任何地方都找不到 Kotlin 版本,所以我认为它可能对某些人有用。
| 归档时间: |
|
| 查看次数: |
22390 次 |
| 最近记录: |