Androidのボタンの秘密。 パート2:リファクタリングレイアウト

挨拶、著名なコミュニティ。

前回の記事では、レイアウトのみを使用して、「オン/オフ」ボタンを作成しましたが、次のようになりました。
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:padding="6dp" android:background="#dddddd" > <ToggleButton android:id="@+id/act_main_btn_telephony" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@drawable/button_background" android:drawableLeft="@drawable/icon_phone" android:drawableRight="@drawable/icon_on_off" android:gravity="left|center_vertical" android:textOn="" android:textOff="" android:textSize="24sp" android:textStyle="bold|italic" android:textColor="@color/text_color" android:onClick="onToggleButtonClick" /> </RelativeLayout> 

XMLコードはかなり重くなりました。 この記事では、本当に美しくする方法を示します。 アプリケーションのメンテナンスを複雑にしたり、チームリーダーに不満を抱かせる可能性のあるものをすべて削除して、コードを半分にします。 この記事では、文字列リソース( strings.xml )、次元リソース( dimens.xml )、スタイルとテーマ( styles.xml )を使用します。 記事の最初の部分に慣れていない場合は、少なくとも彼女の目を通すことをお勧めします。

前の記事からAndroidアプリケーションプロジェクトをダウンロードすることもできますこれについては、このパートで詳しく説明します。

ボタンは次のようになります。
画像
画像

押された状態のボタンは、右側に表示されます。つまり、指でボタンを保持しています。 左側-押されていない、オンおよびオフモード。

テキストリソースstrings.xml

コードのリファクタリングをしましょう。 そこには間違いなく、たとえばという言葉があります。 アプリケーションを複数の言語に翻訳するには、すべてのテキスト定数をstrings.xmlファイルに収集する必要があります。 すでに作成されており、 res/valuesディレクトリにあります。 開いて、その内容を次のものに置き換えます。
 <?xml version="1.0" encoding="utf-8"?> <resources> <string name="app_name">MysteriesOfButtons</string> <string name="action_settings"></string> <string name="act_main_telephony"></string> </resources> 

そこで、テキスト定数act_main_telephonyを宣言しました。 次に、ボタンテキストandroid:textOnandroid:textOff@string/act_main_telephonyリンクに@string/act_main_telephonyます。
  <ToggleButton android:id="@+id/act_main_btn_telephony" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@drawable/button_background" android:drawableLeft="@drawable/icon_phone" android:drawableRight="@drawable/icon_on_off" android:gravity="left|center_vertical" android:textOn="@string/act_main_telephony" android:textOff="@string/act_main_telephony" android:textSize="24sp" android:textStyle="bold|italic" android:textColor="@color/text_color" /> 

これからのコードの量は増えただけですが、これは少し良いですが、これはアプリケーションを便利にローカライズする能力に対する料金です。 どのくらい正確にローカライズできますか? strings.xmlファイルstrings.xml res/valuesディレクトリにあります。 今、ロシア語のテキストを書いています。 英語もサポートしたいとします。 これを行うには、 res/values-enディレクトリを作成し、その中に別のstrings.xmlファイルを作成します。 最初のファイルと同じ定数をすべて含む必要がありますが、すでに英語になっています。 アプリケーションを起動すると、Androidは主にユーザーがデフォルトでシステムにインストールしたロケールをアプリケーションで検索します。 アプリケーションにこのロケールのリソースがない場合、Androidはデフォルトのロケール、つまり接尾辞なしのres/valuesディレクトリからリソースを取得します。 任意の言語のテキストが存在する場合がありますが、必ずしもロシア語や英語ではありません。 ユーザーがアプリケーションで利用可能な他のリソースに適合しない場合、このリソースが使用されます。 valuesのリソースだけでなく、他のリソースもローカライズすることができvalues 。たとえば、画像によってテキストが指定されている場合、多くの場合drawableローカライズします。 詳細に興味がある場合は、Google のアプリケーションのローカライズAndroidが最適なリソースを選択する方法 に関する興味深い記事を読むことをお勧めします 。 時間があれば、この質問は非常に広範囲にわたるため、ローカリゼーションに関する別の記事を例とともに準備しようとします。

