Android 用の ColorPicker を探す

# 概要
ColorPicker は任意の色をユーザに選ばせるための UI 部品です。Android SDK には標準の ColorPicker が用意されていないので、自作するか OSS を利用する必要があります。

今回は GitHub でソースコードが公開されていて、かつ Gradle で依存を追加できる ColorPicker について調べてみました。

## 選定条件
1. GitHub 上でソースコードが公開されている
2. Gradle で依存を追加できる
3. 再配布の条件が厳しくないライセンスを適用している

## 実行環境
Listener の実装に Lambda 式を使いたかったので、サンプルコードは Kotlin で記述しています。View の紐づけには Kotlin Android Extensions を用いました。
Java でのサンプルコードは各ライブラリのリポジトリにある README.md やサンプルアプリで参照できますので、そちらをご覧ください。

| 項目 | 値
|:---|:---
| Android Studio | 2.3.3
| compileSdkVersion | 26
| targetSdkVersion  | 26
| Java | 1.8.0_131
| Kotlin | 1.1.4

----
# 今回調べる ColorPicker
以下6つを調べます。

1. jaredrummler/ColorPicker 
2. LarsWerkman/HoloColorPicker
3. QuadFlask/colorpicker
4. martin-stone/hsv-alpha-color-picker-android
5. Madrapps/Pikolo
6. kristiyanP/colorpicker

----

