Little Strange Software

スマホアプリの開発を行う LittleStrangeSoftware のブログです。

kotlinでコードから動的に<SHAPE>の装飾を変更するには?

どうも!LSSです!!

 Androidアプリ開発の勉強中です。
「まずは公開を目標にしてるけど、公開するとなると見栄えのいいものにしたいなぁ」
と思い、色々考えたり調べたりしていたところ、
【ボタン等のビューを装飾するためのxml】を作る事で、オリジナリティがあって
見栄えのいいボタン等を作れると知り、色々いじってました。

 そして出来たのが、例えばこんな感じ。

 

xmlでSHAPEによるボタンの装飾、やってみた!

ボタンの外観 xmlの記載内容
f:id:little_strange:20190916180825p:plain
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android=
"http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<gradient
android:angle="270"
android:startColor="#FFFFFF"
android:centerColor="#666666"
android:endColor="#555555"

android:type="radial"
android:gradientRadius="135dp"
android:centerX="0.2"
android:centerY="0.2"
/>

<corners android:radius="10dp"/>
<stroke android:width="1dp"
android:color="#666666"/>

</shape>
</item>
</selector>


 あと、これを普段の時と押し下げた時で作り分ける事で、見劣りしない
オリジナルのボタンが作れるのですね。

 

突然生まれた、コードからボタン外観を変更したい欲

 外観をなかなか素敵に装飾できる事が分かりました。
が、これを自分の好みに合うように色々カスタマイズしていきたい!と思った時に、
つどつど装飾用のxmlを打ち換えては、ボタンを設置したxmlのデザインビューで
確認したり、デザインビューで分かりにくかったらビルドしてエミュレータ上で
確認して…という手順。

 がっつりやり込みたいとなったら、結構な手間になってしまうんじゃないだろうか?
 やる事はパラメータの調整だけなので、エミュレータか実機の上でリアルタイムに
調整できる仕組みを作ったほうが結果ラクなんじゃないかな?
…てな事を考え始めてしまい、手をつけようとしたのですが…

 

ネットで検索するも、ズバリな情報が見つからない件

 部分的な記事や、逆にもっと大きい括りの記事は見つかりましたが、
kotlin勉強しはじめの自分にはちょっと敷居が高いように感じてしまいました^^;

 また、コードの記載が大抵がJAVAの記載で、kotlinで始めようとしている自分には
JAVAのこの書き方はkotlinではどう表現するんだっけ?」という翻訳も挟むため、
多分慣れた人ならすぐ分かるような事でも、また別のサイトを参考にしながら元のサイトの記載を理解する、といった工程を踏むため、余計に時間がかかりました。
(このへんちょっとうじうじしていて、読んでくれてる方に申し訳ない。
 自分が後日読み返した時に、自分が初心の頃どんな事でつまづいていたかの記録に、
 とそのまま書いてます^^;。)

 

表題の件 xmlのSHAPEをkotlinのコードから設定

  全てを網羅しているわけではありませんが、最初のボタンのようなものを作るのに
必要なコードをまとめたものが、以下になります。
 

xmlでの記載 kotlinでの記載
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android=
"http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<gradient
android:angle="270"
android:startColor="#FFFFFF"
android:centerColor="#666666"
android:endColor="#555555"

android:type="radial"
android:gradientRadius="135dp"
android:centerX="0.2"
android:centerY="0.2"
/>

<corners android:radius="10dp"/>
<stroke android:width="1dp"
android:color="#666666"/>

</shape>
</item>
</selector>
fun bt1redraw(){

val dp2px = getResources().getDisplayMetrics()
val gd0 = GradientDrawable(
GradientDrawable.Orientation.TOP_BOTTOM,
intArrayOf( Color.parseColor("#FFFFFF") ,
Color.parseColor("#666666") ,
Color.parseColor("#555555")
)
)
gd0.setGradientType(GradientDrawable.RADIAL_GRADIENT)
gd0.setGradientRadius(135 * dp2px.density)
gd0.setGradientCenter(0.2f ,0.2f )

gd0.setCornerRadius(10f * dp2px.density)
gd0.setStroke((1 * dp2px.density).toInt() ,
Color.parseColor("#666666"))

bt1.setBackgroundDrawable(gd0)

}

 パラメータの出現順は合わせました。
 分かりづらい部分はxml270がkotlinのTOP_BOTTOMに相当する事、
kotlin上では数値の単位がピクセルで指定するけどxmlではdpで指定したいので
dp2px = getResources().getDisplayMetrics()
としてdp2px.densityを掛けて、dpと同じ数値を入れてやればいいようにしている事、
あたりでしょうか。
(あ、kotlinのほうの最後のbt1は、自分が対象のボタンにつけたidです)

 

最後に。

 自分用の備忘録に、として書き始めました。

 もしも自分と同様に最近アプリ開発を勉強しはじめ、同じくSHAPEに興味を持って、検索でここに辿りついた方のお役に立てたら幸いです!