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

android OS & iPadOS の記録。

【kotlin】 inner classの明確宣言

2024-02-27 13:49:39 | Android studio 日記

Javaから自動変換したら下記のようになった。
修正をしつつビルドするとGestureListenerからグローバル変数&関数にアクセスできない。

検索してもKotlin のGestureListenerの説明が少ない。
何日かスコープの試行錯誤をしながら検索サンプルに「inner class」の表記を見つける。
あぁ、これか。問題に関係あるサンプルではなかったが結びついたのでコードに書き込み。

動く。Javaって大雑把だったのね orz。

 

【Java 元コード】

    private ImageSwitcher mImageSwitcher = null;
    private boolean mMainImageFlag = true;
    private GestureDetectorCompat mDetector;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        mDetector = new GestureDetectorCompat( requireContext(), new MyGestureListener() );
    }

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

        mImageSwitcher = view.findViewById(R.id.image_switcher);
        mImageSwitcher.setFactory(() -> {
            MyImageView imageView = new MyImageView( requireContext() );
            imageView.setScaleType( ImageView.ScaleType.MATRIX );
            return imageView;
        });
        
        mImageSwitcher.setOnTouchListener(
                (v, event) -> mDetector.onTouchEvent(event)
        );

    }

    private class MyGestureListener extends GestureDetector.SimpleOnGestureListener {
        @Override
        public boolean onDown(MotionEvent event) {
            if ( !mMainImageFlag )
                realDown();

            return true;
        }
    }
 
    private void realDown() {
        省略
    }

【Kotlinへ自動変換】

    private var mImageSwitcher: ImageSwitcher? = null
    private val mMainImageFlag = true //内容を変更できない
    private val mDetector: GestureDetectorCompat? = null //内容を変更できない

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        
        mDetector = GestureDetectorCompat(
            requireContext(),
            パッケージ.ui.main.MainFragment.MyGestureListener()
        )
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        
        mImageSwitcher = view.findViewById(R.id.image_switcher)
        mImageSwitcher.setFactory(ViewSwitcher.ViewFactory {
            val imageView = MyImageView(requireContext())
            imageView.setScaleType(ImageView.ScaleType.MATRIX)
            imageView
        })
        
        mImageSwitcher.setOnTouchListener(
            OnTouchListener { v: View?, event: MotionEvent? ->
                mDetector!!.onTouchEvent(
                    event!!
                )
            }
        )

    }

    private class MyGestureListener : SimpleOnGestureListener() {
        override fun onDown(event: MotionEvent): Boolean {

            // mMainImageFlag、realDown() が参照できない。
            if (!mMainImageFlag) realDown()
            return true
        }
    }

    private fun realDown() {
        //省略
    }

【Kotlin 修正部分】

    private var mImageSwitcher: ImageSwitcher? = null

    // val -> var に変更。
    private var mMainImageFlag = true
    private var mDetector: GestureDetectorCompat? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        
        mDetector = GestureDetectorCompat(
            requireContext(),
            MyGestureListener() //スッキリ
        )
    }

    override fun onViewCreated(
        view: View,
        savedInstanceState: Bundle?
    ) {
        super.onViewCreated(view, savedInstanceState)

        mImageSwitcher = view.findViewById(R.id.image_switcher)
        mImageSwitcher.setFactory(
            ViewSwitcher.ViewFactory {
                val imageView = MyImageView(requireContext())
                imageView.scaleType = ImageView.ScaleType.MATRIX
                return@ViewFactory imageView
            }
        )

        mImageSwitcher.setOnTouchListener { _, motionEvent ->
            mDetector.onTouchEvent(motionEvent) // なんかスッキリ
        }
    }

    // inner class 宣言しないとグローバル変数等にアクセスできない。
    private inner class MyGestureListener(): GestureDetector.SimpleOnGestureListener() {
        override fun onDown(event: MotionEvent): Boolean {
            if (!mMainImageFlag) realDown()
            return true
        }
    }

    private fun realDown() {
        //省略
    }

 

