スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

[Android]マルチタッチを使えるかどうか

マルチタッチに対応している端末かどうかで、利用するクラスを分岐する必要があったので
リフレクションを使って分岐してみました。

try{
Class cls = Class.forName(MotionEvent.class.getName());
Field f = cls.getField("ACTION_POINTER_1_DOWN");

// マルチタッチ対応端末用クラス

}catch(Exception e){

// マルチタッチ非対応端末用クラス

}

上手くはいきましたが、こんな方法で良いのかな・・
真っ当なやり方ってあるんでしょうか。
スポンサーサイト

[Android]Scrollerメモ

Galleryクラスのソースを見てて、Scrollerを使っている部分が
最初よく理解できませんでした。

試してみたのが以下のコードです。

class TestRunnable implements Runnable{

Scroller mScroller;
int destX = 100;
int currentX = 0;

public TestRunnable(){
mScroller = new Scroller(getContext());
}

public void startScroll(){
removeCallbacks(this);
mScroller.startScroll(0, 0, destX, 0, 10000);
post(this);
}

public void run(){
mScroller.computeScrollOffset();

currentX = mScroller.getCurrX();

Log.d("Scroller", "currX" + currentX);

if(currentX < destX){
postDelayed(this, 1000);
}
}

}

Scrollerがスクロールをシミュレートして現在の位置を計算してくれて
それをRunnableを利用して定期的にチェックしにいくという感じなんですね。

ちなみに、computeScrollOffsetを呼ばないと現在位置がいつまでたっても0でした。

[Android]onLayoutを使用したレイアウト

AbsoluteLayoutを使おうとすると非推奨と怒られるので
自作ViewGroupで自由にレイアウトを決める方法を調べてみました。

public class SampleLayout extends ViewGroup{

private int mWidthMeasureSpec;
private int mHeightMeasureSpec;

private static final int WC = ViewGroup.LayoutParams.WRAP_CONTENT;
private static final int FP = ViewGroup.LayoutParams.FILL_PARENT;

public SampleLayout(Context c){
super(c);
}

@Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
super.onMeasure(widthMeasureSpec, heightMeasureSpec);

mWidthMeasureSpec = widthMeasureSpec;
mHeightMeasureSpec = heightMeasureSpec;
}

@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {

RelativeLayout rl = new RelativeLayout(getContext());
rl.setBackgroundColor(Color.WHITE);
ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(FP, FP);

TextView tv = new TextView(getContext());
tv.setText("Sample");
RelativeLayout.LayoutParams rlp = new RelativeLayout.LayoutParams(WC, WC);
rlp.addRule(RelativeLayout.CENTER_IN_PARENT);
rl.addView(tv, rlp);

// 子要素の追加
addViewInLayout(rl, -1, lp);

// 子要素に必要な大きさを計測
int padding = 50;
int childWidthSpec = ViewGroup.getChildMeasureSpec(mWidthMeasureSpec, padding * 2, lp.width);
int childHeightSpec = ViewGroup.getChildMeasureSpec(mHeightMeasureSpec, padding * 2, lp.height);
rl.measure(childWidthSpec, childHeightSpec);

// 子要素の描画範囲を渡してレイアウト
rl.layout(padding, padding, padding + rl.getMeasuredWidth(), padding + rl.getMeasuredHeight());

}

}

addViewではなく、addViewInLayoutで追加することと
子要素の大きさを測るところがミソのようです。

孫要素は子要素にレイアウトをお願いしています。

標準部品のソースは勉強になります。

[C/C++]Eclipse+CDTにおける外部ライブラリの追加

とても基本的なことと思いますが、かなり探しまわったのでメモ。

[プロジェクトを右クリック] - [プロパティ] - [C/C++ビルド] - [設定] - [C++リンカー] - [ライブラリ]

[Android]1.6エミュレータのアニメーションの初期設定

以下のページを見てActivityのOpen/Close時のアニメーションに挑戦してみました。

ActivityのOpenとCloseをアニメーションさせる


なぜか2.1のエミュレータでは動くアニメーションが1.6では動かない。

しばらくコードを疑っていましたが、エミュレータで「Settings - Sound & display」の中に
「Animation」という項目を発見!


ヨシヨシと喜んでいたところ、改めて記事をよく読むと

HOMEメニューの[設定]-[サウンド&画面設定]-[アニメーション表示]をONにしておかないと、このエフェクトは動作しません。




…自分が情けないです。


ちなみに2.1のエミュレータではこの項目がデフォルトで有効(All animations)となっていました。


気になったので上記アニメーション設定をアプリ側から有効にできないか調べたのですがよくわかりませんでした。

このあたりとか見ながら少し試しましたが、「Permission Denial」というエラーが出てしまいます。
ちゃんと署名すればいけるのかなー。

[Android]Matrix.setTranslate

