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

android OS & iPadOS の記録。

Fragment [基礎] ジェスチャー

2022-09-24 12:19:24 | Android studio 日記

骨子。

【MainActivity.java】

public class MainActivity extends AppCompatActivity {

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

        if (savedInstanceState == null) {
            MainFragment mFragment = MainFragment.newInstance("渡すデータ。文字以外もOK。");
            getSupportFragmentManager().beginTransaction()
                    .replace(R.id.container, mFragment)
                    .commitNow();


            View view = (View)findViewById(R.id.container);
            view.setOnTouchListener((MainFragment)mFragment);
        }
    }
}

 

【fragment_main.xml】com.????.MyImageView/????部分はパッケージ名

< androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/mainFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".ui.main.MainFragment">


    < com.????.MyImageView
        android:id="@+id/main_image"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

 

 

【MainFragment.java】

public class MainFragment extends Fragment implements View.OnTouchListener {

    MyImageView mImageView = null;

    private GestureDetectorCompat mDetector = null;
    class MyGestureListener extends SimpleOnGestureListener {

        @Override
        public boolean onDown(MotionEvent event) {
            return true;
        }

        //他、省略。
    }


    @Override
    public boolean onTouch(View v, MotionEvent event) {
        return mDetector.onTouchEvent(event);
    }

    public static MainFragment newInstance(String name) {

        MainFragment mainFragment = new MainFragment();// インスタンス生成

        Bundle args = new Bundle();// Bundle にパラメータを設定
        args.putString("test", name);// 渡す型に合わせてメソッドを変える
        mainFragment.setArguments(args);

        return mainFragment;
    }

    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
            @Nullable Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_main, container, false);
    }

    @Override
    public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        mDetector = new GestureDetectorCompat(requireContext(), new MyGestureListener());
       
        Bundle args = getArguments();// Bundle にパラメータを取得
        if(args != null ){
            String name = args.getString("test");
            // 受け取った値を処理する
        }

        mImageView = (MyImageView) view.findViewById(R.id.main_image);
        mImageView.setScaleType(ImageView.ScaleType.MATRIX);
        try {
            AssetManager mAssetManager = getResources().getAssets();
            InputStream istream = mAssetManager.open("image/0001.jpg");
            Bitmap mBitmap = BitmapFactory.decodeStream(istream);
            if (mBitmap != null) mImageView.setImageBitmap(mBitmap);
            istream.close();
        } catch (Exception e) {
            ;
        }
    }
}

 


Fragment+ViewModel [基礎] 画像のScroll、Fling

2022-09-24 11:32:12 | Android studio 日記

フラグメントで SimpleOnGestureListener のScroll、Flingを設定。
画像はAssetsフォルダーに用意したものを使用。


【activity_main.xml】
MainActivity.java】は前回のまま。
MyImageView.java


【fragment_main.xml】

追加。<????>は各々のパッケージ名。

< com.????.MyImageView
    android:id="@+id/main_image"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

 


MainFragment.java】前回と同じ部分などは省略

public class MainFragment extends Fragment implements View.OnTouchListener {
    
    private MyImageView mImageView = null;

    private OverScroller mScroller;
    private ValueAnimator scrollAnimator = ValueAnimator.ofFloat(0,1);
    private GestureDetectorCompat mDetector = null;

    class MyGestureListener extends SimpleOnGestureListener {
        @Override
        public boolean onDown(MotionEvent event) {
            if ( !mScroller.isFinished() ) mScroller.abortAnimation();
            scrollAnimator.cancel();
            return true;
        }

        @Override
        public boolean onScroll(MotionEvent event1, MotionEvent event2, float distanceX, float distanceY) {

            if ( mImageView == null ) return true;

            int x = (int) distanceX;
            int cX = (int) distanceX;
            int y = (int) distanceY;
            int cY = (int) distanceY;
            int scrX = mImageView.getScrollX();
            int scrY = mImageView.getScrollY();
            int dx = ( mImageView.getImageWidth() - getScreenWidth() );
            int dy = ( mImageView.getImageHeight() - getScreenHeight() );

            if ( dx > 0 ) {
                if ( x > 0 ) {
                    if ( scrX == dx ) cX = 0;
                    else {
                        int xx = dx - scrX;
                        if ( x >= xx ) cX = xx;
                    }
                } else if ( x < 0 ){
                    if ( scrX == 0 ) cX = 0;
                    else if ( scrX > 0 && -scrX >= x ) cX = -scrX;
                } else cX = 0;
            } else
                cX = 0;

            if ( dy > 0 ) {
                if ( y > 0 ) {
                    if ( scrY == dy ) cY = 0;
                    else {
                        int yy = dy - scrY;
                        if ( y >= yy ) cY = yy;
                    }
                } else if ( y < 0 ){
                    if ( scrY == 0 ) cY = 0;
                    else if ( scrY > 0 && -scrY >= y ) cY = -scrY;
                } else cY = 0;
            } else
                cY = 0;

            mImageView.scrollBy( cX, cY );
            return true;
        }

