【VB】フォームをコンポーネントのように扱う【.Net】

Windows Formアプリケーションで、複数の画面で同じように使う機能(外見的な部分というよりは内部ロジック)がある場合、機能をまとめたフォームをコンポーネントとして機能を使い回すと便利です。
この記事ではそのやり方をまとめます。サンプルプロジェクトはGitHubをご覧ください。
github.com

メリット/デメリット

メリット

これをやる最大のメリットは、MVCで言うところのモデル部のコードが共通化でき、作成/保守が容易になる点です。
クラスライブラリとして分割すればプロジェクト毎に使い回すことも可能です。
VisibleやEnabledといったパラメータをいじることでまとめて有効/無効化できる点も、場合によっては便利です。

デメリット

フォームをコンポーネントとして扱う場合、それをデザイナーで表示することができないため、位置などの調整が面倒になります。
Designerを弄ることでデザイナーにも表示可能でした。後で記事を書き直します。
デザイン用のプロジェクトを用意してそこで作成し、実際の作成時にやるのが一番手っ取り早いでしょうか。
Formを継承するクラスは抽象クラス化出来ないのも地味に面倒だったりします。

やること

デザイン的な部分でやることは大きく2つです。

  1. コンポーネントとして扱うフォームを準備する
  2. 呼び出し側のフォームを準備する
  3. (ベースとして作ったフォームを継承し、使い回す)
コンポーネントとして扱うフォームを準備する

まずFormBorderStyleをNoneに設定します。これによってFormの枠が消えます。
f:id:wrongwrongwrongwrong163377:20180816020350p:plain
次にコンポーネントのデザインを設定します。今回は背景色を変えてボタン1つのみ置いた状態としました。
f:id:wrongwrongwrongwrong163377:20180816020234p:plain
最後にコンストラクタに必要な内容を記述します。重要なのはWith句内と、その後に続くparent.Controls.Add(Me)です。

Public Class CompornentBase
    Public Sub New(ByRef parent As Form, ByVal location As Point, Optional ByVal txt As String = "loaded")
        ' この呼び出しはデザイナーで必要です。
        InitializeComponent()
        ' InitializeComponent() 呼び出しの後で初期化を追加します。

        '別のフォームに設定するための準備
        With Me
            .TopLevel = False
            .Visible = True
            .Location = location
        End With

        parent.Controls.Add(Me) '親コンポーネントに自分を加える

        Button1.Text = txt
    End Sub
End Class
呼び出し側のフォームを準備する

テキトーにフォームのデザインを用意します。
f:id:wrongwrongwrongwrong163377:20180816020805p:plain
これのコードで、以下のようにコンポーネントを呼び出します。

Public Class Parent
    Private Sub Parent_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Dim compo1 = New CompornentBase(Me, New Point(0, 0))
        Dim compo2 = New CompornentBase(Me, New Point(0, 200), "compo2")
    End Sub
End Class

実行すると、以下のようになります。
f:id:wrongwrongwrongwrong163377:20180816021128p:plain
フォームをコンポーネントのように扱うためにやることとしては以上です。
冒頭で述べたとおり、これは本来外見ではなくロジックの部分を使い回すためのハックなので、実際は「コンポーネントとして扱うフォームを準備する」部分のコードにロジックを書き、それを継承したフォームでデザインを書くというのが正しいです。

(ベースとして作ったフォームを継承し、使い回す)

この部分は本来フォームをコンポーネントのように扱うことの本質的な内容ですが、例を作りきれなかったので時間があればやります。
一応、自分がやる上で工夫していたやり方は以下の2点です。

  • (ボタンなど)イベントで受け取れるsenderをDictionaryの引数にしたり、senderのタグに必要な情報を持たせるなどする
  • ボタンは配列として扱い、AddHandlerなどを用いて挙動の設定を行う
    • 設定する挙動の部分は関数として継承先が実装する形にするのもよい

【読書感想】日本語の作文技術

【新版】日本語の作文技術 (朝日文庫)

【新版】日本語の作文技術 (朝日文庫)

 

 日本語の構造について学ぶことができた

