TODOアプリは殺風景なものがほとんどで、もっとデザイン入ったほうが良いよねって事で、拙作アプリ「しつこいTODO」ではデザインを頑張ってみました。
この記事では、そんな苦労した見た目を実現する方法を一通り紹介したいと思います。
iOS風、リスト削除・並べ替えの実装方法
iOSだとUICollectionViewを使えば簡単にリストの並べ替えと、洗練された横スワイプでの削除ができますが…
Androidは、RecyclerViewでやると結構面倒ですよね。
特に、横スライドでの削除が超面倒。
今回は、面倒な並べ替え、スワイプ削除を一発解決できるライブラリ
DragDropSwipeRecyclerView
で片付けました。
- 長押しでの並べ替え
- 右スワイプに別機能を割当て
- 行削除時のデータ更新処理の自動化
などなど、リスト操作でやりたいことが必要十分に揃いつつ、面倒な実装が一切ないのでオススメです。
角丸Viewの動的な作成方法
AndroidでViewを角丸にしたい場合、drawableにこんなxml作って
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<corners android:radius="20dp" />
</shape>
</item>
</selector>
viewのbackgroundに指定する方法が一般的、というか、それしかないと思っていたのですが。
xmlで指定する方法は、静的に設定したい場合は便利ですが、しつこいTODOの場合、テーマ機能と行の背景色変更機能があるので
- テーマによって枠線の色が変わるし
- 指定した色で背景色も変わる。
- 場所によって上だけもしくは下だけ角丸になる…。
組み合わせ分xmlを作るのは脳筋すぎるので、動的にコードからもろもろ指定できないものか調べたら、ありました!
GradientDrawable
これに、角丸、文字色、背景色、枠線の太さ・色を指定して、backgroundにセットすると、xmlでやっていたようなことがコードから動的に行なえます。
val gradientDrawable = GradientDrawable()
// 角丸指定
val radius = 40
gradientDrawable.cornerRadii = floatArrayOf(
radius, radius, radius, radius, // 上の角丸サイズ
radius, radius, radius, radius) // 下の角丸サイズ
// 枠線の太さと色
gradientDrawable.setStroke(2, Color.parseColor("#COLOR_CODE"))
// 背景色
gradientDrawable.setColor(Color.parseColor("#COLOR_CODE"))
// セット!
hogeView.background = gradientDrawable
これ、めちゃくちゃ便利なのでぜひ活用してみて下さい。
動的な画像の色変え方法
しつこいTODOは、テーマを入れ替えると、背景画像が変わるだけじゃなくて、文字色、枠線の色と、ボタンの色が変わります。(チェックマーク)
さらに、チェックボタンは選択状態とそうじゃない状態でも色が変わります。
テーマ毎に全部色が違う上に、テーマを定期的にポロポロ追加しているので、そのたびに色違いのボタンを追加で用意するのはキツいので、画像を1種類だけ用意して、ボタンの色をコードから動的に変えています。
val colorStateList = ColorStateList(
arrayOf(
intArrayOf(android.R.attr.state_selected), // 選択状態
intArrayOf(-android.R.attr.state_selected) // 非選択状態
),
intArrayOf(
Color.parseColor("#COLOR_CODE"), // 選択状態時の画像色
Color.parseColor("#COLOR_CODE") // 非選択状態時の画像色
)
)
checkBtn.backgroundTintList = colorStateList
これも、凝ったアプリを作る時に重宝するので、ぜひ活用してみてください。
背景にパターン画像を動的にセットする方法
テーマ変更機能用に色々な背景画像を用意していますが、端末のサイズは様々なので、上下左右が綺麗につながるパターン画像を用意して表示しています。
パターン画像をViewの背景に表示させるのはこんなコードです。
val imageID = requireContext().resources.getIdentifier("画像ファイル名", "mipmap", requireContext().packageName)
var bgBitmapDrawable = BitmapFactory.decodeResource(requireContext().resources, imageID).toDrawable(requireContext().resources)
bgBitmapDrawable.tileModeX = Shader.TileMode.REPEAT
bgBitmapDrawable.tileModeY = Shader.TileMode.REPEAT
hogeView.background = bgBitmapDrawable
これで、こんな画像が
こんな感じに表示されます。
ただ、画像のパターン表示は、OppoのReno Aという端末でだけ、引き伸ばされた変な表示になっちゃう問題が確認されています。
対応方法はまだ分からなくて、まだ今も困っています..
文字に打ち消し線を入れる方法
だんだん珍しくない方法になってきていますが…、せっかくなので載せておきます。
これが
こうなるやつ
val paint = textView.paint
if (checked) {
// 打ち消し線、入れる
paint.flags = textView.paintFlags or Paint.STRIKE_THRU_TEXT_FLAG
paint.isAntiAlias = true
} else {
// 打ち消し線、消す
paint.flags = 0
}
しつこいTODOでは文字の色もついでに変えています。
使っている素材のリンク
最後に、アプリで使っている素材の出どころを紹介します。
全て商用利用も無料です。
アプリ内のモノクロフラットアイコンは以下
ICOOON MONO
iconmonstr
設定画面のカラフルなフラットアイコン
FLAT ICON DESIGN
魅力的な背景画像
freepik