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:textOn



android: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 Layout



Graphical Layout



モードで開き、ボタンを選択します。 それを右クリックして、「 Extract Style



Extract Style



を選択します。





スタイル名: styleOnOffButton



styleOnOffButton



android:textOn



android: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.Toggle



android:style/Widget.Button.Toggle



? 同じAndroidソースのstyles.xml







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


これですべてが正常に機能するようになりました。 しかし、さらにいくつかの小さな改善を行う必要があります。 お気づきのように、 styleOnOffButton



スタイルstyleOnOffButton



android: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が最適なリソースを選択する方法



All Articles