AndroidでViewのスケーリングをするには?(Honeycomb以前のAPIで)
AndroidでViewのスケーリングをするにはどうしたらいいだろう。
ドキュメントを見ると、setScaleX()とsetScaleY()があるのでこれを使えばいいだろう・・・と思った。
しかし、これはHoneycomb以降の話。API Level 11以降だ_| ̄|○
setRotation()やsetAlpha()もAPI Level 11以降だった。このあたりの「常識だよね?」と思われるAPIは大体Honeycomb以降に追加されたのだとわかった。
では、API Level 11以前でViewを拡大縮小する方法は無いのか?
ここでScaleAnimationの事を思い出した。「実際には」無理かもしれないけど、ScaleAnimationを使えば「見え」だけは拡大縮小するはず・・・と考えてやってみた。
Eclipseプロジェクトファイル:ViewScaling.zip(153KB)
res/layout/main.xml
ViewScalingActivity.java
ポイントはonScale()でチラつき防止のためにScaleAnimationにsetFillEnabled(true)とsetFillAfter(true)しているところ。
API Level 10でも何とかViewのスケーリングができたε-(´∀`*)ホッ
ドキュメントを見ると、setScaleX()とsetScaleY()があるのでこれを使えばいいだろう・・・と思った。
しかし、これはHoneycomb以降の話。API Level 11以降だ_| ̄|○
setRotation()やsetAlpha()もAPI Level 11以降だった。このあたりの「常識だよね?」と思われるAPIは大体Honeycomb以降に追加されたのだとわかった。
では、API Level 11以前でViewを拡大縮小する方法は無いのか?
ここでScaleAnimationの事を思い出した。「実際には」無理かもしれないけど、ScaleAnimationを使えば「見え」だけは拡大縮小するはず・・・と考えてやってみた。
Eclipseプロジェクトファイル:ViewScaling.zip(153KB)
res/layout/main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/target"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#660000"
android:gravity="center"
android:text="Pinch-IN or Pinch-OUT" />
</LinearLayout>
ViewScalingActivity.java
package jp.example;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
import android.view.ScaleGestureDetector.SimpleOnScaleGestureListener;
import android.view.animation.ScaleAnimation;
import android.widget.TextView;
public class ViewScalingActivity extends Activity {
protected TextView target;
protected ScaleGestureDetector sgd;
protected boolean isPinch = false;
protected float scalePrev = 1.0f;
protected float spanPrev = 0.0f;
@Override
public void onCreate(Bundle savedInstanceState) {
// お約束
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// ScaleGestureDetector作成
sgd = new ScaleGestureDetector(this, new MySimpleOnScaleGestureListener());
// ターゲット取得
target = (TextView) findViewById(R.id.target);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
sgd.onTouchEvent(event);
switch (event.getAction()) {
case MotionEvent.ACTION_UP:
procActionUp();
break;
} // END switch
return false;
} // END onTouchEvent()
protected void procActionUp() {
// ピンチ動作だったらスケーリングなし状態までアニメーションさせる
if (isPinch) {
ScaleAnimation anim = new ScaleAnimation(scalePrev, 1.0f, scalePrev, 1.0f, target.getWidth() / 2, target.getHeight() / 2);
anim.setDuration(250);
target.startAnimation(anim);
}
// 各種パラメーターリセット
isPinch = false;
scalePrev = 1.0f;
spanPrev = 0.0f;
} // END procActionUp()
protected class MySimpleOnScaleGestureListener extends SimpleOnScaleGestureListener {
@Override
public boolean onScale(ScaleGestureDetector detector) {
// 2つの指の距離を使って遊びを持たせる(一定の距離以下ならピンチとみなさない)
float spanCurr = detector.getCurrentSpan();
if (Math.abs(spanCurr - spanPrev) < 20) {
return false;
}
// ピンチ動作とみなす
isPinch = true;
// アニメーションが走っていたら止める
if (target.getAnimation() != null) {
target.getAnimation().cancel();
}
// 現在のスケーリング
float scaleCurr = detector.getScaleFactor();
Log.v("onScale", "scalePrev=" + scalePrev + " scaleCurr=" + scaleCurr + " spanCurr=" + spanCurr + " spanPrev=" + spanPrev);
// スケールアニメーション開始
ScaleAnimation anim = new ScaleAnimation(scalePrev, scaleCurr, scalePrev, scaleCurr, target.getWidth() / 2, target.getHeight() / 2);
anim.setDuration(100); // あまり速すぎるとガクガクする
anim.setFillEnabled(true); // チラつき防止
anim.setFillAfter(true); // チラつき防止
target.startAnimation(anim);
// 各種パラメーター保存
spanPrev = spanCurr;
scalePrev = scaleCurr;
return super.onScale(detector);
}
} // END class MySimpleOnScaleGestureListener
} // END class
ポイントはonScale()でチラつき防止のためにScaleAnimationにsetFillEnabled(true)とsetFillAfter(true)しているところ。
API Level 10でも何とかViewのスケーリングができたε-(´∀`*)ホッ
コメント
コメントを投稿