タッチイベントのフック【Android・Kotlin】

動画のように画面に指を触れて動かしたときの移動量を取得できるようなプログラムを作ってみた。

指で画面に触れながらタッチイベントを取得
指で画面に触れながらタッチイベントを取得

TouchableFragmentクラス

AndroidStudioのレイアウト画面
AndroidStudioのレイアウト画面

今回はフラグメントを使用してタッチイベントのフックを行った。

TouchableFragmentクラスを作成し、フラグメントのレイアウトファイルにイベントフック専用のビューであるtouchableViewを配置した。

このビューをフラグメントのonCreateViewで取得しリスナー登録を済ませておく。

override fun onCreateView(
	inflater: LayoutInflater, container: ViewGroup?,
	savedInstanceState: Bundle?
): View? {

	val view = inflater.inflate(R.layout.fragment_touchable, container, false)
	view.findViewById<View>(R.id.touchableView).setOnTouchListener(this)
	return view
}

次にTouchableFragmentクラスにView.OnTouchListenerインタフェースを実装する。そしてそのメンバメソッドであるonTouchメソッドを次のようにオーバーライドする。

private var yPrec = 0.0f

override fun onTouch(v: View?, event: MotionEvent?): Boolean {
	when (event?.actionMasked) {
		MotionEvent.ACTION_DOWN -> {
			yPrec = event.getY(0)
			listener?.actionDown()
		}
		MotionEvent.ACTION_MOVE -> {
			val dy = yPrec - event.getY(0)
			listener?.actionMove(dy)
		}
		MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
			listener?.actionUp()
		}
	}
	return true
}

今回は移動量を計算させているが他にもVelocityTrackerを使って指の速度を得ることもできるようになっている。詳しくはこちらを参考にしてもらいたい。

さてTouchableFragmentクラスの全体のプログラム内容は次のようになっている。

private const val ARG_PARAM1 = "param1"
private const val ARG_PARAM2 = "param2"

class TouchableFragment : Fragment(),View.OnTouchListener {
    private var param1: String? = null
    private var param2: String? = null
    private var listener: OnTouchableFragmentListener? = null

    private var yPrec = 0.0f

    override fun onTouch(v: View?, event: MotionEvent?): Boolean {
        when (event?.actionMasked) {
            MotionEvent.ACTION_DOWN -> {
                yPrec = event.getY(0)
                listener?.actionDown()
            }
            MotionEvent.ACTION_MOVE -> {
                val dy = yPrec - event.getY(0)
                listener?.actionMove(dy)
            }
            MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
                listener?.actionUp()
            }
        }
        return true
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        arguments?.let {
            param1 = it.getString(ARG_PARAM1)
            param2 = it.getString(ARG_PARAM2)
        }
    }

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {

        val view = inflater.inflate(R.layout.fragment_touchable, container, false)
        view.findViewById<View>(R.id.touchableView).setOnTouchListener(this)
        return view
    }



    override fun onAttach(context: Context) {
        super.onAttach(context)
        if (context is OnTouchableFragmentListener) {
            listener = context
        } else {
            throw RuntimeException(context.toString() + " must implement OnFragmentInteractionListener")
        }
    }

    override fun onDetach() {
        super.onDetach()
        listener = null
    }


    interface OnTouchableFragmentListener {
        fun actionDown()
        fun actionMove(dy: Float)
        fun actionUp()
    }

    companion object {
        @JvmStatic
        fun newInstance(param1: String, param2: String) =
            TouchableFragment().apply {
                arguments = Bundle().apply {
                    putString(ARG_PARAM1, param1)
                    putString(ARG_PARAM2, param2)
                }
            }
    }
}

MainActivityクラス

次にMainActivityクラスでの実装を行っていく。アクティビティのレイアウトファイルの左半分にはテキストビューを設置し、右半分にはフラグメントを入れ込むためにフレームレイアウトを設置した。

そしてMainActivityから動的にフラグメントを生成させるためのコードは次のようになる。

private const val TOUCHABLE_FRAGMENT_TAG = "touchableFragment"

class MainActivity : AppCompatActivity(), TouchableFragment.OnTouchableFragmentListener {


    override fun actionDown() {
        @SuppressLint("SetTextI18n")
        resultTextView.text = "Action Down\n${resultTextView.text}"
    }

    override fun actionMove(dy: Float) {
        @SuppressLint("SetTextI18n")
        resultTextView.text = "dy: $dy\n" +
                "${resultTextView.text}"
    }

    override fun actionUp() {
        @SuppressLint("SetTextI18n")
        resultTextView.text = "\nAction Up\n" +
                "${resultTextView.text}"
    }

