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

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でシェアする