スタイルとテーマ:styles.xml

碑文と左のアイコンのみが異なる10個のボタンが必要な場合はどうでしょうか。 すべてコピーしますか? レイアウトファイルのサイズは非常に大きくなり、繰り返しコードの80%が含まれます。 ここでスタイルが役立ちます。 繰り返すことができるすべてのものをスタイルに入れましょう。 幸いなことに、Androidスタイルのファイル開発にあまり慣れていない場合、Eclipse用ADTプラグインを使用するとプロセスが少し簡単になります。

スタイルを抽出するには、 Graphical LayoutGraphical Layoutモードで開き、ボタンを選択します。 それを右クリックして、「 Extract StyleExtract Styleを選択します。


スタイル名: styleOnOffButtonstyleOnOffButtonandroid:textOnandroid:textOnおよびandroid:textOffを除くすべての属性を残しandroid:textOff 。これらはアプリケーションのボタンごとに異なります。 残りの属性はスタイルでレンダリングされます:


OKをクリックします。 結果のスタイルは、 res/values/styles.xml
  <style name="styleOnOffButton"> <item name="android:background">@drawable/button_background</item> <item name="android:drawableRight">@drawable/icon_on_off</item> <item name="android:gravity">left|center_vertical</item> <item name="android:onClick">onToggleButtonClick</item> <item name="android:textColor">@color/text_color</item> <item name="android:textSize">24sp</item> <item name="android:textStyle">bold|italic</item> </style> 

ただし、ボタンのテキストは大幅に減少しています。
  <ToggleButton android:id="@+id/act_main_btn_telephony" android:layout_width="match_parent" android:layout_height="wrap_content" android:drawableLeft="@drawable/icon_phone" android:textOn="@string/act_main_telephony" android:textOff="@string/act_main_telephony" /> 

ここで、10個のボタンを作成するには、はるかに少ないテキストと最小限のコード重複を記述する必要があります。 注意:属性android:layout_widthおよびandroid:layout_heightはスタイルされていません。 これらは、レイアウトファイルの各要素に存在する必要があります。 もちろん、 android:id属性には、オブジェクトごとに独自の属性があるため、スタイルにも表示されません。 それでも、結果のコードは十分にコンパクトであるため、便利に再利用できます。

ここでアプリケーションを実行すると、すべてが「浮いている」ことがわかり、結果は予想したものとはまったく異なります。 なんで? スタイルは、作成されたものの、ボタンには適用されなかったためです。

属性style="@style/styleOnOffButton"指定して、ボタンにスタイルを適用できます。 これは、スタイルを抽出するときに、抽出Set style attribute on extracted elementsオプションを有効にした場合に自動的に行われます。 どちらの方法でも機能しますが、これらのオプションは最良のオプションではありません。これは、この行を各ウィンドウの各ボタンインスタンスに書き込む必要があるためです。 これを避けたいです。 原則として、アプリケーションは同じコントロールに対して同じスタイルを使用しますが、これは基本的な設計ルールの1つです。 つまり、すべてのオン/オフボタンは同じように見え、アイコンとテキストのみが異なります。 1つが長方形になり、もう1つが円形になり、3つ目がひし形になることはほとんどありません。

これにより、テーマのスタイルを規定する機会が与えられます。 styles.xmlを開き、次のテキストを見つけます。
  <!-- Application theme. --> <style name="AppTheme" parent="AppBaseTheme"> <!-- All customizations that are NOT specific to a particular API-level can go here. --> </style> 

これがアプリケーションのテーマです。 すべてのToggleButtonボタンは同じスタイルである必要があることを指摘しましょう。
  <!-- Application theme. --> <style name="AppTheme" parent="AppBaseTheme"> <!-- All customizations that are NOT specific to a particular API-level can go here. --> <item name="android:buttonStyleToggle">@style/styleOnOffButton</item> </style> 

