タブレット用プログラムの書き止め

android OS & iPadOS の記録。

ViewSwitcher の ImageView の Padding 設定

2021-06-23 17:00:02 | Android studio 日記

 勘違いでImageViewの画像サイズ取得値が間違っていた。Margin設定で複雑に考えていた。これらを正規値を取得、Padding設定でシンプル変更に変えたところ満足する内容になった。

 デバイスサイズより画像サイズが小さい時に余白部分を計算して、半分ずつPadding設定。

 

            Bitmap mBitmap = BitmapFactory.decodeStream(istream);   // ビットマップへデコード

            if (mBitmap != null) {
                mView.setImageBitmap( mBitmap );                  // イメージビューにビットマップ登録

                int dx = mBitmap.getWidth();
                if ( dx < displayWidth ) {
                    dx = ( displayWidth - dx ) / 2;                        // 余白の半分
                } else dx = 0;                                                   // サイズが大きい時は余白0

                int dy = mBitmap.getHeight();
                if ( dy < displayHeight ) {
                    dy = ( displayHeight - dy ) / 2;
                } else dy = 0;

                mView.setPaddingRelative( dx, dy, dx, dy );         // イメージビューにパディング設定

            }

 ビュースイッチャーを使い、フルスクロールの下にイメージビューがある。そして、画面サイズより小さい画像を中央に表示したい場合は、プログラムで Padding設定をする。

 

 

プログラム =========================================================

【 FullscreenActivity.java 】

public class FullscreenActivity extends AppCompatActivity {


    private int displayWidth, displayHeight;      // デバイスのサイズ
    private int targetIndexNo;                          // ファイル名リスト配列のインデックスNO

            // ファイル名リスト配列。カスタムソート用
    private final ArrayList< MyNumbersInString> mFileNameList = new ArrayList< >();

    private boolean viewFlag;                                // ビュースイッチャー用
    private ViewSwitcher mViewSwitcher;              // ビュースイッチャー

    private MyScrollView mMSV1, mMSV2;           // ビュースイッチャー設定用
    private ImageView imageView1, imageView2;  // レイアウト組み込みイメージビュー

            // シンプルタッチイベント用
    private GestureDetectorCompat mDetector;
    private final MyGestureListener mGestureListener = new MyGestureListener();

    private AssetManager mAssetManager;           // assetsフォルダアクセス