MyGestureListener()に引数を渡して内部で利用できる。面倒だけど。


    private class MyGestureListener(
        vm : MyViewModel, 
        m : MyManager
        ): GestureDetector.SimpleOnGestureListener() {

        val viewModel: MyViewModel = vm
        val manager: MyManager = m

        override fun onDown(event: MotionEvent): Boolean {
            if (!viewModel.mMainImageFlag) manager.realDown()
            return true
        }
    }

 


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

【Kotlin】回転による縦、横画面で表示モードの切り替え

2024-02-23 21:01:07 | Android studio 日記

大手のBOOKアプリのようにタブレットが縦の時に1枚表示で横の時は左右2枚表示にしたかったけど、

onConfigurationChanged() で状態を判断して数値を保存、onCreate() で上手く読み出せない状態。

センサーで判断して、onCreate() で利用を考えたけど、onConfigurationChanged() とセンサーの独自判定角度が異なると画面が回転しないのにモードが切り替わってしまう、回転してるのにモードが切り替わらないなどの問題が起こる。

今の技術力では解消できないので、デバイスの縦、横で表示モードを切り替えるのは中止する。

 

 


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

【kotlin】 viewModelの保存値が取り出せない

2024-02-22 01:55:22 | Android studio 日記

ActivityのonCreate(){ }、fragmentのonViewCreated() 内で画面回転後の再描画でviewModelの保存値が読み出せない。

onConfigurationChanged()内で正常に保存している。
onCreate()以外では正常値が読み出せている。

onCreate()など、初期過程でどうとか何か記事を読んだような…、その時は例外発生するとか…。
原因が分からないので、センサーから向きを判定するメソッドを作成予定。

ダメなら回転で表示枚数を変えるのは中止。
Javaで開発してたものをブラッシュアップしながらKotlin習得にする。

 

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

【kotlin】 不可解な現象が発生。

2024-02-21 02:38:45 | Android studio 日記

viewModelにInt変数(viewModel.stateOrientation)を作成してデバイスが回転したら、その数値をviewModelのInt変数に保存する。
TextView1をonCreate()で表示。
TextView2をonConfigurationChanged()で表示。

TextView1、TextView2には、viewModel.stateOrientation.toString()を書き込む。

エミュレータのデバイス回転アイコンで回転させると
onCreate()で表示させている文字は初期値(0)のまま変化しない。
onConfigurationChanged()で表示させている文字は縦(1)、横(2)と切り替わる。

viewModelの変数の値はActivityの再描画でも保持されるので
viewModel.stateOrientation
の数値は同じ数値であるはず。
なのに違う数値が表示されるのはなぜ?

弱った。エミュレータの問題かな…。
数値を保存していて取り出し場所で数値が異なる状況ではプログラムは無理。

 

class MainActivity : AppCompatActivity() {

    private val viewModel: MainViewModel by viewModels()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val textView = findViewById<TextView>(R.id.message)
        textView.setText(viewModel.stateOrientation.toString()) // 初期値 0 のみ表示

    }

    override fun onConfigurationChanged(newConfig: Configuration) {
        super.onConfigurationChanged(newConfig)

        viewModel.stateOrientation = newConfig.orientation
        val textView = findViewById<TextView>(R.id.message2)
        textView.setText(viewModel.stateOrientation.toString()) // 1⇔2 切り替わって表示

    }

 


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

【kotlin】 getOrientation()失敗

2024-02-21 00:37:22 | Android studio 日記

override fun onCreate()の中で

var ori = resources.configuration.orientation

これを実行すると初回のみ正常な値を返します。
回転して再描画されたときは変化せず初回と同じ値が返されます。

viewModel にメソッドを作り、任意のタイミングで

Activity.resources.configuration.orientation

を返させても初回のみ正常値でその後は画面の状態とは関係なく初回値と同じ値が戻ってきます。

 

override fun onConfigurationChanged()の中で実行した場合はその時点のスクリーンの状態を正常に返します。

 

override fun onConfigurationChanged(){}でLiveDataのプロパティを変更させるのが良いのかも…。
screenTypeとは別のプロパティオンリーを作って利用しようか。

 


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