If you think the Android project iosched2011 listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.
Java Source Code
/*
* Copyright 2011 Google Inc.//fromwww.java2s.com
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/package com.google.android.apps.iosched.util;
import android.graphics.Rect;
import android.graphics.RectF;
import android.view.MotionEvent;
import android.view.TouchDelegate;
import android.view.View;
/**
* {@link TouchDelegate} that gates {@link MotionEvent} instances by comparing
* then against fractional dimensions of the source view.
* <p>
* This is particularly useful when you want to define a rectangle in terms of
* the source dimensions, but when those dimensions might change due to pending
* or future layout passes.
* <p>
* One example is catching touches that occur in the top-right quadrant of
* {@code sourceParent}, and relaying them to {@code targetChild}. This could be
* done with: <code>
* FractionalTouchDelegate.setupDelegate(sourceParent, targetChild, new RectF(0.5f, 0f, 1f, 0.5f));
* </code>
*/publicclass FractionalTouchDelegate extends TouchDelegate {
private View mSource;
private View mTarget;
private RectF mSourceFraction;
private Rect mScrap = new Rect();
/** Cached full dimensions of {@link #mSource}. */private Rect mSourceFull = new Rect();
/** Cached projection of {@link #mSourceFraction} onto {@link #mSource}. */private Rect mSourcePartial = new Rect();
privateboolean mDelegateTargeted;
public FractionalTouchDelegate(View source, View target, RectF sourceFraction) {
super(new Rect(0, 0, 0, 0), target);
mSource = source;
mTarget = target;
mSourceFraction = sourceFraction;
}
/**
* Helper to create and setup a {@link FractionalTouchDelegate} between the
* given {@link View}.
*
* @param source Larger source {@link View}, usually a parent, that will be
* assigned {@link View#setTouchDelegate(TouchDelegate)}.
* @param target Smaller target {@link View} which will receive
* {@link MotionEvent} that land in requested fractional area.
* @param sourceFraction Fractional area projected onto source {@link View}
* which determines when {@link MotionEvent} will be passed to
* target {@link View}.
*/publicstaticvoid setupDelegate(View source, View target, RectF sourceFraction) {
source.setTouchDelegate(new FractionalTouchDelegate(source, target, sourceFraction));
}
/**
* Consider updating {@link #mSourcePartial} when {@link #mSource}
* dimensions have changed.
*/privatevoid updateSourcePartial() {
mSource.getHitRect(mScrap);
if (!mScrap.equals(mSourceFull)) {
// Copy over and calculate fractional rectangle
mSourceFull.set(mScrap);
finalint width = mSourceFull.width();
finalint height = mSourceFull.height();
mSourcePartial.left = (int) (mSourceFraction.left * width);
mSourcePartial.top = (int) (mSourceFraction.top * height);
mSourcePartial.right = (int) (mSourceFraction.right * width);
mSourcePartial.bottom = (int) (mSourceFraction.bottom * height);
}
}
@Override
publicboolean onTouchEvent(MotionEvent event) {
updateSourcePartial();
// The logic below is mostly copied from the parent class, since we
// can't update private mBounds variable.
// http://android.git.kernel.org/?p=platform/frameworks/base.git;a=blob;
// f=core/java/android/view/TouchDelegate.java;hb=eclair#l98
final Rect sourcePartial = mSourcePartial;
final View target = mTarget;
int x = (int)event.getX();
int y = (int)event.getY();
boolean sendToDelegate = false;
boolean hit = true;
boolean handled = false;
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
if (sourcePartial.contains(x, y)) {
mDelegateTargeted = true;
sendToDelegate = true;
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_MOVE:
sendToDelegate = mDelegateTargeted;
if (sendToDelegate) {
if (!sourcePartial.contains(x, y)) {
hit = false;
}
}
break;
case MotionEvent.ACTION_CANCEL:
sendToDelegate = mDelegateTargeted;
mDelegateTargeted = false;
break;
}
if (sendToDelegate) {
if (hit) {
event.setLocation(target.getWidth() / 2, target.getHeight() / 2);
} else {
event.setLocation(-1, -1);
}
handled = target.dispatchTouchEvent(event);
}
return handled;
}
}