    // ******************************************************************


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_fullscreen);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { // OSによりデバイスサイズの求め方が違う
            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;
        }

            // ビュースイッチャー登録準備
        mMSV1 = (MyScrollView) getLayoutInflater().inflate(R.layout.image1, null);
        mMSV2 = (MyScrollView) getLayoutInflater().inflate(R.layout.image2, null);

            // スイッチャー設定
        mViewSwitcher = (ViewSwitcher) findViewById( R.id.viewSwither );
        mViewSwitcher.addView( mMSV1, 0 );
        mViewSwitcher.addView( mMSV2, 1 );

            // 切り替え時のアニメーション
        mViewSwitcher.setInAnimation(AnimationUtils.loadAnimation( this, android.R.anim.fade_in));
        mViewSwitcher.setOutAnimation(AnimationUtils.loadAnimation( this, android.R.anim.fade_out));

            // イメージのレイアウト情報設定。ビットマップは後で設定
        imageView1 = findViewById(R.id.image_view1);
        imageView2 = findViewById(R.id.image_view2);

            // assetsフォルダ情報登録
        mAssetManager = getResources().getAssets();


            // フルスクリーン表示 ------------------
        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);
            // ---------------------------------------

 


            // 本来、ディレクトリ絶対パスを渡す。画像ファイル名をリストアップ
        setFileNameList( mAssetManager );

        viewFlag = true;            // 初期化
        targetIndexNo = 0;

            // イメージビューにビットマップを設定。本来はフルパスを渡す
        setImage( imageView1, "image/" + mFileNameList.get(0).getName() );
        setImage( imageView2, "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() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            return false;
        }
    };

            // とりあえず、ダブルタップがシングルタップに飛び込まないように
    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() ) {      // indexをインクリメント
                        targetIndexNo = 0;
                    }
                    if ( viewFlag ) {            // image1が表示されているので image2にセット
                        setImage( imageView2, "image/" + mFileNameList.get(targetIndexNo).getName() );
                        viewFlag = false;     // image2 表示フラグセット
                    } else {
                        setImage( imageView1, "image/" + mFileNameList.get(targetIndexNo).getName() );
                        viewFlag = true;
                    }
                    mViewSwitcher.showNext();   // 次を表示
                } else {
                    if ( --targetIndexNo < 0 ) {
                        targetIndexNo = mFileNameList.size() - 1;
                    }
                    if ( viewFlag ) {                       // image1が表示されているので image2にセット
                        setImage( imageView2, "image/" + mFileNameList.get(targetIndexNo).getName() );
                        viewFlag = false;
                    } else {
                        setImage( imageView1, "image/" + mFileNameList.get(targetIndexNo).getName() );
                        viewFlag = true;
                    }
                    mViewSwitcher.showPrevious(); // 前を表示
                }
            }
            doubleTapFlag = false;                      // リセット
            return false;
        }

        @Override
        public boolean onDoubleTap(MotionEvent e) {
            doubleTapFlag = true;                        // セット。return true; でもいいのかな・・
            return false;
        }
        @Override
        public boolean onSingleTapUp(MotionEvent e) {
            doubleTapFlag = false;                       // リセット
            return false;
        }
    };

            // ファイル名リストアップ。
    private void setFileNameList( AssetManager am ) {

        String fName;
        String[] mList = new String[0];
        try {
            mList = am.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< MyNumbersInString>() {
                    @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 = BitmapFactory.decodeStream(istream);   // ビットマップへデコード

            if (mBitmap != null) {
                iView.setImageBitmap( mBitmap );                    // イメージビューにビットマップ登録

                int dx = mBitmap.getWidth();
                if ( dx < displayWidth ) {<br />                    dx = ( displayWidth - dx ) / 2;
                } else dx = 0;

                int dy = mBitmap.getHeight();
                if ( dy < displayHeight ) {<br />                    dy = ( displayHeight - dy ) / 2;
                } else dy = 0;

                iView.setPaddingRelative(dx,dy,dx,dy);               // イメージビューにパディング設定

            }
            istream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

 

【 MyNumbersInString.java 】

public class MyNumbersInString {
    private String name1 = ""; // 元のファイル名
    private String name2 = ""; // 漢字、数字混在のとき、半角数字を前方を"0"で埋めた8桁に修正

    /*
        ArrayList<> で、ファイル名をソートするための準備。name2を判定条件に使う
    **/

    public MyNumbersInString( String name ){
        name1 = name;

        StringBuilder sb = new StringBuilder(name);
        String[] msplit1 = sb.toString().split( "[^\\d]" ); // 数字以外で分割
        String[] msplit2 = sb.toString().split( "\\d" );     // 数字で分割

        boolean mFlag = true;
        sb = new StringBuilder();

        // 1つの文字列を同条件反転分割しているので[0]のみ、どちらか必ず文字が入っている

        if (msplit1[0].length() == 0) {
            mFlag = true;
            sb.append(msplit2[0]);                                  // 文字を積む
        }
        if (msplit2[0].length() == 0) {
            mFlag = false;
            sb.append( zeroCompensation( msplit1[0]) ); // 0補填をして数字を積む
        }

        // 数字の次は文字、文字の次は数字、フラグで切り替え積んでいく。数字は0補填
        int i = 0, j = 0, len;
        while ( ( i
            if (mFlag) {                                      // 直前が数字でなかった
                if ( ++i
                    if (msplit1[i].length() != 0) {      // 数字が現れた
                        sb.append( zeroCompensation( msplit1[i] ) );
                        mFlag = false;
                    }
                }
            } else {                                              // 直前が文字でなかった
                if ( ++j
                    if (msplit2[j].length() != 0) {       // 文字が現れた
                        sb.append(msplit2[j]);
                        mFlag = true;
                    }
                }
            }
        }

        name2 = sb.toString();
    }
    public String getName(){
        return name1;
    }
    public String getName2(){
        return name2;
    }

    private String zeroCompensation(String text){
        StringBuilder sb = new StringBuilder();
        int len = text.length();                 // 桁数
        if ( len < 8 ) {                              // 8桁以下なら0を前に付けて8桁に合わせる
            len = 8 - len;
            for (int c = 0; c
                sb.append("0");
            }
        }
        sb.append( text );
        return sb.toString();
    }
}

 

 

【 MyScrollView.java 】


public class MyScrollView extends ScrollView {

    public MyScrollView(Context context, AttributeSet attrs, int defStyle){
        super(context, attrs, defStyle);
    }

    public MyScrollView(Context context, AttributeSet attrs){
        super(context, attrs);
    }

    public MyScrollView(Context context){
        super(context);
    }

    @Override
    public void requestDisallowInterceptTouchEvent(boolean disallowIntercept){

    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent event){
        onTouchEvent(event);
        return false;
    }
}


注意:半角“<”を全角“<”に置換。手抜き。


【 activity_fullscreen.xml 】

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="?attr/fullscreenBackgroundColor"
    android:theme="@style/ThemeOverlay.MyTest2.FullscreenContainer"
    tools:context=".FullscreenActivity">


       <ViewSwitcher
           android:id="@+id/viewSwither"
           android:layout_width="wrap_content"
           android:layout_height="wrap_content" />

</RelativeLayout>

 

※ ”com.????.mytest2” この部分は各々のパッケージネーム

【 image1.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="wrap_content"
    android:layout_height="wrap_content" >

    <HorizontalScrollView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" >

        <LinearLayout
            android:id="@+id/L_Layout1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            tools:ignore="ObsoleteLayoutParam">

            <ImageView
                android:id="@+id/image_view1"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                tools:ignore="ContentDescription" />

        </LinearLayout>
    </HorizontalScrollView>
</com.????.mytest2.MyScrollView>

 


【 image2.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="wrap_content"
    android:layout_height="wrap_content" >

    <HorizontalScrollView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" >

        <LinearLayout
            android:id="@+id/L_Layout2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            tools:ignore="ObsoleteLayoutParam">

            <ImageView
                android:id="@+id/image_view2"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                tools:ignore="ContentDescription" />

        </LinearLayout>
    </HorizontalScrollView>
</com.????.mytest2.MyScrollView>

 

 画像のリアルサイズモード、フィットサイズモード切り替え。設定用アクティビティーの組み込み。色々。

 

 

 

参考文献

Android Studio : ViewSwitcher とフリックによる画面切り替え。
ViewSwitcherで2つのViewをなめらかに切り替える。
【Android】画面タッチイベントを実装する。
【 Android アプリ開発 】全画面表示を行う方法 ( 通知バー非表示 )
Android: 画面サイズよりも大きいViewを縦/横/斜めでスクロールする。



 

 

 

この記事についてブログを書く
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする
« fullscroll やり直し? | トップ | なぜか、ImegeView の scaleT... »

Android studio 日記」カテゴリの最新記事