【 ViewSwitcher 】 フルスクリーン、フルスクロール、ファイル名リストアップ、タップ処理、ここまでできたのでファイル名のリスト順に画像を切り替えるプログラムにまとめる。
自前で画像の切り替えをしようと思ったが、イメージスイッチャー、ビュースイッチャーを見つけた。切り替えのアニメーションが揃っていて面白そうなので利用する。全体の動作チェックなのでフェードイン、アウトを使う。設定が楽だから。
とりあえず、通しで。
【MainActivity.java】
public class MainActivity extends AppCompatActivity {
// デバイス画面サイズ、Width、Height
private int displayWidth, displayHeight;
// Assetsフォルダ操作用
private AssetManager mAssetManager;
// ファイル名リスト用index
private int targetIndexNo;
// ファイル名リスト、ソート用
private final ArrayList<MyNumbersInString> mFileNameList = new ArrayList<>();
// viewswitcher切り替えビュー把握用フラグ
private boolean viewFlag;
// ビュースイッチャー
private ViewSwitcher mViewSwitcher;
// viewswitcher割り当てイメージビュー
private ImageView mImageView1, mImageView2;
// viewswitcher割り当てレイアウト
private LinearLayout mL_Layout1, mL_Layout2;
// シンプルタップアクション取得用
private GestureDetectorCompat mDetector;
private MyGestureListener mGestureListener = new MyGestureListener();
// ******************************************************************
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// フルスクリーン表示
View decorView = getWindow().getDecorView();
int uiOptions;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
uiOptions = View.SYSTEM_UI_FLAG_LOW_PROFILE
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION ;
} else {
uiOptions = View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE ;
}
decorView.setSystemUiVisibility(uiOptions);
// OSによりデバイスサイズの求め方が違うらしい
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
WindowMetrics mWindowMetrics = this.getWindowManager().getCurrentWindowMetrics();
displayWidth = mWindowMetrics.getBounds().width();
displayHeight = mWindowMetrics.getBounds().height();
} else {
WindowManager mWindowManager = (WindowManager)getSystemService(WINDOW_SERVICE);
Display mDisplay = mWindowManager.getDefaultDisplay();
Point mRealSize = new Point();
mDisplay.getRealSize(mRealSize);
displayWidth = mRealSize.x;
displayHeight = mRealSize.y;
}
// ビュースイッチャーに image1.xml image2.xml を設定する
viewFlag = true;
LinearLayout mL_Layout1 = (LinearLayout) getLayoutInflater().inflate(R.layout.image1, null);
LinearLayout mL_Layout2 = (LinearLayout) getLayoutInflater().inflate(R.layout.image2, null);
mViewSwitcher = (ViewSwitcher) findViewById( R.id.viewSwither );
mViewSwitcher.addView(mL_Layout1);
mViewSwitcher.addView(mL_Layout2);
mViewSwitcher.setInAnimation(AnimationUtils.loadAnimation( this, android.R.anim.fade_in));
mViewSwitcher.setOutAnimation(AnimationUtils.loadAnimation( this, android.R.anim.fade_out));
// 画像ファイル差し替え用
mImageView1 = findViewById(R.id.image_view1);
mImageView2 = findViewById(R.id.image_view2);
// Assetsフォルダ操作用
mAssetManager = getResources().getAssets();
// Assetsフォルダ内imageフォルダの画像ファイル名をリスト化
setFileNameList();
targetIndexNo = 0;
// ファイル名から画像をイメージビューに設定する
setImage( mImageView1, "image/" + mFileNameList.get(0).getName() );
setImage( mImageView2, "image/" + mFileNameList.get(1).getName() );
// ビュースイッチャーにタッチイベントリスナーを取り付け
mViewSwitcher.setOnTouchListener( MyTouchEventListener );
mDetector = new GestureDetectorCompat(this, mGestureListener );
mDetector.setOnDoubleTapListener( mGestureListener );
}
// ディスパッチ設定
@Override
public boolean dispatchTouchEvent( MotionEvent event ) {
super.dispatchTouchEvent(event);
mDetector.onTouchEvent(event);
return super.onTouchEvent(event);
}
// タッチリスナー設定
private final View.OnTouchListener MyTouchEventListener = new View.OnTouchListener() {
@SuppressLint("ClickableViewAccessibility")
@Override
public boolean onTouch(View v, MotionEvent event) {
return false;
}
};
// ダブルタップフラグ。onDoubleTap(){return true;}で良いのかも知れない
private boolean doubleTapFlag = false;
// シンプルタップリスナーオーバーライド
class MyGestureListener extends GestureDetector.SimpleOnGestureListener {
@Override
public boolean onSingleTapConfirmed(MotionEvent e) {
if( !doubleTapFlag ) {
if ( (int) e.getRawX() > ( displayWidth / 2 ) ) { // 画面の右側をタップ
if ( ++targetIndexNo >= mFileNameList.size() ) {
targetIndexNo = 0;
}
if ( viewFlag ) { // image1が表示されているので image2にセット
setImage( mImageView2, "image/" + mFileNameList.get(targetIndexNo).getName() );
viewFlag = false; // 表示判定フラグ書き換え
} else {
setImage( mImageView1, "image/" + mFileNameList.get(targetIndexNo).getName() );
viewFlag = true;
}
mViewSwitcher.showNext(); // 次を表示切替え
} else { // 画面の左側をタップ
if ( --targetIndexNo < 0 ) {
targetIndexNo = mFileNameList.size() - 1;
}
if ( viewFlag ) { // image1が表示されているので image2にセット
setImage( mImageView2, "image/" + mFileNameList.get(targetIndexNo).getName() );
viewFlag = false;
} else {
setImage( mImageView1, "image/" + mFileNameList.get(targetIndexNo).getName() );
viewFlag = true;
}
mViewSwitcher.showPrevious(); // 前を表示切替え
}
}
doubleTapFlag = false;
return false;
}
@Override
public boolean onDoubleTap(MotionEvent e) {
doubleTapFlag = true;
return false;
}
@Override
public boolean onSingleTapUp(MotionEvent e) {
doubleTapFlag = false;
return false;
}
};
// 画像がデバイス画素数よりはるかに大きい時に縮小してBitmapを返す。
private Bitmap bitmapDimension(InputStream istream){
BitmapFactory.Options mOptions = new BitmapFactory.Options();
mOptions.inJustDecodeBounds = true;
Bitmap mBitmap = BitmapFactory.decodeStream(istream, null, mOptions);//bitmapは取得されない
float mX = (float)mOptions.outWidth / (float)displayWidth;;
float mY = (float)mOptions.outHeight / (float)displayHeight;;
if( mX >= 8.0 || mY >= 8.0 ){
mOptions.inSampleSize = 4;
} else if( mX >= 4.0 || mY >= 4.0 ){
mOptions.inSampleSize = 2;
} else mOptions.inSampleSize = 1;
mOptions.inJustDecodeBounds = false;
return BitmapFactory.decodeStream(istream, null, mOptions);
}
// "Assets/image" 内のファイル名をリストアップ
private void setFileNameList() {
String fName;
String[] mList = new String[0];
try {
mList = mAssetManager.list("image");
} catch (IOException e) {
e.printStackTrace();
}
for (String s : mList) {
fName = s;
fName.toLowerCase(); //小文字に変換
if ( fName.endsWith(".jpg") || fName.endsWith(".png")) { //画像ファイル選択
mFileNameList.add( new MyNumbersInString(s) );
}
}
Collections.sort( // 数字の文字列を数値の順番としてソートする
mFileNameList, new Comparator() {
@Override
public int compare(MyNumbersInString mn1, MyNumbersInString mn2) {
return mn1.getName2().compareTo( mn2.getName2() );
}
}
);
}
// 画像ファイル名からイメージビューへ画像データを設定する
private void setImage( ImageView iView, String fName ) {
try {
InputStream istream = mAssetManager.open(fName);
Bitmap mBitmap = bitmapDimension(istream);
if (mBitmap != null) iView.setImageBitmap(mBitmap);
istream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
※ “<”半角 を “<”全角 に変更しています。半角はhtml文書変換で誤変換されて無表示になる。
【activity_main.xml】
<?xml version="1.0" encoding="utf-8"? >
<com.????.mytest2.MyScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:theme="@style/ThemeOverlay.MyTest2.MainContainer" >
<HorizontalScrollView
android:id="@+id/H_scroll"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center" >
<ViewSwitcher
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/viewSwither"
tools:ignore="ScrollViewSize" />
</HorizontalScrollView>
</com.????.mytest2.MyScrollView >
※ ”com.????.mytest2” この部分は各々のパッケージネーム
スイッチャー設定に使う。
【image1.xml】
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<ImageView
android:id="@+id/image_view1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:contentDescription="full screen mode"
tools:ignore="HardcodedText" />
</LinearLayout>
【image2.xml】
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<ImageView
android:id="@+id/image_view2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:contentDescription="full screen mode"
tools:ignore="HardcodedText" />
</LinearLayout>
あと、基本的な画像サイズの変更も組み込む。2本の指で画面上を狭めたり広げたりでサイズを変更する。
><:画面サイズより画像サイズが大きいとき小さくして画面サイズに合わせる。
画面サイズより画像サイズが小さいときリアルサイズで表示する。
<>:画面サイズより画像サイズが大きいときリアルサイズで表示する。
画面サイズより画像サイズが小さいとき大きくして画面サイズに合わせる。
タッチアクションで画像切り替えをスライドアニメーションで実行する。
参考文献
Android Studio : ViewSwitcher とフリックによる画面切り替え
ViewSwitcherで2つのViewをなめらかに切り替える