Androidプログラミング日記 (仮)  

エミュと向きとタッチパネル

あなたは

人目のプログラマーだよ。

Androidプログラミング日記 (仮).

 

 

 

 

ある程度の区切り

ここらへんでちょっとだけちゃちゃっと何かやって軽いアプリを作りたくなったので、必要な知識を入れて、アプリ作りをやっていこうかなと思います。てことで一応ここで基礎の基礎の区切りです。

今更ですが

ここまでやってきて大変なことに気づきました。わたくし触れませんでしたがPCでプログラミングしている時に使用しているスマホエミュレーターですが、何も考えずやってました。たしかに書籍の通りの座標設定とかでやっていると、はみ出たりして自分で調整して、おかしいな・・とは思っていたのですが・・・というわけで、やはりここは自分の為ののアプリ作りです。まずは自分のスマホで動けばまず安心です。と思ったわたしはさっそく調べました。ちなみにわたしの携帯スマホは「XperiaX10」でいいのかなしかもAndroid2.1です。買い換えたい・・お金がない・・・

  1. Android端末のmenuボタンから「設定>アプリケーション>開発」を選択
  2. 「USBデバッグ」にチェックを入れる
  3. Android端末を付属のUSBケーブル(充電ケーブル)でPCに接続
  4. 私の場合はPCが自動でドライバを認識してくれましたがしない場合はAndroidSDKのusb_driver/x86フォルダ内のドライバを指定

これをしてEclipseでデバッグ時に「デバッグの実行と構成」を選択し下記写真のターゲットタブから「手操作」を選択しておくと、この次の表示で、接続されているスマホを選べるようになります。

   

こちらの方が実機で動作も確認できますし、起動もエミュレーターに比べて断然はやいので、これからはこちらのほうがいいかもしれません。しかし今はまだ練習なのでどちらでもいいですし、将来的にはどのスマホにもある程度同じような表示ができるようにするつもりなので、今回はこういうやり方もあります。と思っておいてください。

画面の回転

Android携帯は、携帯を横にするとアプリの表示もクルッと回転しますよね。エミュレーターでもctrl+F11で回転します。

回転すると、一度アクティビティが破棄されます。破棄される前に起動しているアプリのデータを保存させる必要があります。回転させる場合はその保存方法などもおぼえる必要があります。

回転させない場合は設定があります。プロジェクトファイルの中に「AndroidManifest.xml」というファイルがあります。内容は下記の黒字のようになってますがそこに赤字のメソッドを加えます。

 

フィル名「AndroidManifest.xml」

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="and.roid"
android:versionCode="1"
android:versionName="1.0" >

<uses-sdk android:minSdkVersion="7" />

<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<activity
android:name=".BotanActivity"
android:label="@string/app_name"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>

</manifest>

portraitー縦向き固定

landscapeー横向き固定

unspecifiedー固定しない

固定していまう場合はデータ保存とかはないのでこの設定をすればいいですね。

次は回転させてそのつど表示を変えるやり方です。今回紹介するやり方は、書籍にかいてある通りなのでわたしにもいまいちわかりませんが、回転機能を使うときに改めて勉強しなすことにします。一応ご紹介。

 

設定が変更された時に「呼び出される

 
  public void onConfigrationChanged(Configration newConfig)  
  このメソッドは、アクティビティの設定が変更されたときに自動的に呼び出されるメソッドです。  
 

引数には、アクティビティの設定を管理するConfigrationというクラスのインスタンスが渡されます。

 
 

インスタンスの状態を保存する

 
  protected void onStateInstanceState(Bundle savedInstanceState)  
  アクティビティが破棄されるときにフィールド値を初期状態にしてしまいます。そこで破棄する前にインスタンスの状態を保管  
  するためのメソッドを用意し、これを呼び出すようになっています。それが  
  onSavedInstanceState メソッドです。引数には Bundle というクラスのインスタンスが渡されます。  
  これを使って、さまざまな値を一時保存できるようになっています。  
 

インスタンスの状態を再現する

 
  protected void onRestoreInstanceState(Bundle outState)  
  新たにアクティビティのインスタンスを作成して画面に表示する際に呼び出されるメソッドです。  
  保管してあったメソッドの状態を、これから使うインスタンスに設定するためのものです。  
  引数に渡される「Bandle」から、一時保存してあった値を撮り出し、新しいプロパティに設定してやることで、前のインスタンスの状態を再現することができます。  
     
  ということで、縦の時は縦長に、横の時は横長に画像を表示するプログラムを書きます。  
     
 

ファイル名「ViewActivity.java」

package and.roid;

import android.app.Activity;
import android.content.res.*;
import android.graphics.Rect;
import android.os.Bundle;
import android.view.*;

public class ViewActivity extends Activity {
private Configuration config;
private int orientation;
private static int[][] areas = new int [][]{
new int[]{5,5,205,305},
new int[]{5,5,305,205}
};
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);

Resources resources = getResources();
config = resources.getConfiguration();
if(config.orientation != Configuration.ORIENTATION_PORTRAIT)
orientation = 1;

setContentView(R.layout.main);
//setContentView(new MyView(this));
}

public void onConfigurationChanged(Configuration newConfig){
super.onConfigurationChanged(newConfig);
config = newConfig;
}

protected void onSaveInstanceState(Bundle savedInstanceState){
super.onRestoreInstanceState(savedInstanceState);
int ori = 0;
if(config.orientation != Configuration.ORIENTATION_PORTRAIT)
ori = 1;
savedInstanceState.putInt("ORIENTATION", ori);
}

protected void onRestoreInstanceState(Bundle outState){
super.onSaveInstanceState(outState);
orientation = outState.getInt("ORIENTATION");
}

public Rect getArea(){
int[] area = areas[orientation];
return new Rect(area[0], area[1], area[2], area[3]);
}
}

 
  わたしはイマイチわからないのですが、このやり方は「普通こんなやり方ではやらない」やり方らしいです。ただ今回のメソッドの使い方などをわかりやすく使用するためのサンプルらしいです。  
 

ファイル名「MyView」

package and.roid;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.*;
import android.graphics.Paint.Style;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.View;

public class MyView extends View {
private ViewActivity context;
private Drawable drawable;

public MyView(Context context) {
this(context,null);
}

public MyView(Context context,AttributeSet attrs){
super(context,attrs);
this.context = (ViewActivity)context;

Resources resources = context.getResources();
drawable = resources.getDrawable(R.drawable.android005);

}

protected void onDraw(Canvas c){
super.onDraw(c);
c.drawColor(Color.WHITE);
if(drawable != null){
drawable.setBounds(context.getArea());
drawable.draw(c);
}

int w = this.getWidth();
int h = this.getHeight();
Paint p = new Paint();
p.setStyle(Style.STROKE);
p.setColor(Color.DKGRAY);
c.drawRect(new Rect(5,5,w-10,h-10), p);
c.drawText("w:"+w+"h:"+h, 50, h-50, p);
}

}

 
  こちらも微妙に変更してありますね。実行すると  
   
   
  こうなりました。とりあえずわたしは固定に頼ることにして、回転機能を使うときにまたおぼえることにします・・・  

 

 

タッチのイベント

 
  たっちゃん・・とか幽体離脱とかじゃないですよ。スマホといえばやはりタッチパネルです。そのタッチイベントの処理を書いていきます。  
  前回のソースコードをちょちょっと改造すればいいみたいなので、ちゃちゃっとやってみます。  
 

ファイル名「MyView.java」

package and.roid;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.*;
import android.graphics.Paint.Style;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

