2016-01-19 25 views
7

私は自分のアプリケーションのためのdrawableを準備しています。私はラジオボタンをたくさん持っています。ラジオボタンは、オプションのフレームで画像として表示されます(チェックされている場合)。あなたがしたいプレイ「2つの違いを見つける」をしないとAndroidでdrawableの部分を再利用

<?xml version="1.0" encoding="utf-8"?> 
<selector xmlns:android="http://schemas.android.com/apk/res/android"> 
    <item android:state_checked="true"> 
     <layer-list> 
      <item> 
       <shape android:shape="rectangle"> 
        <solid android:color="@color/colorPrimary" /> 
       </shape> 
      </item> 

      <item> 
       <inset android:insetTop="@dimen/selectionBorderSize" 
        android:insetLeft="@dimen/selectionBorderSize" 
        android:insetRight="@dimen/selectionBorderSize" 
        android:insetBottom="@dimen/selectionBorderSize"> 
        <layer-list> 
         <item> 
          <shape android:shape="rectangle"> 
           <solid android:color="#ffffff"></solid> 
          </shape> 
         </item> 
         <item> 
          <bitmap android:src="@drawable/sharp6" > 
           <padding android:bottom="@dimen/selectionBorderSize" 
            android:top="@dimen/selectionBorderSize" 
            android:left="@dimen/selectionBorderSize" 
            android:right="@dimen/selectionBorderSize" /> 
          </bitmap> 
         </item> 
        </layer-list> 
       </inset> 
      </item> 
     </layer-list> 
    </item> 

    <item android:state_checked="false"> 
     <layer-list> 
      <item> 
       <shape android:shape="rectangle"> 
        <solid android:color="#ffffff" /> 
       </shape> 
      </item> 

      <item> 
       <inset android:insetTop="@dimen/selectionBorderSize" 
        android:insetLeft="@dimen/selectionBorderSize" 
        android:insetRight="@dimen/selectionBorderSize" 
        android:insetBottom="@dimen/selectionBorderSize"> 
        <layer-list> 
         <item> 
          <shape android:shape="rectangle"> 
           <solid android:color="#ffffff"></solid> 
          </shape> 
         </item> 
         <item> 
          <bitmap android:src="@drawable/sharp6" > 
           <padding android:bottom="@dimen/selectionBorderSize" 
            android:top="@dimen/selectionBorderSize" 
            android:left="@dimen/selectionBorderSize" 
            android:right="@dimen/selectionBorderSize" /> 
          </bitmap> 
         </item> 
        </layer-list> 
       </inset> 
      </item> 
     </layer-list> 
    </item> 

    <item> 
     <shape android:shape="rectangle"> 
      <solid android:color="#ffffff" /> 
     </shape> 
    </item> 
</selector> 

、変更する唯一のものは<bitmap>タグ内の画像です:

<?xml version="1.0" encoding="utf-8"?> 
<selector xmlns:android="http://schemas.android.com/apk/res/android"> 
    <item android:state_checked="true"> 
     <layer-list> 
      <item> 
       <shape android:shape="rectangle"> 
        <solid android:color="@color/colorPrimary" /> 
       </shape> 
      </item> 

      <item> 
       <inset android:insetTop="@dimen/selectionBorderSize" 
        android:insetLeft="@dimen/selectionBorderSize" 
        android:insetRight="@dimen/selectionBorderSize" 
        android:insetBottom="@dimen/selectionBorderSize"> 
        <layer-list> 
         <item> 
          <shape android:shape="rectangle"> 
           <solid android:color="#ffffff"></solid> 
          </shape> 
         </item> 
         <item> 
          <bitmap android:src="@drawable/sharp7" > 
           <padding android:bottom="@dimen/selectionBorderSize" 
            android:top="@dimen/selectionBorderSize" 
            android:left="@dimen/selectionBorderSize" 
            android:right="@dimen/selectionBorderSize" /> 
          </bitmap> 
         </item> 
        </layer-list> 
       </inset> 
      </item> 
     </layer-list> 
    </item> 

    <item android:state_checked="false"> 
     <layer-list> 
      <item> 
       <shape android:shape="rectangle"> 
        <solid android:color="#ffffff" /> 
       </shape> 
      </item> 

      <item> 
       <inset android:insetTop="@dimen/selectionBorderSize" 
        android:insetLeft="@dimen/selectionBorderSize" 
        android:insetRight="@dimen/selectionBorderSize" 
        android:insetBottom="@dimen/selectionBorderSize"> 
        <layer-list> 
         <item> 
          <shape android:shape="rectangle"> 
           <solid android:color="#ffffff"></solid> 
          </shape> 
         </item> 
         <item> 
          <bitmap android:src="@drawable/sharp7" > 
           <padding android:bottom="@dimen/selectionBorderSize" 
            android:top="@dimen/selectionBorderSize" 
            android:left="@dimen/selectionBorderSize" 
            android:right="@dimen/selectionBorderSize" /> 
          </bitmap> 
         </item> 
        </layer-list> 
       </inset> 
      </item> 
     </layer-list> 
    </item> 

    <item> 
     <shape android:shape="rectangle"> 
      <solid android:color="#ffffff" /> 
     </shape> 
    </item> 
