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

android OS & iPadOS の記録。

息抜き。imageViewのスクロール。View.scrollBy()

2021-09-25 23:26:20 | Android studio 日記

今までの指をスライド中は範囲外の空白が出ても画像が付いて回るものから、画像の端になったらスライドせずに止まるものを考えた。

 


    float mTouchX, mTouchY;
    boolean mImageScrollFlag = false;

    @Override
    public boolean onTouchEvent(MotionEvent event) {

        switch ( event.getActionMasked() ) {
            case MotionEvent.ACTION_DOWN:
                mTouchX = event.getX();
                mTouchY = event.getY();
                break;

            case MotionEvent.ACTION_MOVE:
                mImageScrollFlag = true;
                float x = event.getX();
                float y = event.getY();
                scrollImage( imageView1, (mTouchX-x), (mTouchY-y) );
                mTouchX = x;
                mTouchY = y;
                return true;

            case MotionEvent.ACTION_UP:
                if ( mImageScrollFlag ) {
                    mImageScrollFlag = false;
                    return true;
                }

                break;
        }
        return super.onTouchEvent(event);
    }

    private void scrollImage ( MyImageView view, float x, float y ) {

        int cX = (int) x;
        int cY = (int) y;
        int sw = getScreenWidth();
        int sh = getScreenHeight();
        int iw = view.getImageWidth();
        int ih = view.getImageHeight();
        int scrX = view.getScrollX();
        int scrY = view.getScrollY();

        int dx = ( iw - sw );
        int dy = ( ih - sh );

        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;

        view.scrollBy( cX, cY );
    }

 

 


  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

基礎。2枚の画像をbitmapで用意して1枚のbitmapに合成する。

2021-09-24 02:37:29 | Android studio 日記

ランドスケープが有ったら1枚表示にする。今回はそのままのサイズで横並び。

・画像サイズを取得して、並べる大きさのbitmapを用意する。
・そのbitmapをCanvas指定して、画像のbitmapを書き込む。
・合成したbitmapをimageViewにセットする。

