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
}
}