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

android OS & iPadOS の記録。

public class MyNumbersInString{} 不具合修整。

2021-11-23 03:00:35 | Android studio 日記

ファイル名、ディレクトリ名に数字が含まれていた時の並び順の修正用の文字列作成に不具合あり。
数字が含まれていなかった場合、エラー発生する。実行時はディレクトリ、ファイルに全て数字が含まれていたために発見されなかった。今回、親のフォルダを遡るテストをしていて「files」ディレクトリを読み込んで不具合が見つかった。

数字部分が無い時は、name2 = name として戻る。

 

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" ); // 数字で分割

        // 修正、付け加え数字部分が無い時は、name2 = name; とする。
        if ( msplit1.length == 0 || msplit2.length == 0 ) {
            name2 = name;
            return;
        }
       // ここまで。

        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 < msplit1.length ) && ( j < msplit2.length ) ) {
            if (mFlag) { // 直前が数字でなかった
                if ( ++i < msplit1.length ) {
                    if (msplit1[i].length() != 0) { // 数字が現れた
                        sb.append( zeroCompensation( msplit1[i] ) );
                        mFlag = false;
                    }
                }
            } else { // 直前が文字でなかった
                if ( ++j < msplit2.length ) {
                    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 < len; c++) {
                sb.append("0");
            }
        }
        sb.append( text );
        return sb.toString();
    }
}

 


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

基礎。自作メッセージボード。ダイアログの代わり。

2021-11-19 23:15:19 | Android studio 日記

警告などを表示してボタンを押して閉じる。状況によって複数のボタンを表示して選択もさせる。
単純な内容なのでアラが目立つ。他の操作を遮断するのにonTouch()、onClick() を( Layout.getVisibility() == View.VISIBLE ) でスルー判断させなければならない。

とりあえず、何ができて、どんな問題が起こるのかを知るための基礎。

メッセージボードのデザインをする。
@id/message_layout を setVisibility( View.GONE )、setVisibility( View.VISIBLE )すれば、非表示、表示を切り替えられる。そして、ボタンの代わりとなる TextView も setVisibility() で必要に応じて使う選択肢の数を変えられる。用意したボタンは3個、メソッドの引数でボタン1個表示、2個表示を切り替えている。ボタン上の文字も変更できる。

 

【activity_main.xml】

< ?xml version="1.0" encoding="utf-8"?>
< ConstraintLayout

    < ConstraintLayout
        android:id="@+id/message_layout"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="#FFFFFF"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent" >

        < TextView
            android:id="@+id/message_text"
            android:layout_width="400dp"
            android:layout_height="wrap_content"
            android:maxLines="6"
            android:textSize="24sp"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        < LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            app:layout_constraintStart_toStartOf="@id/message_text"
            app:layout_constraintEnd_toEndOf="@id/message_text"
            app:layout_constraintTop_toBottomOf="@id/message_text" >

            < TextView
                android:id="@+id/key_done"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textSize="24sp"
                android:text="done" />

            < TextView
                android:id="@+id/key_accepted"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textSize="24sp"
                android:text="accepted" />

            < TextView
                android:id="@+id/key_cancel"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textSize="24sp"
                android:text="cancel" />

        </ LinearLayout>
    </ ConstraintLayout>
</ ConstraintLayout>

 

 

骨子。色々と肉付けが必要。また、onClick()処理は、複数のメッセージに対応させるため、分岐処理を組み込む。