    lateinit var resultTextView:TextView

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

        resultTextView = findViewById(R.id.result)

        if (supportFragmentManager.findFragmentByTag(TOUCHABLE_FRAGMENT_TAG) == null) {
            supportFragmentManager.beginTransaction()
                .add(R.id.container, TouchableFragment.newInstance("hoge", "fuga"), TOUCHABLE_FRAGMENT_TAG)
                .commit()
        }
    }


}

フラグメントをファクトリメソッドで生成し引数を渡せるようにしている。またフラグメントからのコールバックを受けて取れるようにインターフェイスを使った実装を行っている。先頭のactionDownactionMoveactionUpメソッドはTouchableFragmentからのコールバック関数となる。actionMoveでは指の移動量が渡されるのでその値をテキストビューにセットして表示させている。

最後にプロジェクトを実行し、画面右半分の中で指を動かせばテキストビューに移動量が表示されるだろう。

AndroidStudioのレイアウト画面
AndroidStudioのレイアウト画面

タッチイベントの処理をアクティビティに直接書いてしまうとアクティビティが読みづらくなってしまうので、できるだけフラグメントに追い出して管理したい。

デスクワークの負担を減らすアイテム

作業効率をアップさせるには姿勢が大事です!実際に使ってみてどれもオススメなのでよかったら参考に!

Bestandノートパソコンスタンド 11 '' -16 '' Macbook Air Pro/富士通と互換性のある放熱性に優れたアルミニウム合金PCスタンド-シルバー
Bestandノートパソコンスタンド 11 '' -16 '' Macbook Air Pro/富士通と互換性のある放熱性に優れたアルミニウム合金PCスタンド-シルバー

ノートパソコンの高さをあげると、長時間のデスクワークでも作業者の負担を軽減する事が可能です。 アルミニウム製品、純正品、高品質、高級感があ ります。 対応機種:MacBook、MacBook Air、MacBook Pro、富士通と対応11"-16"ノートパソコン スタンド.

Amazon
AKRacing ゲーミングチェア Pro-X V2 GREY
AKRacing ゲーミングチェア Pro-X V2 GREY

AKRacingハイエンドゲーミングチェア。大きめの座面でゆったりとした座り心地。張地を経年劣化に強い高耐久仕様のPUレザーに変更したアップグレードモデル 寸法:背もたれ幅55cm/奥行55cm/高さ95cm、座面下高さ:32~39cm、座面厚さ:13cm、重量:25kg

Amazon
Kensington ExpertMouse ワイヤレストラックボール K72359JP
Kensington ExpertMouse ワイヤレストラックボール K72359JP

接続方式/Bluetooth、2.4GHz USB付属品/レシーバー、パームレスト、日本語取扱説明書 サイズ(本体):W130×D157×H65mm 対応OS:2.4GHzUSB:Windows10/8.1/8/7、MacOS10.8以降/Bluetooth4.0LE:Windows10/8.1、MacOS10.8以降

AmazonRakuten

Anrdoidアプリ開発にオススメの書籍

こちらの本は、図や絵が多くてわかりやすく、Androidアプリ開発初心者でも理解しやすい内容。基本的なことはしっかりおさえられるので、この手の本は一冊読んでおくと良と思う。

基本からしっかり身につくAndroidアプリ開発入門
基本からしっかり身につくAndroidアプリ開発入門

圧倒的な多数のユーザーが使っているヤフーのアプリ。その制作の最前線にいる黒帯エンジニアが、ユーザーが使いやすいアプリの大切な基本をしっかりと解説します。

KindleAmazonRakuten

Kotlinの実践的な使い方が学べる内容の本で、プログラミング技術をもっと磨きたい人向け。センスの良いプログラミングがたくさん紹介されていて、個人的には「目からうろこ」の連続だった本。

Kotlinプログラミング
Kotlinプログラミング

Kotlinは、Javaとの相互運用を可能にし、Android OSでGoogleがフルサポートする静的型プログラミング言語です。この言語は、Javaだけでは十全ではない(Javaだけでは実装に手間がかかりすぎる)、軽量かつ豊かな表現形式や、他言語ではすでに実装されている最新の機能を盛り込んでいます。

KindleAmazonRakuten

参考

Amazonでお得に購入するなら、Amazonギフト券がオススメ!

\Amazonギフトがお得/

コンビニ・ATM・ネットバンキングで¥5,000以上チャージすると、プライム会員は最大2.5%ポイント、通常会員は最大2%ポイントがもらえます!
Amazonギフト券

\この記事をシェアする/