public class MyView extends View {
private ViewActivity context;
private Drawable drawable;
private Rect lastRect;

public MyView(Context context) {
this(context,null);
}

public MyView(Context context,AttributeSet attrs){
super(context,attrs);
this.context = (ViewActivity)context;

Resources resources = context.getResources();
drawable = resources.getDrawable(R.drawable.android005);
lastRect = new Rect(5,5,205,205);
}

protected void onDraw(Canvas c){
super.onDraw(c);
c.drawColor(Color.WHITE);
if(drawable != null){
drawable.setBounds(lastRect);
drawable.draw(c);
}

int w = this.getWidth();
int h = this.getHeight();
Paint p = new Paint();
p.setStyle(Style.STROKE);
p.setColor(Color.DKGRAY);
p.setTextSize(30);
c.drawRect(new Rect(5,5,w-10,h-10), p);
c.drawText(lastRect.toString(), 50, h-50, p);
}

public boolean onTouchEvent(MotionEvent event){
int x = (int)event.getX();
int y = (int)event.getY();
lastRect = new Rect(x-100, y-100, x+100, y+100);
invalidate();
return true;
}

}

 
  ちょっと解説です。  
  onTouchEvent(MotionEvent event)がイベントを処理するコードです。event.で色々取り出したりするわけですね。  
  int x = (int)event.getX();  
  int y = (int)event.getY();  
  でタッチした座標X、Yを取り出しています。  
  そしてその座標を中心として200×200の画像を再描画していますね。  
  invalidate();  
  で画面を更新させるみたいですよ。  
   
     
  上記はタッチした場所の座標を認識して表示させていて、画像そのものをタッチしているわけはありません。  
  しかしViewにはButtonなどは組み込めません。なので自分で作っていくことになります。そしてその「どのエリアをタップした」と  
  いう処理をします。  
 

ファイル名「MyView.java」

package and.roid;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.*;
import android.graphics.Paint.Style;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.*;
import android.widget.Toast;

public class MyView extends View {
private ViewActivity context;
private Drawable drawable;
private Rect rect;
private boolean press;
private boolean selected;

public MyView(Context context) {
this(context,null);
}

public MyView(Context context,AttributeSet attrs){
super(context,attrs);
this.context = (ViewActivity)context;

Resources resources = context.getResources();
drawable = resources.getDrawable(R.drawable.android005);
rect = new Rect(140,140,340,340);
press = false;
selected = false;
}

protected void onDraw(Canvas c){
c.drawColor(Color.WHITE);
if(drawable != null){
drawable.setBounds(rect);
if(press)
drawable.setAlpha(100);
else
drawable.draw(c);
}

int w = this.getWidth();
int h = this.getHeight();
Paint p = new Paint();
p.setStyle(Style.STROKE);
p.setColor(Color.DKGRAY);
p.setTextSize(30);
c.drawRect(new Rect(5,5,w-10,h-10), p);
}

public boolean onTouchEvent(MotionEvent event){
int action = event.getAction();
int x = (int)event.getX();
int y = (int)event.getY();
if(x>rect.left && x<rect.right &&
y>rect.top && y<rect.bottom){
switch(action){
case MotionEvent.ACTION_DOWN:
press = true;
selected = false;
break;
case MotionEvent.ACTION_UP:
press = false;
selected = true;
break;
}
}else{
press = false;
selected = false;
}

invalidate();
if(selected){
selected = false;
showMsg();
}
return true;
}

private void showMsg(){
Toast toast = Toast.makeText(context, "クリックしました", Toast.LENGTH_LONG);
toast.show();
}

}

 
  このプログラムは表示させた画像をボタンとしてみたてて、その領域をタップするとタップしたっぽく色が薄くなるプログラムです。  
  だんだんとややこしくなってきました。ちょっとだけ説明です。  
  int action = event.getAction();
int x = (int)event.getX();
int y = (int)event.getY();
 
  event.getAction();はイベントのアクションというものを取り出すものです。  
  if(x>rect.left && x<rect.right && y>rect.top && y<rect.bottom)  
  オブジェクトrectの座標範囲内にタッチしてるかどうかの判定です。  
  switch(action)  
  でactionの種類によって処理をしてます。  
  ACTION_DOWNは「画面に触れたイベント」  
  ACTION_UPは「画面から離したイベント」  
  invalidate();で画面を更新しています。なにか描画更新したときにはこのメソッドで更新し、なにもしないときはメソッドを呼び出さないようにしています。  
     

ということで、今回はここまでです。

次からは今まで覚えたものでなんとかアプリを作ってみようと思います。

 

Androidプログラミング日記 (仮) | サイトマップ | 個人情報保護方針 | 応援メールテヘペロ | ©2012 Japan  相互リンク大募集中です