【MainActivity.java】


    private ConstraintLayout mMessageLayout;
    private TextView mMessageTextView, mAcceptedTextView, mCancelTextView, mDoneTextView;
    private final View.OnClickListener mMessageClick;


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

        mMessageClick  = new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                switch (v.getId()) {
                    case R.id.key_done:
                        mMessageLayout.setVisibility( View.GONE );
                        break;
                    case R.id.key_accepted:

                        break;
                    case R.id.key_cancel:

                        break;
                }
            }
        };


        mMessageLayout = (ConstraintLayout)findViewById( R.id.message_layout );
        mMessageTextView = (TextView) findViewById( R.id.message_text ); // メッセージ
        mAcceptedTextView = (TextView) findViewById( R.id.key_accepted ); // ボタン 1
        mCancelTextView = (TextView) findViewById( R.id.key_cancel ); // ボタン 2
        mDoneTextView = (TextView) findViewById( R.id.key_done ); // ボタン 3

        mAcceptedTextView.setOnClickListener( mMessageClick );
        mCancelTextView.setOnClickListener( mMessageClick );
        mDoneTextView.setOnClickListener( mMessageClick );

    }

    public void onMessageBoard() { mMessageLayout.setVisibility( View.VISIBLE ); }
    public void offMessageBoard() { mMessageLayout.setVisibility( View.GONE ); }
    public boolean isMessageBoard() { return ( mMessageLayout.getVisibility() == View.VISIBLE ); }

    public void myMessage( String text ) { // メッセージのみは、ボタン1個表示。
        mDoneTextView.setVisibility( View.VISIBLE );
        mAcceptedTextView.setVisibility( View.GONE );
        mCancelTextView.setVisibility( View.GONE );
        mDoneTextView.setText( "done" );
        mMessageTextView.setText( text );
        mMessageLayout.setVisibility( View.VISIBLE );
    }
    public void myMessage( String text, String accepted, String cancel ) { 
        mDoneTextView.setVisibility( View.GONE );
        mAcceptedTextView.setVisibility( View.VISIBLE );
        mCancelTextView.setVisibility( View.VISIBLE );
        mMessageTextView.setText( text ); // メッセージ
        mAcceptedTextView.setText( accepted ); // ボタンの文字設定
        mCancelTextView.setText( cancel ); // ボタンの文字設定
        mMessageLayout.setVisibility( View.VISIBLE );
    }

引数の型が違う、数が違うで処理内容を判断する。
ボタンの数が同じで処理が異なる場合は、モード、IDを加えて分岐処理をさせる。

isMessageBoard()の戻り値が true ならメッセージが開いているので、他のタッチイベント、オンクリック処理はスルーさせる。

骨子なので肉付けしないと動かない?。実物は服も着せてるので問題ない状態。


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

基礎。imageButton でアイコンを並べる。

2021-11-13 19:30:41 | Android studio 日記

サムネイルを recyclerView で表示し、seekbar と連動させる。
そして、アイコンを並べて機能別に処理をさせる。その基本部分の実装と処理分岐を記述する。
実際は、mainActivity でOnClickListener() に実装、ページクラスに処理部分を記述。

【activity_main.xml】



        < LinearLayout
            android:id="@+id/icon_layout"
            android:orientation="horizontal"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" >

            < ImageButton
                android:id="@+id/icon_1"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:src="@drawable/ic_1" />

            < ImageButton
                android:id="@+id/icon_2"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:src="@drawable/ic_2" />

            < ImageButton
                android:id="@+id/icon_3"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:src="@drawable/ic_3" "/>

        </ LinearLayout>

 

【MainActivity.java】


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


        ImageButton ib = (ImageButton)findViewById( R.id.icon_1 );
        ib.setOnClickListener( iconButtonClick );

        ib = (ImageButton)findViewById( R.id.icon_2 );
        ib.setOnClickListener( iconButtonClick );

        ib = (ImageButton)findViewById( R.id.icon_3);
        ib.setOnClickListener( iconButtonClick );

        略

    }

 

// 処理部分は別クラスにあっても問題なさそう。別クラスでは、public で宣言か、メソッドで受け渡し。

    private View.OnClickListener iconButtonClick = new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                switch ( v.getId() ) {
                    case R.id.icon_1:
                        // 処理
                        break;
                    case R.id.icon_2:
                        break;
                    case R.id.icon_3:
                        break;
                }
            }
    };

 

実装部分と処理部分を分けるとスッキリする。
まだ、onClick()が呼ばれる条件?範囲?グループ?よく理解できていない。クリックされたら全てが1つのonClick()で呼ばれる のではなさそう。う~ん、今回は3つのボタンクリックをグループとして実装した。この3つはクリックされると、ここのonClick()が呼ばれる。みたい。