</selector> 

もう1:一つの描画可能では次のようになります。

私は全体的な感触があります。ここにあります。このドロアブルの一部を再利用する方法はありますか?

ウェット、いいえDRY

答えて

6

簡潔に言えば、XML描画可能ファイルのパラメータがないため、これは少し複雑になる可能性があります。

通常すべての単一の<item>の内容を個別のドロウアブルファイルに分割してから、<item android:drawable="..." />に含めようとします。それらは他のdrawableで再利用できます。

あなたは別のファイルに以下の項目を移動することができたとえば:あなたのケースでは

<item android:drawable="@drawable/shared_drawable" /> 

<item> 
    <shape android:shape="rectangle"> 
     <solid android:color="#ffffff" /> 
    </shape> 
</item> 

次に、あなたはそれがどこにもそれが必要とされる(再利用)を含むことができ、 <bitmap>要素が階層の深いところに埋め込まれているので、このアプローチを使用すると〜10%しか節約できません。


もう、少しエキゾチックなアプローチは、単一の描画可能なテンプレートから複数のXMLドローアブルを生成するために、Gradleのタスクを使用しています。これは明らかにGradleまたはAndroid Studioをそれぞれ使用する必要があります。

/res/rawフォルダ(または問題のないフォルダ)にドロアブルファイルを置くことができます。私はこのXMLテンプレートファイルの名前をdrawable_template.xmlとします。このファイルでは、実際のビットマップ描画可能の名前のプレースホルダとしてのGroovyテンプレート変数${bitmapdrawable}を使用します。

... 
    <item> 
     <bitmap android:src="@drawable/${bitmapdrawable}"><!-- placeholder for gradle --> 
      ... 
     </bitmap> 
    </item> 
... 

今、私たちは希望描画可能ビットマップと実際の/res/drawableフォルダに描画可能なテンプレートをコピーするにはGradleのタスクを定義する必要があります付属:このスクリプトは、アプリケーションの(モジュールの)build.gradleファイルに入れることができ

def drawablesToGenerate = ['sharp5', 'sharp6', 'sharp7', 'sharp8'] // bitmap names 
task drawableTemplate << { 
    drawablesToGenerate.each { drawableName -> // for each drawable 
     copy { 
      println("copy template for ${drawableName}") 
      from 'src/main/res/raw' // source folder 
      into 'src/main/res/drawable' // target folder 
      include 'drawable_template.xml' // template file 
      // rename file to final drawable 
      rename('drawable_template.xml', "drawable_gen_${drawableName}.xml") 
      expand(bitmapdrawable: "${drawableName}") 
     } 
    } 
} 
preBuild.dependsOn drawableTemplate 

コンパイル時に、1つのテンプレートファイルから異なるビットマップを含む最終的な描画可能ファイルが生成されます。彼らは名前がdrawable_gen_sharpX.xmlであり、通常のドロウアブルとして使用することができます。