android:buttonStyleToggleとは何ですか、他に何をスタイリングできますか? スタイルに関する完全なドキュメントがまだ見つかりませんでした。 誰かが彼女を見たら、コメントを書いてください。 したがって、私はAndroidソースに直接目を向けます。幸いなことに、Androidソースは誰でも利用できます。 私はADTを使用しています。Androidスタイルのソースコードは、 adt-bundle-windows\sdk\platforms\android-< API>\data\res\values\themes.xmlます。 Window->Android SDK Manager 、Eclipseから直接実行されるAndroid SDK Managerユーティリティを使用しWindow->Android SDK Managerます。このユーティリティは、メニューWindow->Android SDK Managerです。

そして、もう1つ修正が必要です。 作成したスタイルはボタンスタイルから継承されていません。つまり、コントロールを押すことができなくなっています。 アプリケーションを今すぐ起動して、ボタンを押そうとしているかどうかを簡単に確認できます。 それを治す方法は? android:style/Widget.Button.Toggleスタイルからスタイルを継承する必要がありますandroid:style/Widget.Button.ToggleこれはすべてのToggleButtonデフォルトスタイルです:
  <style name="styleOnOffButton" parent="android:style/Widget.Button.Toggle"> <item name="android:background">@drawable/button_background</item> <item name="android:drawableRight">@drawable/icon_on_off</item> <item name="android:gravity">left|center_vertical</item> <item name="android:onClick">onToggleButtonClick</item> <item name="android:textColor">@color/text_color</item> <item name="android:textSize">24sp</item> <item name="android:textStyle">bold|italic</item> </style> 

どこでandroid:style/Widget.Button.Toggleを入手しandroid:style/Widget.Button.Toggleandroid:style/Widget.Button.Toggle ? 同じAndroidソースのstyles.xml

ディメンションリソース:dens.xml

これですべてが正常に機能するようになりました。 しかし、さらにいくつかの小さな改善を行う必要があります。 お気づきのように、 styleOnOffButtonスタイルstyleOnOffButtonandroid:textSize 、これは24sp定数で指定されています。 アプリケーションにボタン以外のテキストがある場合は、おそらく全体のスタイルを保持するために同じサイズにしたいでしょう。 そしてこれは、異なる場所で24sp定数を複数回使用することを意味します。 また、後でテキストのサイズを試してみたい場合は、アプリケーション全体でこれらの定数を変更する必要があります。 これを避けるために、名前付きサイズ定数を宣言しましょう。 res/values/dimens.xmlを開き、その内容をすべて次のものに置き換えます。
 <resources> <dimen name="text_size">24sp</dimen> <dimen name="activity_padding">6dp</dimen> </resources> 

ご覧のtext_sizeに加えてtext_sizeここには別の定数がありますtext_sizeです。 レイアウトのコードを思い出すと、 RelativeLayoutタグに定数android:padding="6dp"れます。 また、すべてのアプリケーションウィンドウで画面の境界からのインデントも同じように論理的であるため、この値自体が定数を要求します。

24spスタイルの定数を新しいリソース@dimen/text_sizeます。
  <style name="styleOnOffButton" parent="android:style/Widget.Button.Toggle"> <item name="android:background">@drawable/button_background</item> <item name="android:drawableRight">@drawable/icon_on_off</item> <item name="android:gravity">left|center_vertical</item> <item name="android:onClick">onToggleButtonClick</item> <item name="android:textColor">@color/text_color</item> <item name="android:textSize">@dimen/text_size</item> <item name="android:textStyle">bold|italic</item> </style> 

そして、リソース内の定数を持つactivity_main.xmlファイルのRelativeLayoutタグのテキスト:
 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:padding="@dimen/activity_padding" android:background="#dddddd" > 


そしてスタイルについてもう少し

もう一度スタイルについて考えてみましょう。 すべてのToggleButton同じスタイルを作成したので、すべてのウィンドウにスタイルを作成してみませんか? さらに、境界線からのインデントに加えて、すべてのウィンドウには共通の背景色があります。 このスタイルはシンプルで、何からも継承する必要はありません。手動で書きましょう。 styles.xmlを開き、次のコードを終了タグの前の最後に追加します。
  <color name="activity_background_color">#dddddd</color> <style name="styleActivity"> <item name="android:background">@color/activity_background_color</item> <item name="android:padding">@dimen/activity_padding</item> </style> 