内容は非常に論理的で、自分の書く文章が何故読みにくかったかを構造的に理解できたと思います。日本語の構造に関する研究や翻訳語、その他の言語に関する言及といった、文章の書き方以外の部分も楽しんで読むことができました。

特に知ることができて良かったと思える内容を以下に2点かいつまんで書き出します。

第三章 修飾の順序
  1. 節を先にし、句を後にする(修飾する側とされる側の距離を近づけ、曖昧さが出ないようにする)。
  2. 長い修飾語は前に、短い修飾語は後にする。
  3. 大状況から小状況へ、重大なものからそうでないものへつなげていく。
  4. 語の親和性による曖昧さを回避する。

この内特に重要なのが1と2で、この辺りが崩れると文章として非常に読みにくくなることを学びました。簡単な構造に当てはめて書くだけでとても読みやすくなるので、この点は意識したいです。

第六章 助詞の使い方

助詞全体が一文字の違いで文の意味の範囲を大きく左右するものですが、一文字であるだけにミスに気付きにくいこと、そもそも文章の論理的構造に気を使わずに書いてしまっていることが多かったと気付きました。

「笑っている文章」に気付かされた

『第八章 無神経な文章』の内容ですが、特に刺さったので、これだけ分けて大きく書きます。

笑っている文章というのは書いた人間が渾身のドヤ顔をこちらに向けているような文章なんだと感じました。無駄な修飾や、強い言葉で言い切る、上品に濁すといった演出など、つまり自身のことを表現するための情報が文章のいたる所に入り込んでいて、客観的には読みにくいことこの上ありません。紋切り型についても触れられていましたが、そういった言い回しを好むことも、結局は自身の教養の演出に過ぎないのではないかと思います。また、本文中で触れられていたことですが、そういった言い回しは読みにくいだけでなく、ウソを書いてしまうことにも繋がります。

ただ一方で、最近ではこのような文章が多く流れるようになったとも感じます。特にアフィリエイトブロガーや政治家といった自分を売る商売では、そういった味の強い書き方の方が売上に繋がるのでしょう。良し悪しを論じるつもりはありませんが、目立つ文章を書く人間にとって誠実さが必要なくなったように見えるのは残念だと感じます。

まとめ

30年以上売れるだけあって、非常に良い本でした。

内容について色々書きましたが、読んだ内容が身についているとは言えないので、これからブログを書く上で身につけていこうと思います。

【Android】ListViewを使う【Kotlin】

自作クラスを使ったListViewの使い方をまとめます。この記事を書いた時点で用いているサンプルプロジェクトは以下。
github.com

やること

ListVIewを使うための準備は3つです。

  1. ListViewに表示するレイアウトを作る
  2. Adapterクラスを作る(アイテムの内容はここで設定)
  3. アクティビティへの配置とAdapterのセット(アイテムをタップした時の処理はここで設定)

最終的に、以下の画像のようなレイアウトの列挙が出来ます。
f:id:wrongwrongwrongwrong163377:20180815160611p:plain

表示するレイアウトを作る

レイアウトファイルを追加し、ListViewに表示するレイアウトを作ります。
この記事ではlanguage_item.xmlとしてTextViewを3つ水平に並べたものをサンプルとします。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal">

    <TextView
        android:id="@+id/num"
        android:layout_width="50sp"
        android:layout_height="match_parent"
        android:background="@color/colorPrimary"
        android:textSize="30sp"
        android:textColor="@color/colorWhite"
        android:gravity="center"
        android:shadowColor="@color/colorBlack"
        android:shadowRadius="10.0"
        android:text="99"/>

    <TextView
        android:id="@+id/language"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_weight="5"
        android:textSize="30sp"
        android:text="language"/>

    <TextView
        android:id="@+id/parcent"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_weight="3"
        android:textSize="30sp"
        android:gravity="right"
        android:text="nnn.nn%"/>
</LinearLayout>

Adapterクラスを作る

Adapterクラスは表示するItem全てを管理します。処理の流れとしては「コンストラクタに表示したいデータを渡して初期化→getViewで表示するViewを初期化」となります。
サンプルとしたLanguageAdapter(下記)では、getView内でアイテムに対応する文章や色を設定しています。

