私のAndroidアプリケーションでは、ズーム可能なアクティビティを作成する必要があります。線形レイアウトをズームするための便利なコードを見つけました ここ 。しかし、私のアプリケーションでは、いくつかのアクティビティはスクロールビューで始まります。コードがscrollviewを認識しません。スクロール可能なアクティビティのピンチズームを作成するにはどうすればよいですか?これは私のレイアウトの1つです。
<ScrollView xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:tools="http://schemas.Android.com/tools"
Android:id="@+id/scrollViewZoom"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:layout_centerHorizontal="true"
Android:layout_centerVertical="true" >
<LinearLayout
Android:id="@+id/wd_content"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:layout_marginTop="10dp"
Android:orientation="vertical" >
<!-- Start Circle -->
<TableRow
Android:id="@+id/row_circl1"
Android:layout_width="wrap_content"
Android:layout_height="match_parent"
Android:layout_gravity="center"
Android:layout_marginTop="30dp"
Android:background="@color/purple_color" >
<RelativeLayout
Android:id="@+id/circle_layout1"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:background="@color/white_color" >
<ImageView
Android:id="@+id/img_engin_circle1"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_centerHorizontal="true"
Android:background="@drawable/circle_engin_bg"
Android:contentDescription="TODO" />
</RelativeLayout>
<RelativeLayout
Android:id="@+id/circle_layout2"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:background="@color/white_color" >
<ImageView
Android:id="@+id/img_engin_circle2"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_centerHorizontal="true"
Android:background="@drawable/circle_engin_bg"
Android:contentDescription="TODO" />
</RelativeLayout>
</TableRow>
<TableRow
Android:id="@+id/row_name_circle"
Android:layout_width="wrap_content"
Android:layout_height="match_parent"
Android:layout_gravity="center"
Android:layout_marginTop="30dp" >
<RelativeLayout
Android:id="@+id/circle_name_layout1"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_marginTop="-15dp"
Android:background="@color/white_color" >
<ImageView
Android:id="@+id/img_name_circle1"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_centerHorizontal="true"
Android:background="@drawable/circle_gauge_name"
Android:contentDescription="TODO" />
</RelativeLayout>
<RelativeLayout
Android:id="@+id/circle_name_layout2"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_marginTop="-15dp"
Android:background="@color/white_color" >
<ImageView
Android:id="@+id/img_name_circle2"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_centerHorizontal="true"
Android:background="@drawable/circle_gauge_name"
Android:contentDescription="TODO" />
</RelativeLayout>
</TableRow>
<!-- End Circle -->
</LinearLayout>
</ScrollView>
どんなアイデアでも私を助けてくれるでしょう。ありがとう。
OK。ネットを耕した後、ついに私の答えを見つけました。 scrollviewのonTouchEvent()
が機能しないことがわかったので、dispatchTouchEvent()
の代わりにonTouchEvent()
を使用する必要があります。上部に私のxmlコード(私の質問)が表示されます。これはもちろんコメント付きの私のアクティビティコードです。
// step 1: add some instance
private float mScale = 1f;
private ScaleGestureDetector mScaleDetector;
GestureDetector gestureDetector;
//step 2: create instance from GestureDetector(this step sholude be place into onCreate())
gestureDetector = new GestureDetector(this, new GestureListener());
// animation for scalling
mScaleDetector = new ScaleGestureDetector(this, new ScaleGestureDetector.SimpleOnScaleGestureListener()
{
@Override
public boolean onScale(ScaleGestureDetector detector)
{
float scale = 1 - detector.getScaleFactor();
float prevScale = mScale;
mScale += scale;
if (mScale < 0.1f) // Minimum scale condition:
mScale = 0.1f;
if (mScale > 10f) // Maximum scale condition:
mScale = 10f;
ScaleAnimation scaleAnimation = new ScaleAnimation(1f / prevScale, 1f / mScale, 1f / prevScale, 1f / mScale, detector.getFocusX(), detector.getFocusY());
scaleAnimation.setDuration(0);
scaleAnimation.setFillAfter(true);
ScrollView layout =(ScrollView) findViewById(R.id.scrollViewZoom);
layout.startAnimation(scaleAnimation);
return true;
}
});
// step 3: override dispatchTouchEvent()
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
super.dispatchTouchEvent(event);
mScaleDetector.onTouchEvent(event);
gestureDetector.onTouchEvent(event);
return gestureDetector.onTouchEvent(event);
}
//step 4: add private class GestureListener
private class GestureListener extends GestureDetector.SimpleOnGestureListener {
@Override
public boolean onDown(MotionEvent e) {
return true;
}
// event when double tap occurs
@Override
public boolean onDoubleTap(MotionEvent e) {
// double tap fired.
return true;
}
}
どうもありがとう。
ソリューションのおかげで、スクロールビューがアクティビティではなくフラグメント内にあるため、少し異なる実装を行いました。すべてのロジックをビューに委任するには、同じカスタムスクロールビューにdispatchTouchEventを追加することをお勧めします。
package com.your.package;
import Android.content.Context;
import Android.util.AttributeSet;
import Android.view.GestureDetector;
import Android.view.MotionEvent;
import Android.view.ScaleGestureDetector;
import Android.view.animation.ScaleAnimation;
import Android.widget.ScrollView;
import com.your.package.R;
public class CustomZoomScrollView extends ScrollView {
// step 1: add some instance
private float mScale = 1f;
private ScaleGestureDetector mScaleDetector;
GestureDetector gestureDetector;
public CustomZoomScrollView(Context context) {
super(context);
}
public CustomZoomScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
//step 2: create instance from GestureDetector(this step should be place into onCreate())
gestureDetector = new GestureDetector(getContext(), new GestureListener());
mScaleDetector = new ScaleGestureDetector(getContext(), new ScaleGestureDetector.SimpleOnScaleGestureListener()
{
@Override
public boolean onScale(ScaleGestureDetector detector)
{
float scale = 1 - detector.getScaleFactor();
float prevScale = mScale;
mScale += scale;
if (mScale < 0.1f) // Minimum scale condition:
mScale = 0.1f;
if (mScale > 10f) // Maximum scale condition:
mScale = 10f;
ScaleAnimation scaleAnimation = new ScaleAnimation(1f / prevScale, 1f / mScale, 1f / prevScale, 1f / mScale, detector.getFocusX(), detector.getFocusY());
scaleAnimation.setDuration(0);
scaleAnimation.setFillAfter(true);
getRootView().findViewById(R.id.svSeats).startAnimation(scaleAnimation);
return true;
}
});
}
// step 3: override dispatchTouchEvent()
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
super.dispatchTouchEvent(event);
mScaleDetector.onTouchEvent(event);
gestureDetector.onTouchEvent(event);
return gestureDetector.onTouchEvent(event);
}
//step 4: add private class GestureListener
private class GestureListener extends GestureDetector.SimpleOnGestureListener {
@Override
public boolean onDown(MotionEvent e) {
return true;
}
// event when double tap occurs
@Override
public boolean onDoubleTap(MotionEvent e) {
// double tap fired.
return true;
}
}
}