2010年12月28日火曜日

androidのViewを重ねて色々した時の問題。特にsetOnTouchListenerについて不勉強だった件について

public class example extends Activity{
private View1 view1 = new View1();
private View1 view2 = new View2();
private FrameLayout layout = new FrameLayout();

private Handler handler= new Handler();
private boolean view2Flag = false;

@Override
public void onCreate(Bundle savedInstanceState) {
layout.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
layout.addView(view1);

//view1がタッチされた際にView2を表示する
view1.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_DOWN){
if(view2Flag){
return false;
}else{
view2Flag = true;
//View2を追加してアニメーションでスライドさせてくる。
layout.addView(view2);
AnimationSet animationset = new AnimationSet(true);
animationset.addAnimation(new TranslateAnimation(0, 0, getHeight(), 0));
animationset.setDuration(500);
view2.startAnimation(animationset);

//View2を5000ms秒後にスライドさせたあとlayoutから削除する処理をhandlerに投げておく
handler.postDelayed(new Runnable() {
public void run() {
AnimationSet animationset = new AnimationSet(true);
animationset.addAnimation(new TranslateAnimation(0, 0, 0, getHeight()));
animationset.setDuration(500);
view2.startAnimation(animationset);
layout.removeView(view2);
view2Flag = false;
}
}, 5000);

return false;
}
}
return false;
}
});

}
}

イメージとしてはView1がメインのViewでView2が独自のメニュー画面みたいなイメージのアプリを作ってた。
で、View1でonFlingを取っていたが何故か取れなくなった。
理由はOntouchListenrでreturnでtrueを返していたから。
どうやらtrueを返したら、viewで継承、オーバーライドしたonFlingとかを無視するみたい。
というかタッチイベントすべて無視する。

リファレンスに書いてあった。
OnTouchListenerのonTouchの項目に
Returns
True if the listener has consumed the event, false otherwise.
って書いてあった。

いつも何も考えずにreturn false書き続けてたから理解してなかった。

#追記
中途半端に解決してた状況というかonFlingだけしか動かない状況っていうのは
if(event.getAction() == MotionEvent.ACTION_UP)でreturn trueとかしちゃった場合。
onFlingは内部でACTION_UPが検出された時点でフリックした距離とか返してくれるから動かない。
ただしonScrollはACTION_DOWNとACTION_MOVE辺りを取得して処理してるから問題ない。
そんな感じだったみたい?
これは何かの役に立つかは微妙だけど、覚えておく。

2010年12月21日火曜日

androidのWebViewのスクロールバーの見た目。

基本
webview = new WebView(this);
webview.loadUrl("http://~");
setContentView(webview);
とかして表示するけど、HTML上で背景色指定したりしてると、スクロールバーが表示される領域が真っ白になっちゃって何かカッコ悪い

webview.setScrollBarStyle(WebView.SCROLLBARS_INSIDE_OVERLAY);

これで余白とかなくなる。


日本語じゃあんまり資料ないっぽいので試して見た目チェックした一覧

setScrollBarStyleの定数にはWebView.でもいいけど、View.に含まれてて、WebViewがサブクラスだからどっちでもいい。
SCROLLBARS_INSIDE_OVERLAY WebViewに重ねて表示。
SCROLLBARS_INSIDE_INSET 専用領域確保して表示。白い領域でちゃうので何かダサい。
SCROLLBARS_OUTSIDE_OVERLAY SCROLLBARS_INSIDE_OVERLAYと同じ?
SCROLLBARS_OUTSIDE_INSET SCROLLBARS_INSIDE_INSETと同じ?

OUTSIDEの意味がわからない。見た目的には差がない。
Fill_ParrentでWebviewしか突っ込んでないから差がわからないのかな。並べてみたりすればわかるのだろうか。
リファレンス読んだ感じはパディングがどうのこうのOUTSIDE付いてる方はincreasing the paddingって書いてあるけど。
paddingの意味が良く解らない。

関係ないけど、Webviewに限らず他のViewのサブクラスも似たようなこと出来るってことだろう。

2010年12月15日水曜日

androidのapi level9突っ込んだ時に起こるeclipseのエラー

簡単に回避出来るけどAPI Level9 Gingerbreadのアップデート後にちょっとした問題がeclipseで起きたのでメモ。

なんかadb.exeが
android-sdk-windows/tools/adb.exe
から
android-sdk-windows/platform-tools/adb.exe
にお引越ししたみたい

eclipseのADTを普通にアップデートかけたら問題は回避できた
公式に特に書いてある感じ無いけど、まぁ最新版は常に突っ込んどけってことか

androidのwebviewでHTML5のGeolocationを使う方法 #追記2011/01/14 上手くいってない? #さらに追記2010/01/18

色々調べた結果

以下のパーミッションをマニフェストに追加

<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_GPS" />
<uses-permission android:name="android.permission.ACCESS_ASSISTED_GPS" />
<uses-permission android:name="android.permission.ACCESS_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission>

WebChromeClientを適当に作る。なんかほかにも色々出来そうだけど。とりあえずgeolocationのみで
final class GeoClient extends WebChromeClient {

@Override
public void onGeolocationPermissionsShowPrompt(String origin,
Callback callback) {
// TODO Auto-generated method stub
super.onGeolocationPermissionsShowPrompt(origin, callback);
callback.invoke(origin, true, false);
}
}


でWebViewの準備時に以下のような感じにする


this.webview = new WebView(this);
this.webview.getSettings().setJavaScriptEnabled(true);
GeoClient geo = new GeoClient();
this.webview.setWebChromeClient(geo);



なんか
getSettings().setGeolocationEnabled(true)とかを叩いても行けるっぽいようなことも書いてあったりしたけど、うまくいかなかったので上記で対応した。

#追記
何故か環境依存で上手くいかない場合があるみたい?細かいことは不明だが2.0から2.1にAPIバージョン上げて2.2でテストとか言う変則パターンだと上手く動作しなかった。
細かいこと調べてあとで書きなおす。
なのであんまり参考にしないでね。
##追記の追記
どうやら上手く動いてるようです。
上の追記でおかしくなった理由は試していたgeolocation使ったjsのミスによるものでした。

2010年12月14日火曜日

html5で位置引いて適当にgoogleマップ叩くコード

  var getGps = function() {
  navigator.geolocation.getCurrentPosition(function(position) {
      document.images['map'].src = 'http://maps.google.com/maps/api/staticmap?center=' + position.coords.latitude + ',' + position.coords.longitude + '&zoom=14&size=400x400&maptype=roadmap&sensor=false&markers=color:red|label:A|' + position.coords.latitude +',' + position.coords.longitude
    });
  }

これで適当に<a>タグ書いてロード時に引っ張り出すとかする。
よくわかんないけど、androidだと勝手にGPSから引っ張ってきてくれたipadも
あとipod touchはmacアドレスとかから引っ張り出してきてる感じ?
デスクトップPCでchromeから叩くとIPから引っ張ってくる感じ?