我有一个帧布局,其中包含4个图像image1,image2,image3,image4。我可以缩放/捏合这个Frame布局。我能够通过使用X,Y位置而无需缩放来执行图像的触摸事件。
问题:如何在缩放后单独获得触摸功能上的图像。
public class ZoomLayout extends FrameLayout implements caleGestureDetector.OnScaleGestureListener {
private enum Mode {
NONE,
DRAG,
ZOOM
}
private static final String TAG = "ZoomLayout";
private static final float MIN_ZOOM = 1.0f;
private static final float MAX_ZOOM = 4.0f;
private Mode mode = Mode.NONE;
private float scale = 1.0f;
private float lastScaleFactor = 0f;
// Where the finger first touches the screen
private float startX = 0f;
private float startY = 0f;
// How much to translate the canvas
private float dx = 0f;
private float dy = 0f;
private float prevDx = 0f;
private float prevDy = 0f;
public ZoomLayout(Context context) {
super(context);
init(context);
}
public ZoomLayout(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public ZoomLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context);
}
@SuppressLint("NewApi")
private void init(final Context context) {
final ScaleGestureDetector scaleDetector = new ScaleGestureDetector(context, this);
this.setOnTouchListener(new View.OnTouchListener() {
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
@SuppressLint("NewApi")
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
com.example.target.ZoomLayout test=(com.example.target.ZoomLayout) view;
System.out.println( "iddd : "+test.getId());
switch (motionEvent.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
Log.i(TAG, "DOWN");
if (scale > MIN_ZOOM) {
mode = Mode.DRAG;
startX = motionEvent.getX() - prevDx;
startY = motionEvent.getY() - prevDy;
}
FrameLayout vv=(FrameLayout) child();
System.out.println("count= "+vv.getChildCount());
int count=vv.getChildCount();
for (int i = 1; i <count; i++) {
float startx,starty,endx,endy;
ImageView iv=(ImageView) vv.getChildAt(i);
startx=iv.getX()+startX;
starty=iv.getY()+startY;
endx=iv.getX()+iv.getWidth();
endy=iv.getY()+iv.getHeight();
if(motionEvent.getX()>( startx ) && motionEvent.getX()<(endx ) && motionEvent.getY()>(( starty )+getStatusBarHeight() ) && motionEvent.getY()<(( endy)+getStatusBarHeight()))
{
System.out.println("count= "+iv.getId());
Toast.makeText(context, "i = "+i, 3000).show();
}
}
break;
case MotionEvent.ACTION_MOVE:
if (mode == Mode.DRAG) {
dx = motionEvent.getX() - startX;
dy = motionEvent.getY() - startY;
}
break;
case MotionEvent.ACTION_POINTER_DOWN:
mode = Mode.ZOOM;
break;
case MotionEvent.ACTION_POINTER_UP:
mode = Mode.DRAG;
break;
case MotionEvent.ACTION_UP:
Log.i(TAG, "UP");
mode = Mode.NONE;
prevDx = dx;
prevDy = dy;
break;
}
scaleDetector.onTouchEvent(motionEvent);
if ((mode == Mode.DRAG && scale >= MIN_ZOOM) || mode == Mode.ZOOM) {
getParent().requestDisallowInterceptTouchEvent(true);
float maxDx = (child().getWidth() - (child().getWidth() / scale)) / 2 * scale;
float maxDy = (child().getHeight() - (child().getHeight() / scale))/ 2 * scale;
dx = Math.min(Math.max(dx, -maxDx), maxDx);
dy = Math.min(Math.max(dy, -maxDy), maxDy);
Log.i(TAG, "Width: " + child().getWidth() + ", scale " + scale + ", dx " + dx
+ ", max " + maxDx);
applyScaleAndTranslation();
}
return true;
}
});
}
// ScaleGestureDetector
@Override
public boolean onScaleBegin(ScaleGestureDetector scaleDetector) {
Log.i(TAG, "onScaleBegin");
return true;
}
@Override
public boolean onScale(ScaleGestureDetector scaleDetector) {
float scaleFactor = scaleDetector.getScaleFactor();
Log.i(TAG, "onScale" + scaleFactor);
if (lastScaleFactor == 0 || (Math.signum(scaleFactor) == Math.signum(lastScaleFactor))) {
scale *= scaleFactor;
scale = Math.max(MIN_ZOOM, Math.min(scale, MAX_ZOOM));
lastScaleFactor = scaleFactor;
} else {
lastScaleFactor = 0;
}
return true;
}
@Override
public void onScaleEnd(ScaleGestureDetector scaleDetector) {
Log.i(TAG, "onScaleEnd");
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
@SuppressLint("NewApi")
private void applyScaleAndTranslation() {
child().setScaleX(scale);
child().setScaleY(scale);
child().setTranslationX(dx);
child().setTranslationY(dy);
}
private View child() {
return getChildAt(0);
}
public float getStatusBarHeight() {
float result = 0;
float resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
result = getResources().getDimensionPixelSize((int) resourceId);
}
return result;
}
}
public class MainActivity extends ActionBarActivity {
com.example.target.ZoomLayout zoomerframe;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
zoomerframe=(com.example.target.ZoomLayout)findViewById(R.id.zoomerframe);
ImageView iv=new ImageView(getApplicationContext());
LayoutParams params=new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
FrameLayout frame=new FrameLayout(getApplicationContext());
iv.setLayoutParams(params);
iv.setLayoutParams(params);
iv.setImageResource(R.drawable.notifications_bg);
frame.addView(iv);
params = new FrameLayout.LayoutParams(
200,
200);
params.leftMargin = (int) 100;
params.topMargin = (int) 100;
ImageView iv2=new ImageView(getApplicationContext());
iv2.setLayoutParams(params);
iv2.setImageResource(R.drawable.trnspr);
frame.addView(iv2);
params = new FrameLayout.LayoutParams(
50,
50);
params.leftMargin = (int) 500;
params.topMargin = (int) 500;
ImageView iv3=new ImageView(getApplicationContext());
iv3.setLayoutParams(params);
iv3.setImageResource(R.drawable.trnspr);
frame.addView(iv3);
zoomerframe.addView(frame);
}
}
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/container"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
tools:context="com.example.target.MainActivity"
tools:ignore="MergeRootFrame">
<com.example.target.ZoomLayout
android:id="@+id/zoomerframe"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_centerInParent="true"
></com.example.target.ZoomLayout >
</RelativeLayout>