class LanguageAdapter(val context: Context,
                      val sortedList: List<Pair<String, Int>>,
                      numOfReps: Int,
                      val numColorIds: ArrayList<Int>) : BaseAdapter() {
    val layoutInflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
    var sumOfReps = numOfReps.toDouble()

    override fun getCount(): Int {
        return sortedList.count()
    }

    override fun getItem(position: Int): Pair<String, Int> {
        return sortedList[position]
    }

    override fun getItemId(position: Int): Long {
        return position.toLong()
    }

    @SuppressLint("ViewHolder", "SetTextI18n")
    override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View {
        val view = layoutInflater.inflate(R.layout.language_item, parent, false) //表示するレイアウト取得
        val numtext = view.findViewById<TextView>(R.id.num)
        numtext.text = "${sortedList[position].second}"
        numtext.background = ColorDrawable(ContextCompat.getColor(context, if(numColorIds[position] != 0) numColorIds[position] else R.color.colorWhite))

        view.findViewById<TextView>(R.id.language).text = sortedList[position].first
        view.findViewById<TextView>(R.id.parcent).text = "${String.format("%3.2f", ((sortedList[position].second * 100).toDouble() / sumOfReps))}%"
        return view
    }
}

アクティビティへの配置とAdapterのセット

ここまで作った内容を使うため、以下の3手順を行います。

  1. ListViewをレイアウトに配置
  2. ListViewにAdapterをセット
  3. ListViewにタップ時の挙動を設定
ListViewをレイアウトに配置

レイアウトに加えるだけです。

<!-- リストビュー配置 -->
    <ListView
        android:id="@+id/listView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
    <!-- リストビュー配置 -->
</LinearLayout>
ListViewにAdapterをセット

以下のように、listViewにアダプターを入れるだけです。

val listView = findViewById(R.id.listView)
listView.adapter = LanguageAdapter(/* コンストラクタに必要な引数 */)
ListViewにタップ時の挙動を設定

setOnItemClickListenerでタップ時の挙動が設定できます。
positionにはタップされたアイテムの番号が入っており、例えばparent.getItemAtPosition(position)を呼び出すことでAdapterクラスに作成したgetItem(position: Int)を呼び出すことができます。

val listView = findViewById(R.id.listView)
listView.setOnItemClickListener{parent, v, position, id ->
    /* タップ時の挙動 */
}

ここまでの操作で自作クラスを使ったListViewが使えます。

【Android】GitHubの言語ごとの色に対応するXMLを作る【Kotlin】

GitHubでは以下のように言語ごとに色が割り振られています。これをAndroidで利用したかったので、XML形式に変換しました。
f:id:wrongwrongwrongwrong163377:20180813165149p:plain

やりかた

以下に定義が有るので、これをローカルに持ってきて解析します。
https://raw.githubusercontent.com/hiroppy/github-language-color-themes/master/languages.json

結果

