2011年3月26日土曜日

Android -- 縦横描画の切り替え

■xmlで画面描画している場合


main.xmlで縦横の固定するかを管理するときは、AndroidManifest.xmlの以下configChangesを指定。






  • portrait   縦固定
  • landscape  横固定
  • unspecified  固定なし(デフォルト)
実際には固定なしの場合以下のxmlから作られた描画クラスが使用される。

縦 ⇒ res/layout/xxx.xml
横 ⇒ res/layout-land/xxx.xml

■Viewクラス作成時

Activityクラスで縦、横が切り替わったことは判断できるので、その場合に
Viewクラスの表示内容を切り替える。以下使用するActivity。

// 設定が変更されたとき
    public void onConfigurationChanged(Configuration conf){
     super.onConfigurationChanged(conf);
    }
// インスタンスの状態保管
    public void onSaveInstanceState(Bundle savedInstanceState){
     super.onRestoreInstanceState(savedInstanceState);
    }
// インスタンスの状態を再現する
    public void onRestoreInstanceState(Bundle outState){
     super.onSaveInstanceState(outState);
    }

画面を縦から横にしたときに呼び出される順番。

  1. onSavexxx(変更時の値を保持)
  2. onCreate(Activity作成しなおし)
  3. onRestore(再作成時の処理)

以下、ソースを表示。
MyViewerActivity
public class MyViewerActivity extends Activity {
 static final String TAG = "MyViewerActivity";

 private Configuration config;
 private int orientation;
 private static int[][] areas = new int[][]{
  new int[]{5,5,200,200},
  new int[]{5,5,300,300}
 };

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
     Log.d(TAG, "onCreate");
        super.onCreate(savedInstanceState);

        // Winddowsの変更
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);

        // 環境情報取得
        Resources resouces = getResources();
        config = resouces.getConfiguration();

        if (config.orientation != Configuration.ORIENTATION_PORTRAIT) {
         orientation = 1;
        }

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

    @Override
    // 設定が変更されたとき
    public void onConfigurationChanged(Configuration conf){
     super.onConfigurationChanged(conf);
     Log.d(TAG, "config");
     this.config = conf;
    }

    @Override
    // インスタンスの状態保管
    public void onSaveInstanceState(Bundle savedInstanceState){
     Log.d(TAG, "onSave");
     super.onRestoreInstanceState(savedInstanceState);
     int ori = 0;
     // 縦表示じゃないばあい
     if (config.orientation != Configuration.ORIENTATION_PORTRAIT) {
      ori = 1;
     }
     Log.d(TAG, "orient=" + ori);
     savedInstanceState.putInt("ORIENTATION", ori);
    }

    @Override
    // インスタンスの状態を再現する
    public void onRestoreInstanceState(Bundle outState){
     Log.d(TAG, "onRestore");
     super.onSaveInstanceState(outState);
     orientation = outState.getInt("ORIENTATION");
    }

    public Rect getArea() {
     Log.d(TAG, "getArea");
     int[] area = areas[orientation];
     return new Rect(area[0],area[1],area[2],area[3]);
    }
}
MyViewクラス
public class MyView extends View{
 private MyViewerActivity context;
 private Drawable drawable;

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

 // main.xml使用時はこっちが呼ばれる
 public MyView(Context context, AttributeSet attrs) {
  super(context);
  this.context = (MyViewerActivity)context;

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

 protected void onDraw(Canvas c) {
  super.onDraw(c);
  c.drawColor(Color.GREEN);
  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);
 }
}

0 件のコメント:

試験結果

昨日の夜、CGーArtsエンジニアのベーシック、エキスパートの自己採点をした。 実は日曜日には回答が出ていたけど、自信がなく採点するのもやめようかと思っていたがタイミング&勢いでやってしまった。 <結果>  ベーシック:85点  エキスパート:72.5点 70点以上で合格なので...