        @Override
        public boolean onFling(MotionEvent event1, MotionEvent event2, float velocityX, float velocityY) {

            mScroller.fling(
                    mImageView.getScrollX(),
                    mImageView.getScrollY(),
                    (int) (-velocityX),
                    (int) (-velocityY),
                    0, Math.max(0, mImageView.getImageWidth() - getScreenWidth()),
                    0, Math.max(0, mImageView.getImageHeight() - getScreenHeight())
            );
            scrollAnimator.start();
            return true;
        }
    }

    @SuppressLint("ClickableViewAccessibility")
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        return mDetector.onTouchEvent(event);
    }

    @SuppressLint({"FragmentLiveDataObserve", "UseRequireInsteadOfGet", "WrongViewCast"})
    @Override
    public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

一部省略
        mDetector = new GestureDetectorCompat(requireContext(), new MyGestureListener());

        mImageView = (MyImageView) view.findViewById(R.id.main_image);
        mImageView.setScaleType(ImageView.ScaleType.MATRIX);
        try {
            AssetManager mAssetManager = getResources().getAssets();
            InputStream istream = mAssetManager.open("image/0001.jpg");//用意したファイル
            Bitmap mBitmap = BitmapFactory.decodeStream(istream);
            if (mBitmap != null) mImageView.setImageBitmap(mBitmap);
            istream.close();
        } catch (Exception e) {
            ;
        }

        mScroller = new OverScroller( requireContext(),null );
        scrollAnimator = ValueAnimator.ofFloat(0,1);
        scrollAnimator.addUpdateListener(valueAnimator -> {
            if ( !mScroller.isFinished() ) {
                mScroller.computeScrollOffset();
                mImageView.scrollTo( mScroller.getCurrX(), mScroller.getCurrY() );
            } else {
                scrollAnimator.cancel();
            }
        });
    }
}


[メソッド] getScreenHeight()

2022-09-24 11:30:58 | Android studio 日記

デバイスのスクリーン高さのドット数を返す。

    private int getScreenHeight() {
        WindowManager wManager = (WindowManager) requireContext().getSystemService(Context.WINDOW_SERVICE);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            WindowMetrics mWindowMetrics = wManager.getCurrentWindowMetrics();
            return mWindowMetrics.getBounds().height();
        }

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            DisplayMetrics mDisplayMetrics = new DisplayMetrics();
            wManager.getDefaultDisplay().getRealMetrics(mDisplayMetrics);
            return mDisplayMetrics.heightPixels;
        }

        Point realSize = new Point();
        wManager.getDefaultDisplay().getSize(realSize);

        return realSize.y;
    }


[メソッド] getScreenWidth()

2022-09-24 10:36:03 | Android studio 日記

デバイスのスクリーン横幅のドット数を返す。

    private int getScreenWidth() {
        WindowManager wManager = (WindowManager) requireContext().getSystemService(Context.WINDOW_SERVICE);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            WindowMetrics mWindowMetrics = wManager.getMaximumWindowMetrics();
            return mWindowMetrics.getBounds().width();
        }

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            DisplayMetrics mDisplayMetrics = new DisplayMetrics();
            wManager.getDefaultDisplay().getRealMetrics(mDisplayMetrics);
            return mDisplayMetrics.widthPixels;
        }

        Point realSize = new Point();
        wManager.getDefaultDisplay().getSize(realSize);

        return realSize.x;
    }

 


Fragment+ViewModel [基礎] 【MyImageView.java】

2022-09-24 10:12:45 | Android studio 日記

 

基礎クラス。
Bitmap,Drawableを設定した後に画像サイズを取得したいので継承クラスを作った。


【MyImageView.java】
public class MyImageView extends androidx.appcompat.widget.AppCompatImageView {
    public MyImageView(Context context, AttributeSet attrs, int defStyle){
        super(context, attrs, defStyle);
    }
    public MyImageView(Context context, AttributeSet attrs){
        super(context, attrs);
    }
    public MyImageView(Context context){
        super(context);
    }

    private int myImageWidth = 0;
    private int myImageHeight = 0;

    @Override
    public void setImageBitmap(Bitmap bm) {
        if (bm != null) {
            myImageWidth = bm.getWidth();
            myImageHeight = bm.getHeight();
        } else {
            myImageWidth = 0;
            myImageHeight = 0;
        }
        super.setImageBitmap(bm);
    }
    @Override
    public void setImageDrawable(Drawable drawable) {
        if (drawable != null) {
            myImageWidth = drawable.getIntrinsicWidth();
            myImageHeight = drawable.getIntrinsicHeight();
        } else {
            myImageWidth = 0;
            myImageHeight = 0;
        }
        super.setImageDrawable(drawable);
    }
    public int getImageWidth() {
        return myImageWidth;
    }
    public int getImageHeight() {
        return myImageHeight;
    }
}