色を設定する別の方法は、 colorタグを使用してリソースファイルで行います。

すべてのRelativeLayoutがActivityのメイン要素ではないため、 ToggleButton行ったように、すべてのRelativeLayoutスタイルすることはできません。 この場合、 style属性を使用して、 styleが必要な要素でスタイルを明示的に指定する必要があります。 レイアウトにスタイルを書いて、何が得られたのかを見てみましょう:
 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" style="@style/styleActivity" > <ToggleButton android:id="@+id/act_main_btn_telephony" android:layout_width="match_parent" android:layout_height="wrap_content" android:drawableLeft="@drawable/icon_phone" android:textOn="@string/act_main_telephony" android:textOff="@string/act_main_telephony" /> </RelativeLayout> 

スタイルのウィンドウのすべての属性。 新しいアクティビティごとに、スタイルstyle="@style/styleActivity"ルート要素に指定するだけで十分です。ウィンドウは他のアプリケーションウィンドウと同じように見えます。

おわりに

元のレイアウトと最適化されたレイアウトを比較します。 ここに私たちが持っていたものがあります:
 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:padding="6dp" android:background="#dddddd" > <ToggleButton android:id="@+id/act_main_btn_telephony" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@drawable/button_background" android:drawableLeft="@drawable/icon_phone" android:drawableRight="@drawable/icon_on_off" android:gravity="left|center_vertical" android:textOn="" android:textOff="" android:textSize="24sp" android:textStyle="bold|italic" android:textColor="@color/text_color" android:onClick="onToggleButtonClick" /> </RelativeLayout> 

そして、何が起こったのか:
 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" style="@style/styleActivity" > <ToggleButton android:id="@+id/act_main_btn_telephony" android:layout_width="match_parent" android:layout_height="wrap_content" android:drawableLeft="@drawable/icon_phone" android:textOn="@string/act_main_telephony" android:textOff="@string/act_main_telephony" /> </RelativeLayout> 

真実はもっと美しくなりましたか? スタイルのボタンとウィンドウのすべての一般的な属性。 新しいボタンを作成する場合、新しいボタンを他のボタンと区別する属性、つまりアイコン、名前、識別子、親要素の位置のみを規定します。

すべての数値定数はdimens.xmlのファイルに隠されており、同じ定数のコピーペーストはありません。 すべての文字列定数は、 strings.xmlファイルにあります。 アプリケーションを他の言語にローカライズするには、このファイルのみを翻訳するだけで十分です。

元のバージョンと最適化されたバージョンの違いは、1つのウィンドウ要素でも顕著です。 実際のアプリケーションでは、ウィンドウ内にそれらの数十個が存在するため、最適化されたコードの読み取りと保守がはるかに容易になります。 私の最大のiPUMBアプリケーション-FUIBオンラインには約40のアクティビティが含まれています。 スタイルがなければ、ウィンドウデザインを40回コピーする必要があり、デザイナーが何か新しいものを思いついた場合は、このコードを40回変更する必要があります。

スタイルのもう1つの魅力は、チーム開発におけるコードの統合です。 書かれたスタイルファイルは、開発チームのすべてのメンバーにウィンドウを組版するための既製のツールを提供し、すべてのウィンドウは単一のユニットのように見え、リファクタリングや「調整」はありません。

この記事がお役に立てば幸いです。 次の記事では、Androidのレイアウトの他の微妙な点を間違いなく共有します。

便利なリンク

この記事の既製のAndroidアプリケーションプロジェクト
このパートで最終決定する前の記事のAndroidアプリケーションプロジェクト
Androidのボタンの秘密。 パート1:レイアウトの基本
アプリケーションのローカリゼーション
Androidが最適なリソースを選択する方法

Source: https://habr.com/ru/post/J206064/


All Articles