たったコレだけの事にアホみたいに時間を費やしてしまいました。
背景をページ数で割ってそれぞれのページの背景画像として設定したらいいじゃん。って簡単な話ではなかったんですよ、コレが。
今回、困ったのが次の仕様。
・画面数が動的に増減する。
・背景に使う画像のサイズは特に決まっていない。デザインによってサイズが違う。
この条件で、最初のページから最後のページまでの移動で、ぴったり画像の端から端まで移動させたい。
イメージはこんな感じ。
画面切り替えはViewPagerを使います。
んで、背景画像はアスペクト比をそのままに画面の高さに合わせることにします。
ViewPagerの詳細な使い方はググってください。
とりあえず、背景に画像を設定し、その上に簡単なViewPagerを重ねてみます。
ただし、背景を見えるようにしたいので、ViewPagerの背景は透明としています。
public class CustomAdapter extends PagerAdapter {
private Context mContext;
private ArrayList mList;
public CustomAdapter(Context context) {
mContext = context;
mList = new ArrayList();
}
public void add(Integer item) {
mList.add(item);
}
@Override
public Object instantiateItem(View container, int position) {
// リストから取得
Integer item = mList.get(position);
// View を生成
TextView textView = new TextView(mContext);
textView.setText(position + "ページ");
textView.setTextSize(50);
textView.setTextColor(item);
textView.setGravity(Gravity.CENTER);
// コンテナに追加
((ViewGroup) container).addView(textView);
// 背景を透明にする(第一引数が0ならOK)
container.setBackgroundColor(Color.argb(0, 0, 0, 0));
return textView;
}
@Override
public void destroyItem(View container, int position, Object object) {
((ViewGroup) container).removeView((View) object);
}
@Override
public int getCount() {
// リストのアイテム数を返す
return mList.size();
}
@Override
public boolean isViewFromObject(View view, Object object) {
// Object 内に View が存在するか判定する
return view == (TextView) object;
}
}
public class MainActivity extends Activity {
private ImageView imageView;
private Bitmap img;
private float displayW;
private float displayH;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// カスタム PagerAdapter を生成
CustomAdapter adapter = new CustomAdapter(this);
adapter.add(Color.RED);
adapter.add(Color.GREEN);
adapter.add(Color.BLUE);
adapter.add(Color.BLACK);
adapter.add(Color.WHITE);
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
displayW = metrics.widthPixels;
displayH = metrics.heightPixels;
// まずは画像を読み込まずに画像情報だけを取得する
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true; // 画像そのものは読み込まない設定
BitmapFactory.decodeResource(getResources(), R.drawable.wall, options);
// アスペクト比をそのままに、どの端末でも同じように表示させる(縦に合わせる)
int bmpNativeHeight = options.outHeight;
float dpiRatio = bmpNativeHeight / displayH;
float calcDpi = metrics.densityDpi * dpiRatio;
if (img == null || img.isRecycled()) {
options.inJustDecodeBounds = false;
options.inDensity = (int) calcDpi;
img = BitmapFactory.decodeResource(getResources(), R.drawable.wall, options);
}
imageView = new ImageView(this);
imageView.setImageBitmap(img);
imageView.setScaleType(ScaleType.MATRIX);
addContentView(imageView, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
// ViewPager を生成
ViewPager viewPager = new ViewPager(this);
viewPager.setAdapter(adapter);
addContentView(viewPager, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
}
ここでのポイントは、
・ViewPagerの背景を透明にする
・背景画像のImageViewのScaleTypeをMATRIXに指定する
となります。
背景は動きませんが、とりあえず動かしたい背景画像の上にViewPagerを乗せてみました。
ちなみにAndroidアプリをほどんど開発した事が無い私は、この「背景をどの端末でも同じに見えるようにdpiを合わせる」というのにも悩みまくりました。
これをしないと端末によって背景が拡大表示されたりするので注意してください。
次はViewPagerでページを切り替える度に背景が移動していく箇所を実装していきます。

0 件のコメント:
コメントを投稿