Android Support Library28.0.0-alpha1で追加されたChipGroupを試してみる


目次

こんにちは。ピクトリンク事業部の古川です。

今回は、Android Support Library28.0.0(Alpha1)で追加された、Chip/ChipGroupについて解説します。

Chip/ChipGroupとは?

タグのようなものを指すViewです。

例えば、以下のようにスキルセットの一覧を表示するために使ったりします。

それでは具体的に見ていきましょう。

Chip/ChipGroupの導入

まずはbuild.gradleにAndroidXの情報を追加します。

2018年9月5日時点ではRC02が最新です。

実際に使ってみる

感覚的には、RadioButtonの実装に非常に似ています。

それでは実際に使ってみましょう。

ViewのXMLに情報を追加します。

 

 

これだけでもシンプルなChip/ChipGroupが設置できました。

ひとつずつ見ていきます。

Chipは独立しても使えますが、RadioButtonのようにChipGroupの子要素としてセットします。

8行目、Chipにはいくつかのスタイルが事前に用意されており、XMLで指定できるようになっています。

styleによって設定できるものは以下のものがあります。

  • チップ(チェックマーク)
  • クリック(選択状態)
  • 閉じるアイコン

上記3点をStyleの種別によって設定できます。

<td style="width: 506px; height: 24px;">
  概要
</td>

<td style="width: 346px; height: 24px;">
  イメージ
</td>
<td style="width: 506px; height: 95.2812px;">
  <ul>
    <li>
      チップ:オプション
    </li>
    <li>
      クリック:常に有効
    </li>
    <li>
      閉じるアイコン:オプション
    </li>
  </ul>
  
  <p>
    通常、ChipGroupに属したChipとして利用する際に指定します。</td> 
    
    <td style="width: 346px; height: 95.2812px;">
      <img class="alignnone wp-image-6416" src="/img/wp/2018/08/filter-150x83.png" alt="filter" width="72" height="40" srcset="/img/wp/2018/08/filter-150x83.png 150w, /img/wp/2018/08/filter.png 204w" sizes="(max-width: 72px) 100vw, 72px" /></p> 
      
      <p>
        <img class="alignnone wp-image-6417" src="/img/wp/2018/08/filter_filtered.png" alt="filter_filtered" width="93" height="40" srcset="/img/wp/2018/08/filter_filtered.png 277w, /img/wp/2018/08/filter_filtered-150x64.png 150w" sizes="(max-width: 93px) 100vw, 93px" /></td> </tr> 
        
        <tr style="height: 24px;">
          <td style="width: 350px; height: 24px;">
            @style/Widget.MaterialComponents.Chip.Action
          </td>
          
          <td style="width: 506px; height: 24px;">
            styleを設定しなかった場合、これがデフォルトとなる。</p> 
            
            <ul>
              <li>
                チップ:オプション
              </li>
              <li>
                クリック:不可
              </li>
              <li>
                閉じるアイコン:不可
              </li>
            </ul>
            
            <p>
              通常、ChipGroupに属したChipとして利用する際に指定します。</td> 
              
              <td style="width: 346px; height: 24px;">
                 <img class="alignnone wp-image-6420" src="/img/wp/2018/08/action.png" alt="action" width="89" height="40" srcset="/img/wp/2018/08/action.png 236w, /img/wp/2018/08/action-150x67.png 150w" sizes="(max-width: 89px) 100vw, 89px" />
              </td></tr> 
              
              <tr style="height: 96px;">
                <td style="width: 350px; height: 96px;">
                  @style/Widget.MaterialComponents.Chip.Choice
                </td>
                
                <td style="width: 506px; height: 96px;">
                  <ul>
                    <li>
                      チップ:オプション
                    </li>
                    <li>
                      クリック:常に有効
                    </li>
                    <li>
                      閉じるアイコン:不可
                    </li>
                  </ul>
                  
                  <p>
                    ユーザーが「選択している」ことをわかりやすく表示してくれる。
                  </p>
                  
                  <p>
                    通常、ChipGroupに属したChipとして利用する際に指定します。</td> 
                    
                    <td style="width: 346px; height: 96px;">
                      <img class="alignnone wp-image-6414" src="/img/wp/2018/08/choice.png" alt="choice" width="90" height="40" srcset="/img/wp/2018/08/choice.png 248w, /img/wp/2018/08/choice-150x67.png 150w" sizes="(max-width: 90px) 100vw, 90px" /></p> 
                      
                      <p>
                        <img class="alignnone wp-image-6415" src="/img/wp/2018/08/choice_selected.png" alt="choice_selected" width="86" height="40" srcset="/img/wp/2018/08/choice_selected.png 252w, /img/wp/2018/08/choice_selected-150x70.png 150w" sizes="(max-width: 86px) 100vw, 86px" /></td> </tr> 
                        
                        <tr style="height: 144px;">
                          <td style="width: 350px; height: 144px;">
                            @style/Widget.MaterialComponents.Chip.Entry
                          </td>
                          
                          <td style="width: 506px; height: 144px;">
                            <ul>
                              <li>
                                チップ:オプション
                              </li>
                              <li>
                                クリック:オプション
                              </li>
                              <li>
                                閉じるアイコン:オプション
                              </li>
                            </ul>
                            
                            <p>
                              通常、ChipGroupではなく独立したChipDrawableとして利用する際に指定します。</td> 
                              
                              <td style="width: 346px; height: 144px;">
                                <img class="alignnone wp-image-6419" src="/img/wp/2018/08/entry.png" alt="entry" width="110" height="40" srcset="/img/wp/2018/08/entry.png 288w, /img/wp/2018/08/entry-150x55.png 150w" sizes="(max-width: 110px) 100vw, 110px" /><img class="alignnone wp-image-6418" src="/img/wp/2018/08/entry_filtered-300x92.png" alt="entry_filtered" width="131" height="40" srcset="/img/wp/2018/08/entry_filtered-300x92.png 300w, /img/wp/2018/08/entry_filtered-150x46.png 150w, /img/wp/2018/08/entry_filtered.png 353w" sizes="(max-width: 131px) 100vw, 131px" />
                              </td></tr> </tbody> </table> 
                              
                              <p>
                                最後に android:textAppearance をセットしていますが、これはSupportLibraryの時はセットしなくても問題なかったので、今後正式リリース版が出る場合には不要になるかと思います。
                              </p>
                              
                              <p>
                                (セットしなかった場合、IllegalArgumentExceptionがコールされます。)
                              </p>
                              
                              <p>
                                11行目、android:textについては、SupportLibraryでは app:chipText(setChipText) でしたがdeprecated になっています。
                              </p>
                              
                              <p>
                                通常のandroid:text(setText)を使うようにしましょう。
                              </p>
                              
                              <p>
                                &nbsp;
                              </p>
                              
                              <p>
                                リスナーも豊富に用意されておりsetOnClickListener, setOnCheckedChangeListener, setOnCloseIconClickListenerと、チェックや閉じるボタンに対応したリスナーが用意されています。
                              </p>
                              
                              <p>
                                なお、setOnCloseIconClickListenerについては、コード中の実態はOnClickListenerとなっており、XMLから指定はできませんのでご注意ください。
                              </p>
                              
                              <p>
                                試しに実装してみます。
                              </p>
                              
                              <pre class="lang:default mark:39,48 decode:true" title="activity_main.xml">&lt;layout 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"&gt;

