LoginSignup
11
9

More than 3 years have passed since last update.

【Android】AndroidでFlowLayout(タグクラウド的なあれ)を実現する

Last updated at Posted at 2016-12-26

2018/2/28、スタディプラス株式会社を退社しました。
2019/11/5、リポジトリが消えていたので、近々書き直します。今となってはFlowを使えばいい気もしますが…


こんにちは、りんごのマークをこよなく愛すmayahiroです。
りんごのマークをこよなく愛していますが、今もポジションはAndroidアプリエンジニアです。

アドベントカレンダーもひと段落した、今日この頃、皆様年末進行でやられていらっしゃいますでしょうか?

タグクラウドっぽいレイアウト

さて、Android開発において、タグクラウドっぽいレイアウトを行いたい場合、どうすれば良いのでしょう?
この度、StudyplusAndroidアプリにおいて、それっぽいレイアウトを実現する必要があり、Google先生に聞いたところ以下の2つのライブラリが有名なようでした。

これらのライブラリを利用してもよかったのですが、初めてのCustomLayoutを作るいい機会かもと考え、自前のシンプルなFlowLayoutを作成することにしました。

  • なお、ここでいうタグクラウドっぽいレイアウトについては、以下のようなレイアウトを思い浮かべてください。 f95eabbc-afbc-9853-8d33-c894463fac46.png

実装

FlowLayout.javaをご覧ください。

onMeasureで必要な幅と高さを計算して、onLayoutで実際に子Viewを配置しています。

というわけで、紆余曲折ありましたが出来上がりました

何事も初めてというのは大変なものですが、人間やれば出来るものです。
ということで、出来上がったFlowLayoutを使ったサンプルアプリはこちら

- https://github.com/studyplus/FlowLayoutSampleApplication

ちなみに、本体アプリから切り出す過程で別物といえるほど書き換えてしまったので、これから本体アプリにフィードバックする作業ががが・・・

作ったレイアウト

1.画面幅を考慮して子Viewをいい感じに配置する

b222040a-f239-7909-a32f-5d7110b45000.png

2.子Viewが全て同じサイズだった場合にいい感じにマージンを調整しつつ配置する

マージン未調整 マージン調整
94043621-96e0-3680-f7b4-d880da422ca3.png 1efedc9d-d104-9025-fb10-9e74fb65f673.png
a09cfdfc-e201-8624-57c8-0ef52d68aee2.png 118092fd-7946-2ca1-e240-7ca41d698a1d.png

3.画面の向きに関わらず、いい感じに配置します

ポートレート ランドスケープ
945e2256-7a4e-909a-4032-3629da2d947c.png a9555ce5-2036-21ce-debf-debae7c26654.png
b0239555-86a2-5d7b-6c2c-3b6c1cfe5878.png 772744af-065e-e075-694f-afb8e5389824.png
f886f315-3d9f-5e44-c8dd-dcf2409781de.png e99599ba-d692-6237-be2a-1ec0f636dbb7.png
1b602734-532e-609e-1dee-2de8d9b88836.png 09e1f782-00f7-2b63-fb85-d47d6ae268bc.png

使い方

1.適当にlayoutに配置

<xyz.mayahiro.flowlayoutsampleapplication.FlowLayout
    android:id="@+id/flow_layout_1"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:padding="16dp"
    app:allChildrenSameSize="false"
    app:minMargin="4dp" />
  • allChildrenSameSizeを true にすると上記2のマージン調整が実行されます
    • 必ず、全ての子Viewを同じサイズにしてください

2.適当にデータをセット

LayoutInflater layoutInflater = LayoutInflater.from(this);

FlowLayout flowLayout1 = (FlowLayout) findViewById(R.id.flow_layout_1);
String label = "ho";
for (int i = 0; i < 10; i++) {
    CheckableChip chip = (CheckableChip) layoutInflater.inflate(R.layout.checkable_chip, flowLayout1, false);
    chip.setData(R.drawable.ic_local_offer, label, false, true);
    flowLayout1.addView(chip);

    label += "ho";
}

3.詳細についてはサンプルプロジェクトをご覧ください。

未だに悩んでる箇所

allChildrenSameSize

命名がイマイチなのはさておき・・・全子Viewが同じサイズならマージン調整とかした方が綺麗だよなーという考えで作ったのですが、ここはlayout_alignautojustifyを設定できるようにして、justifyだった場合はマージン調整(均等割り付け)を行うべきなのか???

ただ、それだと最終行だけやたらと子View間が離れたりするなー・・・

などなど、と未だにうだうだと悩んでいるのですが、この辺はきっと時が解決してくれるでしょう。

最後に

初めてのCustomLayoutということで、「これはちょっと・・・」という部分もあるかもしれません。。。
ご意見、ご感想、Issue、Pull request等々、お待ちしております。

11
9
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
9