[ ,+-#]の5文字は使えないので、'_'で置換しました。
一方この内容はどうやら最新ではないようで、見つけた範囲ではKotlinの色が違ったりVim scriptが含まれていなかったりしました。

<color name="ABAP">#E8274B</color>
<color name="AGS_Script">#B9D9FF</color>
<color name="AMPL">#E6EFBB</color>
<color name="ANTLR">#9DC3FF</color>
<color name="API_Blueprint">#2ACCA8</color>
<color name="APL">#5A8164</color>
<color name="ASP">#6a40fd</color>
<color name="ATS">#1ac620</color>
<color name="ActionScript">#882B0F</color>
<color name="Ada">#02f88c</color>
<color name="Agda">#315665</color>
<color name="Alloy">#cc5c24</color>
<color name="Arc">#aa2afe</color>
<color name="Arduino">#bd79d1</color>
<color name="AspectJ">#a957b0</color>
<color name="Assembly">#6E4C13</color>
<color name="AutoHotkey">#6594b9</color>
<color name="AutoIt">#1C3552</color>
<color name="BlitzMax">#cd6400</color>
<color name="Boo">#d4bec1</color>
<color name="Brainfuck">#2F2530</color>
<color name="C">#555555</color>
<color name="C_">#178600</color>
<color name="C__">#f34b7d</color>
<color name="CSS">#563d7c</color>
<color name="Chapel">#8dc63f</color>
<color name="Cirru">#ccccff</color>
<color name="Clarion">#db901e</color>
<color name="Clean">#3F85AF</color>
<color name="Clojure">#db5855</color>
<color name="CoffeeScript">#244776</color>
<color name="ColdFusion">#ed2cd6</color>
<color name="ColdFusion_CFC">#ed2cd6</color>
<color name="Common_Lisp">#3fb68b</color>
<color name="Component_Pascal">#b0ce4e</color>
<color name="Crystal">#776791</color>
<color name="D">#fcd46d</color>
<color name="DM">#447265</color>
<color name="Dart">#00B4AB</color>
<color name="Diff">#88dddd</color>
<color name="Dogescript">#cca760</color>
<color name="Dylan">#6c616e</color>
<color name="E">#ccce35</color>
<color name="ECL">#8a1267</color>
<color name="Eagle">#814C05</color>
<color name="Eiffel">#946d57</color>
<color name="Elixir">#6e4a7e</color>
<color name="Elm">#60B5CC</color>
<color name="Emacs_Lisp">#c065db</color>
<color name="EmberScript">#FFF4F3</color>
<color name="Erlang">#B83998</color>
<color name="F_">#b845fc</color>
<color name="FLUX">#88ccff</color>
<color name="FORTRAN">#4d41b1</color>
<color name="Factor">#636746</color>
<color name="Fancy">#7b9db4</color>
<color name="Fantom">#dbded5</color>
<color name="Forth">#341708</color>
<color name="Frege">#00cafe</color>
<color name="Game_Maker_Language">#8fb200</color>
<color name="Glyph">#e4cc98</color>
<color name="Gnuplot">#f0a9f0</color>
<color name="Go">#375eab</color>
<color name="Golo">#88562A</color>
<color name="Gosu">#82937f</color>
<color name="Grammatical_Framework">#79aa7a</color>
<color name="Groovy">#e69f56</color>
<color name="HTML">#e44b23</color>
<color name="Handlebars">#01a9d6</color>
<color name="Harbour">#0e60e3</color>
<color name="Haskell">#29b544</color>
<color name="Haxe">#f7941e</color>
<color name="Hy">#7790B2</color>
<color name="IDL">#a3522f</color>
<color name="Io">#a9188d</color>
<color name="Ioke">#078193</color>
<color name="Isabelle">#FEFE00</color>
<color name="J">#9EEDFF</color>
<color name="JFlex">#DBCA00</color>
<color name="Java">#b07219</color>
<color name="JavaScript">#f1e05a</color>
<color name="Julia">#a270ba</color>
<color name="KRL">#28431f</color>
<color name="Kotlin">#EA4DFA</color>
<color name="LFE">#004200</color>
<color name="LOLCODE">#cc9900</color>
<color name="LSL">#3d9970</color>
<color name="Lasso">#999999</color>
<color name="Latte">#A8FF97</color>
<color name="LiveScript">#499886</color>
<color name="LookML">#652B81</color>
<color name="Lua">#000080</color>
<color name="MTML">#b7e1f4</color>
<color name="Makefile">#427819</color>
<color name="Mask">#f97732</color>
<color name="Matlab">#bb92ac</color>
<color name="Max">#c4a79c</color>
<color name="Mercury">#ff2b2b</color>
<color name="Mirah">#c7a938</color>
<color name="Nemerle">#3d3c6e</color>
<color name="NetLinx">#0aa0ff</color>
<color name="NetLinx_ERB">#747faa</color>
<color name="NetLogo">#ff6375</color>
<color name="NewLisp">#87AED7</color>
<color name="Nimrod">#37775b</color>
<color name="Nit">#009917</color>
<color name="Nix">#7e7eff</color>
<color name="Nu">#c9df40</color>
<color name="OCaml">#3be133</color>
<color name="Objective_C">#438eff</color>
<color name="Objective_C__">#6866fb</color>
<color name="Objective_J">#ff0c5a</color>
<color name="Omgrofl">#cabbff</color>
<color name="Opal">#f7ede0</color>
<color name="Oxygene">#cdd0e3</color>
<color name="Oz">#fab738</color>
<color name="PAWN">#dbb284</color>
<color name="PHP">#4F5D95</color>
<color name="Pan">#cc0000</color>
<color name="Papyrus">#6600cc</color>
<color name="Parrot">#f3ca0a</color>
<color name="Pascal">#b0ce4e</color>
<color name="Perl">#0298c3</color>
<color name="Perl6">#0000fb</color>
<color name="PigLatin">#fcd7de</color>
<color name="Pike">#005390</color>
<color name="PogoScript">#d80074</color>
<color name="Processing">#0096D8</color>
<color name="Prolog">#74283c</color>
<color name="Propeller_Spin">#7fa2a7</color>
<color name="Puppet">#332A77</color>
<color name="Pure_Data">#91de79</color>
<color name="PureBasic">#5a6986</color>
<color name="PureScript">#1D222D</color>
<color name="Python">#3572A5</color>
<color name="QML">#44a51c</color>
<color name="R">#198ce7</color>
<color name="RAML">#77d9fb</color>
<color name="Racket">#22228f</color>
<color name="Ragel_in_Ruby_Host">#e17600</color>
<color name="Rebol">#358a5b</color>
<color name="Red">#ee0000</color>
<color name="Rouge">#cc0088</color>
<color name="Ruby">#701516</color>
<color name="Rust">#dea584</color>
<color name="SAS">#B34936</color>
<color name="SQF">#3F3F3F</color>
<color name="SaltStack">#646464</color>
<color name="Scala">#7dd3b0</color>
<color name="Scheme">#1e4aec</color>
<color name="Self">#0579aa</color>
<color name="Shell">#89e051</color>
<color name="Shen">#120F14</color>
<color name="Slash">#007eff</color>
<color name="Slim">#ff8f77</color>
<color name="Smalltalk">#596706</color>
<color name="SourcePawn">#5c7611</color>
<color name="Squirrel">#800000</color>
<color name="Standard_ML">#dc566d</color>
<color name="SuperCollider">#46390b</color>
<color name="Swift">#ffac45</color>
<color name="SystemVerilog">#DAE1C2</color>
<color name="Tcl">#e4cc98</color>
<color name="TeX">#3D6117</color>
<color name="Turing">#45f715</color>
<color name="TypeScript">#2b7489</color>
<color name="Unified_Parallel_C">#4e3617</color>
<color name="UnrealScript">#a54c4d</color>
<color name="VHDL">#adb2cb</color>
<color name="Vala">#fbe5cd</color>
<color name="Verilog">#b2b7f8</color>
<color name="VimL">#199f4b</color>
<color name="Visual_Basic">#945db7</color>
<color name="Volt">#1F1F1F</color>
<color name="Web_Ontology_Language">#9cc9dd</color>
<color name="XC">#99DA07</color>
<color name="XQuery">#5232e7</color>
<color name="Zephir">#118f9e</color>
<color name="eC">#913960</color>
<color name="edn">#db5855</color>
<color name="nesC">#94B0C7</color>
<color name="ooc">#b0b77e</color>
<color name="wisp">#7582D1</color>
<color name="xBase">#403a40</color>

【日記】モイ株式会社のFizz Buzz チャレンジをやった

Fizz Buzz チャレンジとは?

モイ株式会社の新卒採用エントリー前の試験です。

saiyo2019.moi.st

結果

スコア上げは気力が続かなかったのでしてません。

ハイスコアは800超え。どうやったのかな……。

f:id:wrongwrongwrongwrong163377:20180813001958p:plain

【Java】Intellij IDEAでWebSocketを導入する【Kotlin】

Intellij IDEAでWebSocketを使います。

やること

やることは以下の通りです。

参考ページ

ここから書く内容は以下のページと同様です。
jckjaer.dk

Java EEを持ってきて配置する

OracleのダウンロードページからJava EE {バージョン} Platform SDKをダウンロードしてきます。
解答すると、中にはglassfish{バージョン}というフォルダが入っているので、C:\Program Files\Java\java_ee_sdk-{バージョン}*1配置します。
自分がやった時はJava EE 8 Platform SDKglassfish5でした。
配置後は以下のようになります。
f:id:wrongwrongwrongwrong163377:20180812200233p:plain

Application Serverを設定する

Intellij IDEAを起動し、New ProjectからJava Enterpriseを選択し、次にApplication Serverの右のNew...を押し、一番上のGlassfish Serverを選択します。
f:id:wrongwrongwrongwrong163377:20180812200756p:plain
選択すると以下のようにGlassfish Serverのディレクトリ選択画面が出るので、先程glassfish{バージョン}を配置したディレクトリを入力します。
f:id:wrongwrongwrongwrong163377:20180812201108p:plain
Application ServerにGlassFish {バージョン}という表記が入れば設定は完了です*2

*1:このフォルダはJDKJREが配置されるフォルダです。Java EEの配置先がここである必要は有りませんが、分かりやすさのためここに配置しています。

*2:ここで使用している画像では既に設定が済んでいます。最初はApplication Server欄が空欄となっています。

【Android】Retrofit2を使う【Kotlin】

KotlinでRetrofit2を使ってみました(2018/9/8全面的に書き直し)。

Retrofitとは

httpで公開されたAPI叩くライブラリです。
Pairsの中の人に聞いた所、事情がなければAndroidアプリ作ってる会社は基本的にRetrofitを使ってるそうです。

プロジェクト

プロジェクトはGitHubに上げてあります。
github.com

やったこと

  • Gradleに追記
  • Manifestに追記
  • 受け取るためのデータクラス作成
  • Retrofitを使う
Gradleに追記

Module.appに以下2行を追加します。

implementation 'com.squareup.retrofit2:retrofit:2.4.0'
implementation 'com.squareup.retrofit2:converter-gson:2.4.0'

追記後全文。

apply plugin: 'com.android.application'

apply plugin: 'kotlin-android'

apply plugin: 'kotlin-android-extensions'

android {
    compileSdkVersion 27
    defaultConfig {
        applicationId "com.wrongwrong.retrofittest"
        minSdkVersion 15
        targetSdkVersion 27
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    //for Retrofit2
    implementation 'com.squareup.retrofit2:retrofit:2.4.0'
    implementation 'com.squareup.retrofit2:converter-gson:2.4.0'

    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
    implementation 'com.android.support:appcompat-v7:27.1.1'
    implementation 'com.android.support.constraint:constraint-layout:1.1.2'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}
Manifestに追記

ネットワークを使うのでパーミッションを書きます。

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

追記後全文。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.wrongwrong.retrofittest">

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>
受け取るためのデータクラス作成

今回はGitHubAPIのreposを取得します。取得するデータ一覧はこちら
今回はデータの変数名をAPIデータと合わせていますが、実際はキャメルケースで書いてもちゃんと動きます。

package com.wrongwrong.retrofittest

import java.io.Serializable

data class Owner(
        var login: String,
        var id: Long,
        var node_id: String,
        var avatar_url: String,
        var gravatar_id: String,
        var url: String,
        var html_url: String,
        var followers_url: String,
        var following_url: String,
        var gists_url: String,
        var starred_url: String,
        var subscriptions_url: String,
        var organizations_url: String,
        var repos_url: String,
        var events_url: String,
        var received_events_url: String,
        var type: String,
        var site_admin: Boolean
): Serializable

data class Permissions(
        var admin: Boolean,
        var push: Boolean,
        var pull: Boolean
): Serializable

data class License(
        var key: String,
        var name: String,
        var spdx_id: String,
        var url: String,
        var name_id: String
): Serializable

data class Repo(
        var id: Long,
        var node_id: String,
        var name: String,
        var full_name: String,

        var owner: Owner,

        var private: Boolean,
        var html_url: String,
        var description: String?,
        var fork: Boolean,
        var url: String,
        var archive_url: String,
        var assignees_url: String,
        var blobs_url: String,
        var branches_url: String,
        var collaborators_url: String,
        var comments_url: String,
        var commits_url: String,
        var compare_url: String,
        var contents_url: String,
        var contributors_url: String,
        var deployments_url: String,
        var downloads_url: String,
        var events_url: String,
        var forks_url: String,
        var git_commits_url: String,
        var git_refs_url: String,
        var git_tags_url: String,
        var git_url: String,
        var issue_comment_url: String,
        var issue_events_url: String,
        var issues_url: String,
        var keys_url: String,
        var labels_url: String,
        var languages_url: String,
        var merges_url: String,
        var milestones_url: String,
        var notifications_url: String,
        var pulls_url: String,
        var releases_url: String,
        var ssh_url: String,
        var stargazers_url: String,
        var statuses_url: String,
        var subscribers_url: String,
        var subscription_url: String,
        var tags_url: String,
        var teams_url: String,
        var trees_url: String,
        var clone_url: String,
        var mirror_url: String,
        var hooks_url: String,
        var svn_url: String,
        var homepage: String,
        var language: String?,
        var forks_count: Int,
        var stargazers_count: Int,
        var watchers_count: Int,
        var size: Int,
        var default_branch: String,
        var open_issues_count: Int,
        var topics: List<String>,
        var has_issues: Boolean,
        var has_projects: Boolean,
        var has_wiki: Boolean,
        var has_pages: Boolean,
        var has_downloads: Boolean,
        var archived: Boolean,
        var pushed_at: String,
        var created_at: String,
        var updated_at: String,
        var permissions: Permissions,
        var allow_rebase_merge: Boolean,
        var allow_squash_merge: Boolean,
        var allow_merge_commit: Boolean,
        var subscribers_count: Int,
        var network_count: Int,
        var license: License
): Serializable
Retrofitを使う

今回はonCreate内でhttps://api.github.com/users/{id}/reposにアクセスしてデータを取得し、0番目のリポジトリのフルネームをLogに出力します。
インターフェース内には、GET, POST, PUT, DELETEなど、Rest APIにおけるCRUD処理が全て書けます。今回はデータを取得していますが、POST処理などでデータが返ってこない場合は戻り値をCall<Unit>*1とします。
retrofitとserviceはクラス内変数として宣言していますが、これらの初期化は処理コストが重いため、実際はグローバルに用意して使うのが良いようです。少なくともそのまま関数に書くのは悪い使い方です。

package com.wrongwrong.retrofittest

import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import com.google.gson.GsonBuilder
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import retrofit2.http.GET
import retrofit2.http.Path
import java.io.IOException

class MainActivity : AppCompatActivity() {
    interface IGetRepos{
        @GET("{id}/repos")
        fun getRepos(@Path("id") userID : String) : Call<List<Repo>>
    }

    private val retrofit: Retrofit = Retrofit.Builder()
            .addConverterFactory(GsonConverterFactory.create(GsonBuilder().serializeNulls().create()))
            .baseUrl("https://api.github.com/users/")
            .build()
    private val service: IGetRepos = retrofit.create(IGetRepos::class.java)

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

        val call = service.getRepos("k163377")
        call.enqueue(object : Callback<List<Repo>> {
            override fun onResponse(call: Call<List<Repo>>?, response: Response<List<Repo>>?) {
                try{
                    var arr: List<Repo>? = response!!.body()
                    Log.d("onResponse", arr!![0].full_name)
                }catch (e: IOException){
                    Log.d("onResponse", "IOException")
                }
            }

            override fun onFailure(call: Call<List<Repo>>?, t: Throwable?) {
                TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
            }
        })
    }
}

参考URL

mainActivityの大部分はこちらから写経させて頂きました。 Retrofit2Demo/Example01.java at master · ikidou/Retrofit2Demo · GitHub
もっと詳しい解説です。 Android Retrofit2 with Kotlin - Qiita
AndroidでRxJavaと組み合わせた例です。 KotlinでRetrofitとRxを使ってAPIクライアントをサクッと実装する - Qiita

*1:UnitはJavaでいうvoidです