個々に実装したら、それぞれのonClick()が呼ばれる?。Activity で implements View.OnClickListener を使うとまた違う動作となる。面倒くさい。

とりあえず、v.getID() で処理を分岐させたいので今回の手法を使う。実装と処理を別クラスに記述できるから都合が良い。

 


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

基礎。seekbar プログレスバーの色を変更。lollipop 以降で利用可能?

2021-11-08 23:30:08 | Android studio 日記

recyclerView で、サムネイル画像を横に並べて表示。その下にseekbar を配置して、recyclerView と同期させる。
サムネイル画像を右から並べるか、左から並べるか、recyclerView はリバースメソッドで切り替えができるが、seekbar はメソッドで用意されていない。
プログレスバーの伸び方は数値変換で対応できる。
プログレスバーの伸び方の見た目は、プログレスバーとプログレスバックグランドの色を入れ替えれば、リバースしたことになる。

用意されている変更のメソッドは、APIレベルの高いもの用でlollipop対象だとエラーとなる。
(用意されてる色変更メソッドで対象OSに使えるなら、それを使う。)
トライエンドエラーで動きそうな方法を残す。

方法は、メインアクティビティーでdrawableに作ったレイアウトファイルを指定するだけ。

 

【MainActivity.java】


    Drawable drawable = ResourcesCompat.getDrawable( getResources(), R.drawable.seekbar_progress_left_start, null );
    SeekBar seekBar = (SeekBar)findViewById( R.id.seekbar );
    seekBar.setProgressDrawable( drawable );

    

ここでは、
    seekbar_progress_right_start.xml
    seekbar_progress_left_start.xml
を切り替え設定して見かけ上でプログレスバーの伸び方を反転している。

見かけが反転し、右から左へ延びるとき、
    progress = MaxNo - progress;
    seekBar.setProgress( progress );

これで補正する。

 

【activity_main.xml】

< ?xml version="1.0" encoding="utf-8"?>
< 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:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

 

    < SeekBar
         android:id="@+id/seekbar"
         android:layout_width="0dp"
         android:layout_height="30dp"

         android:progressDrawable="@drawable/seekbar_progress_right_start"

         app:layout_constraintStart_toStartOf="parent"
         app:layout_constraintEnd_toEndOf="parent" />


</ androidx.constraintlayout.widget.ConstraintLayout>

 

 

drawableに色を入れ替えた xml ファイルを2つ用意する。
色設定をファイル別に入れ替えているだけ。
    「android:color="@color/teal_200"」「android:color="#aaaaaa" 」
など。

 

【seekbar_progress_right_start.xml】

< ?xml version="1.0" encoding="utf-8"?>
< layer-list xmlns:tools="http://schemas.android.com/tools"
    xmlns:android="http://schemas.android.com/apk/res/android">

    < item android:id="@android:id/background">
        < shape android:shape="line" >
            < stroke
                android:width="4dp"
                android:color="@color/teal_200"/>
        </ shape>
    </ item>


    < item android:id="@android:id/progress" >
        < clip>
            < shape android:shape="line" >
                < stroke android:width="4dp"
                    android:color="#aaaaaa" />
            </ shape>
        </ clip>
    </ item>
</ layer-list>

 

【seekbar_progress_left_start.xml】

< ?xml version="1.0" encoding="utf-8"?>
< layer-list xmlns:android="http://schemas.android.com/apk/res/android">

    < item android:id="@android:id/background">
        < shape android:shape="line" >
            < stroke
                android:width="4dp"
                android:color="#aaaaaa"/>
        </ shape>
    </ item>


    < item android:id="@android:id/progress" >
        < clip>
            < shape android:shape="line" >
                < stroke android:width="4dp"
                    android:color="@color/teal_200" />
            </ shape>
        </ clip>
    </ item>
</ layer-list>

 

疲れる。散々悩み、やれることをやって最後に報われたからいいけど、心折れる寸前だったわ。

とりあえず、エミュレーター上で動いているので大丈夫かな。
lollipopデバイスに途中状態でインストールテストをしてみよう。

 

 


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