&lt;data&gt;

    &lt;variable
        name="viewModel"
        type="jp.furyu.chipgroupsample.viewmodel.MainViewModel" /&gt;
&lt;/data&gt;

&lt;androidx.constraintlayout.widget.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".activity.MainActivity"&gt;

    &lt;com.google.android.material.chip.ChipGroup
        android:id="@+id/chipGroup"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="parent"
        app:layout_constraintTop_toTopOf="parent"&gt;

        &lt;com.google.android.material.chip.Chip
            android:id="@+id/chip_default"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Default"
            android:textAppearance="?android:attr/textAppearanceMedium" /&gt;

        &lt;com.google.android.material.chip.Chip
            android:id="@+id/chip_action"
            style="@style/Widget.MaterialComponents.Chip.Action"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="@{viewModel::chipSelect}"
            android:text="Action"
            android:textAppearance="?android:attr/textAppearanceMedium" /&gt;

        &lt;com.google.android.material.chip.Chip
            android:id="@+id/chip_choice"
            style="@style/Widget.MaterialComponents.Chip.Choice"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onCheckedChanged="@{(compoundButton, b)  -&gt; viewModel.chipChecked()}"
            android:text="Choice"
            android:textAppearance="?android:attr/textAppearanceMedium" /&gt;

        &lt;com.google.android.material.chip.Chip
            android:id="@+id/chipfilter"
            style="@style/Widget.MaterialComponents.Chip.Filter"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Filter"
            android:textAppearance="?android:attr/textAppearanceMedium" /&gt;

        &lt;com.google.android.material.chip.Chip
            android:id="@+id/chip_entry"
            style="@style/Widget.MaterialComponents.Chip.Entry"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Entry"
            android:textAppearance="?android:attr/textAppearanceMedium" /&gt;

    &lt;/com.google.android.material.chip.ChipGroup&gt;

&lt;/androidx.constraintlayout.widget.ConstraintLayout&gt;

</layout>

                              <p>
                                次のような画面になります。
                              </p>
                              
                              <p>
                                <img class="alignnone wp-image-6433" src="/img/wp/2018/09/activity-MainActivity-09052018123549-146x300.png" alt="activity-MainActivity-09052018123549" width="250" height="514" srcset="/img/wp/2018/09/activity-MainActivity-09052018123549-146x300.png 146w, /img/wp/2018/09/activity-MainActivity-09052018123549-73x150.png 73w, /img/wp/2018/09/activity-MainActivity-09052018123549-498x1024.png 498w, /img/wp/2018/09/activity-MainActivity-09052018123549.png 1080w" sizes="(max-width: 250px) 100vw, 250px" />
                              </p>
                              
                              <p>
                                setOnCloseIconClickListenerもKotlinのコード上で実装してみましょう
                              </p>
                              
                              <pre class="lang:default mark:10-12 decode:true" title="MainActivity.kt">class MainActivity : AppCompatActivity() {
val mainViewModel = MainViewModel()
val binding: ActivityMainBinding by lazy {
    DataBindingUtil.setContentView&lt;ActivityMainBinding&gt;(this, R.layout.activity_main)
}

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    binding.viewModel = mainViewModel
    binding.chipEntry.setOnCloseIconClickListener {
        binding.chipEntry.visibility = View.GONE
    }
}

}

                              <p>
                                閉じるボタン(✕ボタン)をタップすると、ちゃんとViewがGONEになりました。
                              </p>
                              
                              <h2>
                                まとめ
                              </h2>
                              
                              <p>
                                実装自体はRadioButtonに形が似ていて、直感的で使いやすいものになっていました。
                              </p>
                              
                              <p>
                                Chip/ChipGroupはまだ正式リリースはされていませんが、タグの表示など、活用できるシーンは多いかと思いますので、正式リリースが楽しみですね!
                              </p>