簡単にわかればいいんだよという人向け。

 プログラムを書いていると、いちいちアクティビティ側に記述するのが嫌とか、UI部品の中で完結すればいいのにと思うことがあると思う。そんなときには特定のUI部品(ウィジェット)のクラスを継承して処理をさせることができる。
 作り方は簡単で、ただ特定のUI部品のクラスを継承するクラスを作るだけ。
 コンストラクタは動的に生成する場合とxmlから作る場合とで複数のコンストラクタを設定する必要がある。そのコンストラクタは自分で調べるか、このようにするとAndroid Studioが自動生成してくれる
 setOnClickListenerはボタンなどイベントが発生したときに呼ばれるのではなく、アクティビティ側でイベントハンドラーを登録したときに呼び出されるメソッド。l: OnClickListenerにはアクティビティで設定した処理の内容が入っている。
 それらの処理内容と、ここで処理したい内容を合わせて親のクラスのAppCompatImageViewのイベントリスナーに登録しておく。こうすると、ボタンが押されたときにアクティビティで記述した処理内容と、このクラスで記述した処理内容を実行してくれる。
 アクティビティ側の処理を受けたくない場合にはinitでsuper.setOnClickListener {}を行い処理を記述してあげればいい。

package com.example.to.gameapplication

import android.content.Context
import android.support.v7.widget.AppCompatImageView
import android.util.AttributeSet
import android.util.Log

class MyImageView : AppCompatImageView {
    //アクティビティ廃棄時には必ずinitが実行させる
    init {
//アクティビティ側にコールバックしない場合は、ここでクリックイベントに関する処理を記述する
//super.setOnClickListener {
//} Log.v("nullpo","initMyImageView") }
//イベントが発生したときに処理して欲しい内容がlに入っている override fun setOnClickListener(l: OnClickListener?) {
//イベント発生時にこれをやってねと伝える super.setOnClickListener {
//アクティビティに記述したボタンを押されたときにやって欲しい処理 l?.onClick(it)
//ここで処理したいことを追加でここに記述しておく 他のメソッド呼び出しでもいい Log.v("nullpo","onClick") } } //コンストラクタ constructor(context: Context) : super(context) {} constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {} constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {} }
 アクティビティのレイアウトファイルに設置するには、以下のようにする。
 タグの名前を自作したUI部品を継承したクラス名に変更すればいい。 

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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">

    <com.example.to.gameapplication.MyImageView
        android:id="@+id/imageView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toTopOf="parent"
        app:srcCompat="@mipmap/ic_launcher_round" />

</android.support.constraint.ConstraintLayout>