# [jaredrummler/ColorPicker](https://github.com/jaredrummler/ColorPicker)
![device-2017-09-23-105512.png](https://qiita-image-store.s3.amazonaws.com/0/102004/d27ce61f-e771-1cc3-7cd6-8044a70a806c.png)

シンプルな四角形の ColorPicker です。パレットと2本のバーのみで、ユーザが操作しやすいのが特徴です。

## 依存の追加

```groovy:app/build.gradle
dependencies {
    compile 'com.jaredrummler:colorpicker:1.0.0'
```

## レイアウト

```xml
<com.jaredrummler.android.colorpicker.ColorPickerView
        android:id="@+id/color_picker"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
    />
```

## 実装
Alpha の調節をさせたい場合は ```setAlphaSliderVisible(true)``` を呼びます。選択された ColorInt を使った処理は ```setOnColorChangedListener``` に実装します。

```kotlin
    override fun onViewCreated(view: View?, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        color_picker.setAlphaSliderVisible(true)
        color_picker.setOnColorChangedListener { /* colorInt を使う処理をここに実装. */ }
    }
```

## ライセンス
[the Apache License, Version 2.0](https://github.com/jaredrummler/ColorPicker/blob/master/LICENSE)

## サンプルアプリ
https://github.com/jaredrummler/ColorPicker/tree/master/demo

----

# [LarsWerkman/HoloColorPicker](https://github.com/LarsWerkman/HoloColorPicker)
![device-2017-09-23-105430.png](https://qiita-image-store.s3.amazonaws.com/0/102004/0d316750-9a16-b5ab-4a77-9bcf84ab1ba2.png)

円形のスライダーでベース色を選んでから詳細な色を選択するタイプです。前の選択色を保持しておく機能がデフォルトで用意されています。

## 依存の追加

```groovy:app/build.gradle
dependencies {
    compile 'com.larswerkman:HoloColorPicker:1.5'
```

## レイアウト

```xml
    <com.larswerkman.holocolorpicker.ColorPicker
        android:id="@+id/color_picker"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        />
    <com.larswerkman.holocolorpicker.ValueBar
        android:id="@+id/value_bar"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        />
    <com.larswerkman.holocolorpicker.OpacityBar
        android:id="@+id/opacity_bar"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        />
    <com.larswerkman.holocolorpicker.SVBar
        android:id="@+id/sv_bar"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
/>
```

## View の紐づけ
ColorPicker と各種バーをプログラム側で紐づけする必要があります。

```kotlin:onViewCreated
    override fun onViewCreated(view: View?, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        color_picker?.addValueBar(value_bar)
        color_picker?.addOpacityBar(opacity_bar)
        color_picker?.addSVBar(sv_bar)
```

## 実装
OnColorChangedListener をセットして処理を実装します。

```kotlin:onViewCreated
    override fun onViewCreated(view: View?, savedInstanceState: Bundle?) {
        // ...
        color_picker?.setOnColorChangedListener { /* colorInt を使う処理をここに実装. */ }
```

## ライセンス
[the Apache License, Version 2.0](https://github.com/LarsWerkman/HoloColorPicker/blob/master/LICENSE)

## サンプルアプリ
https://gist.github.com/LarsWerkman/4754528

----

# [QuadFlask/colorpicker](https://github.com/QuadFlask/colorpicker)
![device-2017-09-23-105445.png](https://qiita-image-store.s3.amazonaws.com/0/102004/ddfa275d-0a6c-fdcb-9999-44ead1da74b6.png)

円形、または花形の配置から色を選択させるタイプの ColorPicker です。

## 依存の追加
プロジェクトルートの build.gradle に jitpack への依存を追加する必要があります。

```groovy:build.gradle
allprojects {
    repositories {
        maven { url "https://jitpack.io" }
    }
}
```

ライブラリの依存は下記の通りです。

```groovy:app/build.gradle
dependencies {
    compile 'com.github.QuadFlask:colorpicker:0.0.13'
}
```

## レイアウト
この ColorPicker はレイアウトファイル内で View の紐づけが可能です。

```xml
<com.flask.colorpicker.ColorPickerView
    android:id="@+id/color_picker_view"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:alphaSlider="true"
    app:density="12"
    app:lightnessSlider="true"
    app:wheelType="FLOWER"
    app:lightnessSliderView="@+id/v_lightness_slider"
    app:alphaSliderView="@+id/v_alpha_slider"
    />

<com.flask.colorpicker.slider.LightnessSlider
    android:id="@+id/v_lightness_slider"
    android:layout_width="match_parent"
    android:layout_height="48dp"
    />

<com.flask.colorpicker.slider.AlphaSlider
    android:id="@+id/v_alpha_slider"
    android:layout_width="match_parent"
    android:layout_height="48dp"
    />
```

## 実装
OnColorSelectedListener を実装して add します。

```kotlin
    override fun onViewCreated(view: View?, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        color_picker.addOnColorSelectedListener { /* colorInt を使う処理をここに実装. */ }
    }
```

## ライセンス
the Apache License, Version 2.0
https://github.com/QuadFlask/colorpicker

### 注意
明示的に width を1以上に指定しないと下記のエラーを出力してクラッシュします。

```
java.lang.IllegalArgumentException: width and height must be > 0
  at android.graphics.Bitmap.createBitmap(Bitmap.java:724)
  at android.graphics.Bitmap.createBitmap(Bitmap.java:703)
  at android.graphics.Bitmap.createBitmap(Bitmap.java:670)
  at com.flask.colorpicker.slider.AbsCustomSlider.createBitmaps(AbsCustomSlider.java:56)
  at com.flask.colorpicker.slider.AlphaSlider.createBitmaps(AlphaSlider.java:36)
  at com.flask.colorpicker.slider.AbsCustomSlider.updateBar(AbsCustomSlider.java:43)
  at com.flask.colorpicker.slider.AbsCustomSlider.onSizeChanged(AbsCustomSlider.java:84)
  at android.view.View.sizeChange(View.java:15326)
```

あと、明度を下げ過ぎると黒い穴が密集するので、人によっては不快感を覚えるかもしれません。

## サンプルアプリ
https://github.com/QuadFlask/colorpicker/tree/master/app

----

# [martin-stone/hsv-alpha-color-picker-android](https://github.com/martin-stone/hsv-alpha-color-picker-android)
![device-2017-09-23-105501.png](https://qiita-image-store.s3.amazonaws.com/0/102004/7db323b8-5877-bf08-adca-222a219d416a.png)

独特な配置の ColorPicker です。デフォルトで下部に EditText が配置されており、そこで直接数値を入力して色を設定することが可能です。

## 依存の追加

```groovy:app/build.gradle
dependencies {
    compile 'com.rarepebble:colorpicker:2.2.0'
```

## レイアウト

```xml
<com.rarepebble.colorpicker.ColorPickerView
        android:id="@+id/color_picker"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        />
```

## 実装
名前が Listener ではなく Observer です。色と alpha を別々に参照できます。

```kotlin
    override fun onViewCreated(view: View?, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        color_picker.addColorObserver { color -> 
            val selectedColor = ColorUtils.setAlphaComponent(color.color, color.alpha)
            /* colorInt を使う処理をここに実装. */
        }
    }
```

## ライセンス
[the Apache License, Version 2.0](https://github.com/martin-stone/hsv-alpha-color-picker-android/blob/master/LICENSE)

## サンプルアプリ
https://github.com/martin-stone/hsv-alpha-color-picker-android/tree/master/demo_app

----
# [Madrapps/Pikolo](https://github.com/Madrapps/Pikolo)
![device-2017-09-23-105520.png](https://qiita-image-store.s3.amazonaws.com/0/102004/875698b7-3a50-8a63-63b6-98a1095ce2cc.png)

Kotlin 製の ColorPicker です。 minSdkVerson が15以上でないと使えません。

## 依存の追加

```groovy:app/build.gradle
dependencies {
    compile 'com.github.madrapps:pikolo:1.1.6'
```

## レイアウト

```xml
<com.madrapps.pikolo.HSLColorPicker
        android:id="@+id/color_picker"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        />
```

## 実装
基本的な使い方であれば SimpleColorSelectionListener を実装すればよいでしょう。

```kotlin
    override fun onViewCreated(view: View?, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        color_picker.setColorSelectionListener(object : SimpleColorSelectionListener() {
            override fun onColorSelected(color: Int) {
                /* colorInt を使う処理をここに実装. */
            }
        })
    }
```

## ライセンス
[the Apache License, Version 2.0](https://github.com/Madrapps/Pikolo/blob/master/LICENSE)

## サンプルアプリ
https://github.com/Madrapps/Pikolo/tree/master/sample

----
# [kristiyanP/colorpicker](https://github.com/kristiyanP/colorpicker)
![device-2017-09-23-105532.png](https://qiita-image-store.s3.amazonaws.com/0/102004/8d853ebc-d07b-84af-2723-6f85e8c785a2.png)

これまで調べたのとは違い、アプリ作者側があらかじめ設定した色の中からユーザに選ばせるタイプの ColorPicker です。例として、Material design 準拠の色しか使わせたくない場合はこれを使うと良いでしょう。

View ではなくダイアログとして提供されているので、何らかの Button や Menu と組み合わせて使う必要があります。

## 依存の追加

```groovy:app/build.gradle
dependencies {
    compile 'petrov.kristiyan:colorpicker-library:1.1.5'
```

## 実装
色一覧は ColorInt の可変長配列か16進数表現の String で渡すことが可能です。後者の場合は List でなく ArrayList でないとダメなのが少々残念に感じます。

```kotlin
    override fun onViewCreated(view: View?, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        button.setOnClickListener{ _ -> showColorPicker() }
    }

    private fun showColorPicker() {
        ColorPicker(activity)
                .setColors(
                    Color.parseColor("#82B926"),
                    Color.parseColor("#a276eb"),
                    Color.parseColor("#6a3ab2"),
                    Color.parseColor("#666666"),
                    Color.parseColor("#FFFF00"),
                    Color.parseColor("#3C8D2F"),
                    Color.parseColor("#FA9F00"),
                    Color.parseColor("#FF0000")
                )
                .setDefaultColorButton(Color.parseColor("#f84c44"))
                .setColumns(5)
                .setOnChooseColorListener(object : ColorPicker.OnChooseColorListener {
                    override fun onChooseColor(position: Int, color: Int) {
                        // colorInt を使う処理をここに実装.
                    }

                    override fun onCancel() = Unit
                })
                .setRoundColorButton(true).show()
    }
```

## ライセンス
README.md には MIT と書いてありますが、その後追加されたライセンスファイルは [the Apache License Version 2.0](https://github.com/kristiyanP/colorpicker/blob/master/LICENSE) でした。

## サンプルアプリ
https://github.com/kristiyanP/colorpicker/tree/master/colorpicker-sample

----
# サンプル
今回調べた ColorPicker を1つにまとめたアプリを作ってみました。
https://github.com/toastkidjp/ColorPickers

ビルドするのが面倒という場合には Google Play で公開していますので、そちらをご利用ください。
https://play.google.com/store/apps/details?id=jp.toastkid.colorpickers

----
# まとめ
GitHub でソースコードが公開されていて Gradle での依存追加が容易な ColorPicker を6種類調べてみました。アプリのデザインや要件と合致するものを選択するとよいでしょう。

## 参考
- [Kotlinでkotlin-android-extensionsをFragmentでも使いたい](https://qiita.com/toralipse/items/42b0ab9feb80f91af2e0)……レイアウトファイル内で定義した View を Fragment で使う場合は onViewCreated 内でやる必要がありました。

### メソッド数
debug ビルドの APK で、それぞれのライブラリのメソッド数を覗いてみました。

![スクリーンショット (6).png](https://qiita-image-store.s3.amazonaws.com/0/102004/0eb07348-a47d-e0b4-759e-8f4e37ee38d6.png)