TextViewやButtonにアイコンを入れたり等、Bootstrapライブラリーを使うと簡単にスタイリッシュなテキストやボタンが作成できます。レイアウトの説明はたくさんあるのですが、コーディング実装例が少ないので作ってみました。
2021.2.1
Android Bootstrap
BootstrapはWebアプリケーションなどで使われている、ボタンや文字装飾を作成するフロントエンドWebアプリケーションフレームワークです。Android用のものもあります。
環境設定
Android Studioにライブライリーをインポートするには、幾つかの方法がありますが簡単な方法でやってみましょう。GitHubのサイト にある方法です。
build.gradle(Module.app) 内のdependenciesの記述です。バージョンはサイトを確認して適宜合わせてください。
1 2 3 4 5 |
... dependencies { ... implementation 'com.beardedhen:androidbootstrap:2.3.2' } |
gradle.prpertiesに
enableJetifier = true
を設定します。Androidプラグインは、サードパーティライブラリを自動的にAndroidXの依存関係に移行してを使用します
gradle.prperties
1 2 |
... android.enableJetifier=true |
TypefaceProvider.registerDefaultIconSets()
アイコンが使えるようにするために、プロジェクトのクラスをオーバーライドし追加します
別に、TestBootstrapのクラスを作成します(Licenseも忘れずに)
TestBootstrap.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
//package your.package.name; /* The MIT License (MIT)Copyright (c) 2013-2015 Bearded Hen Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.</td> */ import android.app.Application; import com.beardedhen.androidbootstrap.TypefaceProvider; // Applicationを継承 public class TestBootstrap extends Application { @Override public void onCreate() { super.onCreate(); TypefaceProvider.registerDefaultIconSets(); } } |
プロジェクトの構成はこうなります。プロジェクトのMainActivity.javaとは別のTestBootstrapクラスの作成です。
(この段階はMainActivity.javaは何もしません)
また
android:name=”.TestBootstrap”
をAndroidManifest.xml に追加します
AndroidManifest.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" ... <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:name=".TestBootstrap" android:theme="@style/AppTheme" > <activity ... </activity> </application> </manifest> |
XML レイアウト
AwesomTextViewやBootstrapButtonなど、タイトルに文字とアイコンを並べたりグループ化、角丸など色々できます。
activity_main.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 |
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:gravity="center" android:background="#dfe" tools:context=".MainActivity"> <com.beardedhen.androidbootstrap.AwesomeTextView android:id="@+id/awesome_textview" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="10dp" app:bootstrapBrand="success" app:fontAwesomeIcon="fa_android" android:textSize="32sp" app:bootstrapText="Awesome {fa_heart}" /> <com.beardedhen.androidbootstrap.BootstrapButton android:id="@+id/bootstrap_button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="20dp" app:bootstrapBrand="success" app:bootstrapSize="lg" app:buttonMode="regular" app:showOutline="false" app:roundedCorners="true" app:bootstrapText="Button {fa_heart} {fa_android}" /> <com.beardedhen.androidbootstrap.BootstrapButtonGroup android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="20dp" android:orientation="horizontal" app:bootstrapBrand="success" app:bootstrapSize="lg" app:roundedCorners="true" > <com.beardedhen.androidbootstrap.BootstrapButton android:id="@+id/bootstrap_button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/button1" /> <com.beardedhen.androidbootstrap.BootstrapButton android:id="@+id/bootstrap_button2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/button2" /> </com.beardedhen.androidbootstrap.BootstrapButtonGroup> <com.beardedhen.androidbootstrap.BootstrapLabel android:id="@+id/bootstrap_label" android:layout_width="200dp" android:layout_height="wrap_content" android:layout_margin="20dp" app:bootstrapBrand="primary" app:bootstrapHeading="h3" app:roundedCorners="true" android:text="@string/BootstrapLabel" /> <LinearLayout android:orientation="horizontal" android:gravity="center" android:layout_width="match_parent" android:layout_height="wrap_content"> <com.beardedhen.androidbootstrap.BootstrapEditText android:id="@+id/bootstrap_edittext" android:layout_width="180dp" android:layout_height="40dp" android:layout_margin="20dp" android:textSize="20sp" app:bootstrapSize="md" app:bootstrapBrand="info" android:hint="@string/hint" app:roundedCorners="true" /> <Button android:id="@+id/button" android:text="@string/button" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout> <com.beardedhen.androidbootstrap.BootstrapProgressBarGroup android:id="@+id/example_progress_bar_group_round_group" android:layout_width="300dp" android:layout_height="wrap_content" android:layout_margin="20dp" android:layout_gravity="center_horizontal" app:bootstrapSize="md" app:bootstrapMaxProgress="100"> <com.beardedhen.androidbootstrap.BootstrapProgressBar android:id="@+id/bootstrap_progressbar1" android:layout_width="0dp" android:layout_height="wrap_content" app:bootstrapBrand="success" app:bootstrapProgress="0" /> <com.beardedhen.androidbootstrap.BootstrapProgressBar android:id="@+id/bootstrap_progressbar2" android:layout_width="0dp" android:layout_height="wrap_content" app:bootstrapBrand="warning" app:bootstrapProgress="0" /> </com.beardedhen.androidbootstrap.BootstrapProgressBarGroup> <SeekBar android:id="@+id/seekbar" android:layout_width="200dp" android:layout_height="wrap_content" /> </LinearLayout> |
strings.xml
1 2 3 4 5 6 7 8 9 10 |
<resources> <string name="app_name">YourAppName</string> <string name="button">Button</string> <string name="button1">Button 1</string> <string name="button2">Button 2</string> <string name="BootstrapLabel">Bootstrap Label</string> <string name="hint">Input text</string> <string name="label1">Bootstrap</string> <string name="label2">Label</string> </resources> |
それぞれ、固有の設定もありますが元々の
android:layout_width
なども合わせて使えます。
ここでは、AwesomeTextView, BootstrapButton, BootstrapLabel, BootstrapEditText, BootstrapProgressBar を試しましたが、これ以外にもCircleThumbnailなどいくつかあります。
app:bootstrap… がエラーになる場合は
xmlns:app=”http://schemas.android.com/apk/res-auto”
import android.app.Application;
を忘れているかもしれません
「Alt」「Enter」で適正化されます
これができない場合は、今までの設定が正しくなされていないためだと思います
これで実行するとテキストやボタンが表示されたと思います
コーディングの実装
レイアウトでは魅力的なボタンやラベルが表示できましたが、それを実際に使って、文字とアイコンを表示させたり、ボタンクリックを受け取るにはどうするのでしょう。
カスタムUIなので、そのカスタムクラスでインスタンス生成をしていけばいいのですね。
MainActivity.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 |
//package your.package.name; /* The MIT License (MIT)Copyright (c) 2013-2015 Bearded Hen Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.</td> */ import androidx.appcompat.app.AppCompatActivity; import android.annotation.SuppressLint; import android.os.Bundle; import android.widget.Button; import android.widget.SeekBar; import com.beardedhen.androidbootstrap.AwesomeTextView; import com.beardedhen.androidbootstrap.BootstrapButton; import com.beardedhen.androidbootstrap.BootstrapEditText; import com.beardedhen.androidbootstrap.BootstrapLabel; import com.beardedhen.androidbootstrap.BootstrapProgressBar; import com.beardedhen.androidbootstrap.BootstrapText; public class MainActivity extends AppCompatActivity { private AwesomeTextView awesomeTextView; private BootstrapText.Builder builder; private BootstrapText bootstrapText1; private boolean flg = true; private BootstrapLabel bsLabel; private BootstrapEditText bsEditText; private BootstrapProgressBar bsProgressBar1, bsProgressBar2; int progA, progB = 0; @SuppressLint("WrongConstant") @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // BootstrapText.Builder builder = new BootstrapText.Builder(getApplicationContext(), true); // AwesomeTextView awesomeTextView = findViewById(R.id.awesome_textview); BootstrapButton bsButton = findViewById(R.id.bootstrap_button); // リスナーをボタンに登録 bsButton.setOnClickListener(v -> { if(flg){ builder = new BootstrapText.Builder(getApplicationContext(), true); bootstrapText1 = builder .addFontAwesomeIcon("fa_check-square") .addText(" チェック") .build(); } else{ builder = new BootstrapText.Builder(getApplicationContext(), true); bootstrapText1 = builder.addText("Awesome ").addFontAwesomeIcon("fa_heart").build(); flg = true; } awesomeTextView.setBootstrapText(bootstrapText1); }); // BootstrapLabel bsLabel= findViewById(R.id.bootstrap_label); BootstrapButton bsButton1 = findViewById(R.id.bootstrap_button1); bsButton1.setOnClickListener(v -> bsLabel.setText(R.string.label1)); BootstrapButton bsButton2 = findViewById(R.id.bootstrap_button2); bsButton2.setOnClickListener(v -> bsLabel.setText(R.string.label2)); // BootstrapEditText bsEditText = findViewById(R.id.bootstrap_edittext); Button button = findViewById(R.id.button); button.setOnClickListener(v -> { String str = bsEditText.getText().toString(); bsLabel.setText(str); }); // BootstrapProgressBar bsProgressBar1 = findViewById(R.id.bootstrap_progressbar1); bsProgressBar2 = findViewById(R.id.bootstrap_progressbar2); // SeekBar SeekBar seekBar = findViewById(R.id.seekbar); seekBar.setProgress(0); seekBar.setMax(100); seekBar.setOnSeekBarChangeListener( new SeekBar.OnSeekBarChangeListener() { @Override public void onProgressChanged( SeekBar seekBar, int progress, boolean fromUser) { progA = progress; progB = progress/2; if(progA+progB <= 100){ bsProgressBar1.setProgress(progA); bsProgressBar2.setProgress(progB); } } @Override public void onStartTrackingTouch(SeekBar seekBar) {} @Override public void onStopTrackingTouch(SeekBar seekBar) {} }); } } |
AwesomeTextViewでの文字とアイコンの合体表示はBootstrapText.Builderを使うのがわかりにくかったですが、カスタムViewという観点で構築すればそれほど難しくはないですね。
1 2 3 4 5 6 |
BootstrapText.Builder builder = new BootstrapText.Builder(getApplicationContext(), true); BootstrapText bootstrapText1 = builder .addFontAwesomeIcon("fa_check-square") .addText(" チェック") .build(); |
サンプル動画
これでattractiveなアプリが作れるかもしれません…
その他のLibraryページ
- Jsoup: HTML parser
- AndroidBootstrap:カスタムUI
- AChartEngine:グラフを描画
References:
GitHub – Bearded-Hen/Android-Bootstrap
http://bearded-hen.github.io/Android-Bootstrap/