InputStreamは2度目の使用の時にシークすれば使い回しができるのかな。後で試そう。

 

    private int setImage_2p( MyImageView view, String fName1, String fName2 ) {

        if ( fName1 == null ) return 0;
        File f1 = new File( fName1 );
        if ( !f1.exists() || !f1.isFile() ) return 0;
        if ( fName2 == null ) {
            setImage( view, fName1 );
        } else {

            File f2 = new File( fName2 );
            try {
                InputStream istream1 = new FileInputStream(f1);
                Bitmap mBitmap = BitmapFactory.decodeStream(istream1);
                int width1 = mBitmap.getWidth();
                int height1 = mBitmap.getHeight();
                if ( getImageShape( width1, height1 ) == Configuration.ORIENTATION_LANDSCAPE ) {
                    setImage_2p( view, mBitmap );
                    istream1.close();
                    return 1;
                }
                if ( !f2.exists() || !f2.isFile() ) {
                    setImage_2p( view, mBitmap );
                    istream1.close();
                    return 1;
                }
                BitmapFactory.Options mOptions = new BitmapFactory.Options();
                mOptions.inJustDecodeBounds = true;
                InputStream isop = new FileInputStream(f2);// サイズ取得オンリー
                Bitmap bmop = BitmapFactory.decodeStream( isop, null, mOptions );
                int width2 = mOptions.outWidth;
                int height2 = mOptions.outHeight;
                isop.close();
                bmop = null;
                mOptions = null;

                if ( getImageShape( width2, height2 ) == Configuration.ORIENTATION_LANDSCAPE ) {
                    setImage_2p( view, mBitmap );
                    istream1.close();
                    return 1;
                }

                Bitmap synBitmap =
                      Bitmap.createBitmap( ( width1 + width2 ), Math.max( height1, height2 ), Bitmap.Config.ARGB_8888);
                Canvas c = new Canvas( synBitmap );
                c.drawBitmap( mBitmap, 0, 0, null );

                InputStream istream2 = new FileInputStream(f2); // InputStreamは一度使うと二度目に問題が起こるので新規取得
                Bitmap mBitmap2 = BitmapFactory.decodeStream(istream2);
                c.drawBitmap( mBitmap2, width1, 0, null );

                view.setImageBitmap(synBitmap);
                view.scrollTo(0, 0);
                setPaddingImageView(view, synBitmap.getWidth(), synBitmap.getHeight());

                c = null;
                istream1.close();
                istream2.close();
                mBitmap.recycle();
                mBitmap = null;
                mBitmap2.recycle();
                mBitmap2 = null;
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
        return 2;
    }
    private void setImage_2p( MyImageView view, Bitmap bm ) {
        if ( bm == null ) return;
        view.setImageBitmap(bm);
        view.scrollTo( 0,0 );
        setPaddingImageView( view, bm.getWidth(), bm.getHeight() );
    }

 

追記、InputStreamにシークは無い。スキップとマークがあるが分かりにくいので、新規取得が早い。
ⅽlose()を忘れないようにする事。

 


  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

迷想、scrollView と View.scroll

2021-09-23 15:42:03 | Android studio 日記

2枚の画像ファイルを並べて同時に表示させる場合。layoutViewにimageViewを2つ設置して画像ファイルを読み込む。スクロールさせたければ、このレイアウトビューをScrollViewの子にすれば良い。簡単。
ただ、タッチイベントで思い通りの動作が望めない。

一枚のimageViewなら、imageView.scrollBy() でスクロールできる。タップ処理も理解の範囲内。
だけど、並べて2枚同時・・・、レイアウトビューに2枚並べてレイアウトビューをスクロールすればいいんじゃね?と思うが結果は、失敗。
レイアウトビューで表示されている部分だけがスクロールされ、はみ出し部分の画像は空白表示。ScrollViewは、はみ出て見えていない部分の画像もスクロールされて出てくる。

このままではどちらも思うような結果を求められない。
・ScrollViewの使えるタップ部分を限定して動作、機能を省く。
・View.scroll を工夫(2枚を1枚に合成)する。

合成時間など、処理に関わる事の検証をしてみる。

・縦長は2枚並べて、横長は1枚表示させる。スクロール込み。


  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

基礎。画像サムネイル表示。追加、OnClickListener()

2021-09-20 08:30:49 | Android studio 日記

サムネイル表示は問題なさそうなのでタップ処理を組み込む。
imageViewにOnClickListener()を組み込む理屈は分かるが、どのタイミング、どの場所でが良く分からない。
試行錯誤の末、テストでメインクラスで処理をさせるから、内容宣言はメインクラス、貼り付け場所はMyThumbnailImagesクラスという事になった。

MainActivity.java(部分省略)

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

        View.OnClickListener ocl = new View.OnClickListener(){ // 宣言
            @Override
            public void onClick(View v) {
                String fileName = mThumbnailImages.getTapThumbnailName( v );
                // 処理を書く
            }
        };

        mR_Layout = (RelativeLayout)findViewById( R.id.thumbnail_image );
        mThumbnailImages = new MyThumbnailImages( this, mR_Layout, ocl ); // OnClickListener()渡す
        initThumbnail ();
    }

 

インスタンス時にOnClickListener()を渡す。

MyThumbnailImages.java

public class MyThumbnailImages {
    private static final int THUMBNAIL_WIDTH = 144;
    private static final int THUMBNAIL_HEIGHT = 144;
    private static final int TEXT_MARGIN = 5;
    private static final int TEXT_HEIGHT = 32;
    private int mScreenWidth, mScreenHeight;

    private int mColumn = 0, mRow = 0;
    private int mMarginWidth = 10, mMarginHeight = 30;
    private int viewId = 0;

    private RelativeLayout r_Layout= null;
    private ArrayList< ImageView > thumbnailImage = new ArrayList<>();
    private ArrayList< TextView > thumbnailText = new ArrayList<>();
    private View.OnClickListener mOnClickListener = null;

// コンテキスト、レイアウト、タップ関連を受け取る

    public MyThumbnailImages ( Context context, RelativeLayout rl, View.OnClickListener ocl ) {

        if ( rl == null ) return;
        mOnClickListener = ocl; // 一時保管
        r_Layout = rl;
        viewId = getViewId( rl );
        getScreenSize( context );
        init( context, rl );
    }

// 部分省略
// 確保された画像を入れるためのImageViewへ OnClickListener()を設定。

    private void setThumbnailImageView( ImageView iv, int id ) {
        iv.setId(id);
        iv.setScaleType(ImageView.ScaleType.FIT_CENTER);
        iv.setVisibility(ImageView.GONE);
        iv.setBackgroundColor(0xFFFFFFFF);
        iv.setOnClickListener( mOnClickListener ); // OnClickListener()をセットする
        thumbnailImage.add(iv);
    }

// OnClickListener() で渡された View v からID(v.getId())を取得。imageViewを特定し付随のファイルネームを返す。

    public String getTapThumbnailName( View v ) {
        return (String)thumbnailText.get( ( v.getId() - (viewId + 1) ) / 2 ).getText();
    }

 

後で、iv.setBackgroundColor(0xFFFFFFFF); color.xmlにBackgroundColor登録しなくては。忘れてた。

 


  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

基礎。画像サムネイル表示。追加、MyDirectoryクラス。

2021-09-19 00:53:38 | Android studio 日記

フォルダを指定すると、その中のディレクトリとファイルを別々に配列で取得する。

 

public class MyDirectory {
    private File targetDir = null;
    private final ArrayList< MyNumbersInString> mDirNameList = new ArrayList<>();
    private final ArrayList< MyNumbersInString> mFileNameList = new ArrayList<>();
    private int dirIndexNo = 0, fileIndexNo = 0;

    public MyDirectory( File dir ) {
        if ( dir == null || !dir.exists() || !dir.isDirectory()) return;
        targetDir = dir;
        initMyDirectory(dir);
    }
    private void initMyDirectory( File dir ) {

        String name = dir.getPath();
        File[] files = new File( name ).listFiles();

        for (File file : files) {
            if (file.isDirectory()) {
                mDirNameList.add(new MyNumbersInString(file.getName()));
            } else if (file.isFile()) {
                name = file.getName();
                name.toLowerCase(); //小文字に変換
                if (name.endsWith(".jpg") || name.endsWith(".png")) { //画像ファイル選択
                    mFileNameList.add(new MyNumbersInString(file.getName()));
                }
            }
        }

        Collections.sort(
                mDirNameList, new Comparator< MyNumbersInString>() {
                    @Override
                    public int compare(MyNumbersInString mn1, MyNumbersInString mn2) {
                        return mn1.getName2().compareTo(mn2.getName2());
                    }
                }
        );
        Collections.sort(
                mFileNameList, new Comparator< MyNumbersInString>() {
                    @Override
                    public int compare(MyNumbersInString mn1, MyNumbersInString mn2) {
                        return mn1.getName2().compareTo(mn2.getName2());
                    }
                }
        );
    }
    public File getTargetDir() {
        return targetDir;
    }
    public boolean resetTargetDir( File dir ) {
        if ( dir == null || !dir.exists() || !dir.isDirectory() ) return false;
        if ( targetDir != null ) close();

        targetDir = dir;
        initMyDirectory(dir);
        return true;
    }


    public String getDirName() {
        return mDirNameList.get(dirIndexNo).getName();
    }
    public String getDirName(int no) {
        if ( no < 0 || no >= mDirNameList.size() )
            return null;

        return mDirNameList.get(no).getName();
    }
    public String getNextDirName() {
        if ( ++dirIndexNo >= mDirNameList.size() ) {
            dirIndexNo--;
            return null;
        }

        return mDirNameList.get(dirIndexNo).getName();
    }
    public String getPrevDirName() {
        if ( --dirIndexNo < 0 ) {
            dirIndexNo = 0;
            return null;
        }

        return mDirNameList.get(dirIndexNo).getName();
    }
    public boolean setDirIndexNo( int no ) {
        if ( no < 0 || no >= mDirNameList.size() )
            return false;
        dirIndexNo = no;
        return true;
    }
    public int getDirListSize() {
        return mDirNameList.size();
    }

    public String getFileName() {
        return mFileNameList.get(fileIndexNo).getName();
    }
    public String getFileName( int no ) {
        if ( no < 0 || no >= mFileNameList.size() )
            return null;

        return mFileNameList.get(no).getName();
    }
    public String getNextFileName() {
        if ( ++fileIndexNo >= mFileNameList.size() ) {
            fileIndexNo--;
            return null;
        }
        return mFileNameList.get(fileIndexNo).getName();
    }
    public String getPrevFileName() {
        if (--fileIndexNo < 0) {
            fileIndexNo = 0;
            return null;
        }
        return mFileNameList.get(fileIndexNo).getName();
    }
    public boolean setFileIndexNo( int no ) {
        if ( no < 0 || no >= mFileNameList.size() )
            return false;
        fileIndexNo = no;
        return true;
    }
    public int getFileListSize() {
        return mFileNameList.size();
    }
    public void close() {
        targetDir = null;
        mDirNameList.clear();
        mFileNameList.clear();
    }
}

 


  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする