MapFragment
に新しい ScrollView
sの1つがあります。実際にはSupportMapFragment
ですが、とにかくです。動作しますが、2つの問題があります。
スクロールすると、黒いマスクが残ります。黒は、+ /-ズームボタンがあった穴を除いて、マップがあった領域を正確に覆います。下のスクリーンショットをご覧ください。これはAndroid 4.0。
ビューは、ユーザーがマップを操作するときにrequestDisallowInterceptTouchEvent()
を使用しないため、ScrollView
がタッチをインターセプトしないようにするため、マップ内で垂直方向にパンしようとすると、含まれるScrollView
。理論的にはビュークラスMapView
を派生させてその機能を追加することはできますが、どのようにしてMapFragment
を取得して標準の代わりにカスタマイズされたMapView
を使用できますか?
Mapviewフラグメントに透明な画像を適用すると、問題が解決するようです。最もきれいではありませんが、うまくいくようです。これを示すXMLスニペットを次に示します。
<RelativeLayout
Android:id="@+id/relativeLayout1"
Android:layout_width="match_parent"
Android:layout_height="300dp" >
<fragment
Android:id="@+id/map"
Android:name="com.google.Android.gms.maps.MapFragment"
Android:layout_width="fill_parent"
Android:layout_height="fill_parent"/>
<ImageView
Android:id="@+id/imageView123"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:src="@drawable/temp_transparent" />
</RelativeLayout>
透明なImageViewを追加しても、ブラックマスクを完全に削除することはできませんでした。マップの上部と下部には、スクロール中に黒いマスクが表示されたままです。
だからそれに対する解決策、私は この答え で小さな変化を見つけました。追加した、
_Android:layout_marginTop="-100dp"
Android:layout_marginBottom="-100dp"
_
それは垂直スクロールビューだったので、私の地図の断片に。したがって、私のレイアウトは次のようになりました。
_<RelativeLayout
Android:id="@+id/map_layout"
Android:layout_width="match_parent"
Android:layout_height="300dp">
<fragment
Android:id="@+id/mapview"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:layout_marginTop="-100dp"
Android:layout_marginBottom="-100dp"
Android:name="com.google.Android.gms.maps.MapFragment"/>
<ImageView
Android:id="@+id/transparent_image"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:src="@color/transparent" />
</RelativeLayout>
_
質問の2番目の部分を解決するために、メインのScrollViewにrequestDisallowInterceptTouchEvent(true)
を設定しました。ユーザーが透明画像に触れて移動したときに、マップフラグメントがタッチイベントを取得できるように、_MotionEvent.ACTION_DOWN
_および_MotionEvent.ACTION_MOVE
_の透明画像のタッチを無効にしました。
_ScrollView mainScrollView = (ScrollView) findViewById(R.id.main_scrollview);
ImageView transparentImageView = (ImageView) findViewById(R.id.transparent_image);
transparentImageView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
int action = event.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
// Disallow ScrollView to intercept touch events.
mainScrollView.requestDisallowInterceptTouchEvent(true);
// Disable touch on transparent view
return false;
case MotionEvent.ACTION_UP:
// Allow ScrollView to intercept touch events.
mainScrollView.requestDisallowInterceptTouchEvent(false);
return true;
case MotionEvent.ACTION_MOVE:
mainScrollView.requestDisallowInterceptTouchEvent(true);
return false;
default:
return true;
}
}
});
_
これは私のために働いた。お役に立てば幸いです。
これはおそらく この質問 の問題の原因と同じ場所にそのルーツを持っています。そこでの解決策は、透明なフレームを使用することです。これは、透明な画像より少し軽いです。
多くの研究開発の後に行われた:
fragment_one.xmlは次のようになります
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:id="@+id/scrollViewParent"
Android:orientation="vertical" >
<LinearLayout
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:orientation="vertical" >
<RelativeLayout
Android:layout_width="match_parent"
Android:layout_height="400dip" >
<com.google.Android.gms.maps.MapView
Android:id="@+id/mapView"
Android:layout_width="match_parent"
Android:layout_height="match_parent" />
<View
Android:id="@+id/customView"
Android:layout_width="fill_parent"
Android:layout_height="fill_parent"
Android:background="@Android:color/transparent" />
</RelativeLayout>
<!-- Your other elements are here -->
</LinearLayout>
</ScrollView>
Your Java FragmentOne.Javaのクラスは次のようになります:
private GoogleMap mMap;
private MapView mapView;
private UiSettings mUiSettings;
private View customView
onCreateView
mapView = (MapView) rootView.findViewById(R.id.mapView);
mapView.onCreate(savedInstanceState);
if (mapView != null) {
mMap = mapView.getMap();
mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
mUiSettings = mMap.getUiSettings();
mMap.setMyLocationEnabled(true);
mUiSettings.setCompassEnabled(true);
mUiSettings.setMyLocationButtonEnabled(false);
}
scrollViewParent = (ScrollView)rootView.findViewById(R.id.scrollViewParent);
customView = (View)rootView.findViewById(R.id.customView);
customView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
int action = event.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
// Disallow ScrollView to intercept touch events.
scrollViewParent.requestDisallowInterceptTouchEvent(true);
// Disable touch on transparent view
return false;
case MotionEvent.ACTION_UP:
// Allow ScrollView to intercept touch events.
scrollViewParent.requestDisallowInterceptTouchEvent(false);
return true;
case MotionEvent.ACTION_MOVE:
scrollViewParent.requestDisallowInterceptTouchEvent(true);
return false;
default:
return true;
}
}
});
私はこの構造を使用し、問題を克服しました。
マップフラグメントにコンテナビューを使用しました。
<ScrollView
Android:layout_width="match_parent"
Android:layout_height="match_parent">
<LinearLayout
Android:orientation="vertical"
Android:layout_width="match_parent"
Android:layout_height="wrap_content">
<TextView
Android:text="Another elements in scroll view1"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content" />
<com.erolsoftware.views.MyMapFragmentContainer
Android:orientation="vertical"
Android:layout_width="match_parent"
Android:layout_height="250dp">
<fragment
xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:tools="http://schemas.Android.com/tools"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:id="@+id/eventMap"
tools:context="com.erolsoftware.eventapp.EventDetails"
Android:name="com.google.Android.gms.maps.SupportMapFragment"/>
</com.erolsoftware.views.MyMapFragmentContainer>
<TextView
Android:text="Another elements in scroll view2"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content" />
</LinearLayout>
</ScrollView>
コンテナクラス:
public class MyMapFragmentContainer extends LinearLayout {
@Override
public boolean onInterceptTouchEvent(MotionEvent ev)
{
if (ev.getActionMasked() == MotionEvent.ACTION_DOWN)
{
ViewParent p = getParent();
if (p != null)
p.requestDisallowInterceptTouchEvent(true);
}
return false;
}
public MyMapFragmentContainer(Context context) {
super(context);
}
public MyMapFragmentContainer(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyMapFragmentContainer(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
}
CustomScrollViewsと透明なレイアウトファイルに苦労する必要はありません。 Googleマップの軽量バージョンを使用するだけで、問題は解決します。
map:liteMode="true"
レイアウトファイルのマップフラグメント内に上記のプロパティを追加します。問題が修正されます。
<ScrollView
Android:layout_width="match_parent"
::
::
::
<FrameLayout
Android:id="@+id/map_add_business_one_rl"
Android:layout_width="match_parent"
Android:layout_height="100dp"
>
<fragment
Android:id="@+id/map"
Android:name="com.google.Android.gms.maps.SupportMapFragment"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:layout_marginTop="-100dp"
Android:layout_marginBottom="-100dp"
/>
</FrameLayout>
::
::
::
</ScrollView>
質問の2番目の部分では、SupportMapFragmentからフラグメントクラスを派生させ、代わりにレイアウトで使用できます。その後、 Fragment#onCreateView をオーバーライドして、カスタムMapViewをインスタンス化できます。
それが機能しない場合は、いつでも独自のフラグメントを作成できます。すべてのライフサイクルメソッド(onCreate、onResumeなど)を自分で呼び出す必要があります。 この回答 にはさらに詳細があります。