Matrix.setTranslateの怪しい動きに悩まされました。

public void zoom(ImageView iv, Matrix m){
m.postScale(2.0f, 2.0f);
m.setTranslate(0.0f, 0.0f);
iv.setImageMatrix(m);
}


画像をズームして、表示位置を変えるというような単純なコードですが
「setTranslate」を使用すると、直前の「postScale」で設定した値が無効になってしまいました。

setTranslateって、MTRANS_XとMTRANS_Yの値を変更するだけかと思っていたのですが・・

こんな仕様なのでしょうか。

仕方ないので以下のような感じで回避しました。

public void zoom(ImageView iv, Matrix m){
m.postScale(2.0f, 2.0f);

float[] v = new float[9];
m.getValues(v);
v[Matrix.MTRANS_X] = 0.0f;
v[Matrix.MTRANS_Y] = 0.0f;
m.setValues(v);

iv.setImageMatrix(m);
}

[Android]アニメーションを使ってみる


ImageView imageView = (ImageView) findViewById(R.id.imageview);
RotateAnimation rotate = new RotateAnimation(0, 360,
Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
rotate.setDuration(1000);
imageView.startAnimation(rotate);


最初startAnimationの存在に気づかず、setAnimationを代わりに使っていたら
全然動いてくれず困りました。
アニメーションをさっさと実行したい場合はstartAnimationを使うようです。


setAnimationを使う場合は、アニメーションのstartTimeを設定して
Viewをinvalidateする必要があるようです。

http://developer.android.com/

/* setStartTimeを使う例 */

// AnimationUtils.currentAnimationTimeMillisを使って指定
rotate.setStartTime(AnimationUtils.currentAnimationTimeMillis());
imageView.setAnimation(rotate);
imageView.invalidate();


/* setStartOffsetを使う例 */

// 何ミリ秒後に実行するかを指定
rotate.setStartOffset(1000);
imageView.setAnimation(rotate);
imageView.invalidate();


複数のアニメーションを組み合わせて実行する場合は、AnimationSetを利用すると良さそう。

TranslateAnimation translate = new TranslateAnimation(
Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 0.5f,
Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 0);
translate.setDuration(1000);
translate.setInterpolator(new CycleInterpolator(3));
translate.setStartOffset(0);

RotateAnimation rotate = new RotateAnimation(0, 360,
Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
rotate.setDuration(1000);
rotate.setStartOffset(1000);

AnimationSet animationSet = new AnimationSet(false);
animationSet.addAnimation(translate);
animationSet.addAnimation(rotate);
imageView.startAnimation(animationSet);


大変参考になりました。

http://www.adamrocker.com/blog/181/android_animation.html

[Android]SQLiteにつないでみる

SQLiteOpenHelperを利用してつないでみました。

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

public class DatabaseHelper extends SQLiteOpenHelper {

public DatabaseHelper(Context context, String dbname) {
super(context, dbname, null, 1);
}

@Override
public void onCreate(SQLiteDatabase db) {
db.beginTransaction();
try {
db.execSQL("create table sample (name text);");
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

}

}


データベースがなければonCreateが呼ばれるようです。

検索は・・

DatabaseHelper helper = new DatabaseHelper(this, "test.db");
SQLiteDatabase db = helper.getReadableDatabase();

Cursor c = db.rawQuery("select * from sample;", null);
if(c.getCount() > 0){
// 最初の行に移動
c.moveToFirst();
Log.d("debug", c.getString(0));

// 次の行に進む場合はc.moveToNext()
}
c.close();


次は更新です。

SQLiteDatabase db = helper.getWritableDatabase();
db.beginTransaction();
try {
db.execSQL("delete from sample;");

SQLiteStatement stmt = db.compileStatement("insert into sample values (?);");
stmt.bindString(1, "test");
stmt.executeInsert();

db.setTransactionSuccessful();
} finally {
db.endTransaction();
}

[Android]An SDK Target must be specified

新しくAndroidプロジェクトを作成しようとすると

「An SDK Target must be specified」

とメッセージが出て先に進めませんでした。

よくよく見ると、「Build Target」の項目が表示されていないようです。


BuildTargetが出ていない


ディスプレイが小さいのでどうしたものかと悩みましたが
Dockを非表示にしてウィンドウを拡大したらなんとか選べるようになりました。

BuildTargetが出た

地味にハマりました。


助かりました。

http://d.hatena.ne.jp/Florian/20091107/1257594640
http://d.hatena.ne.jp/ya_ma/20091128/1259427017
プロフィール

jou4

Author:jou4
FC2ブログへようこそ!

最新記事
最新コメント
最新トラックバック
月別アーカイブ
カテゴリ
検索フォーム
RSSリンクの表示
リンク
ブロとも申請フォーム

この人とブロともになる

QRコード
QRコード
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。