2015-01-05 4 views
26

私は私のリップルのために次のコードを持っている:Android 5.0 LollipopでRippleDrawableをコードで(xmlではなく)プログラムで使用するにはどうすればいいですか?

<?xml version="1.0" encoding="utf-8"?> 
<ripple xmlns:android="http://schemas.android.com/apk/res/android" 
    android:color="?android:colorControlHighlight"> 
    <item android:id="@+id/rip"> 

     <shape android:shape="oval"> 
      <solid android:color="?android:colorAccent"/> 
     </shape> 
    </item> 
</ripple> 

を今、私は、ユーザーに自分の色を選択する可能性を与えたいので、私はプログラム的に波紋を作成する必要があります。
thisが見つかりました。これは正しい方法だと思いますが、これをどのように処理するのか分かりません。

リップルは、ここで使用されます。

<ImageButton 
    android:id="@+id/add_button" 
    android:layout_width="@dimen/diameter" 
    android:layout_height="@dimen/diameter" 
    android:layout_gravity="end|bottom" 
    android:layout_marginBottom="@dimen/add_button_margin" 
    android:layout_marginEnd="@dimen/add_button_margin" 
    android:layout_alignParentBottom="true" 
    android:layout_alignParentEnd="true" 
    android:src="@drawable/ic_action_add_person" 
    android:tint="@android:color/white" 
    android:background="@drawable/oval_ripple" 
    android:elevation="@dimen/elevation_low" 
    android:stateListAnimator="@anim/button_elevation" 
    android:contentDescription="Neuer Spieler" /> 

は、私はこのようなRippleDrawableに背景を設定する必要があります。

addButton.setBackground(ripple); 
+0

xmlリソースはどこにありますか? – pskink

+0

@pskink最初の投稿を編集しました:) – ich5003

+0

新しいRippleDrawableを作成するときの問題は何ですか? – pskink

答えて

44

これは私がこれを達成することができた方法です。

これはApi 21+のみですので、下位バージョンをサポートする場合は通常のDrawableにフォールバックする必要があります。

public static RippleDrawable getPressedColorRippleDrawable(int normalColor, int pressedColor) 
{ 
    return new RippleDrawable(getPressedColorSelector(normalColor, pressedColor), getColorDrawableFromColor(normalColor), null); 
} 

public static ColorStateList getPressedColorSelector(int normalColor, int pressedColor) 
{ 
    return new ColorStateList(
     new int[][] 
      { 
       new int[]{android.R.attr.state_pressed}, 
       new int[]{android.R.attr.state_focused}, 
       new int[]{android.R.attr.state_activated}, 
       new int[]{} 
      }, 
     new int[] 
      { 
       pressedColor, 
       pressedColor, 
       pressedColor, 
       normalColor 
      } 
    ); 
} 

public static ColorDrawable getColorDrawableFromColor(int color) 
{ 
    return new ColorDrawable(color); 
} 

編集: 私はいくつかのより多くの本に手を加えそしてColorStateListは、上記の溶液とほぼ同じくらい複雑である必要はないことを発見しました。私はそれを以下のスニペットに単純化しました。 (上記のコードブロックの他のものはすべて同じです。私はColorStateListの作成を変更しました。)このメソッドは誰かのために動作しない場合は、上記のブロックを元のままにします。

new ColorStateList(
    new int[][] 
     { 
      new int[]{} 
     }, 
    new int[] 
     { 
      pressedColor 
     } 
); 
+5

非常にあなたのためにお答えいただきありがとうございます:) (upvote、十分な評判を与えることはできません)。 – ich5003

+0

確かなこと;それは私が共有することを嬉しく思う痛みだった。 :)それはあなたのために働いたのですか?私はそれをもう少し試してみて、ColorStateListを大幅に単純化して同じ結果を得ることができたので、私もその答えを編集するように編集しました。 – kdenney

+9

また、 'ColorStateList.valueOf(rippleColor);'を使用して行うこともできます。 – milosmns

19
public static Drawable getAdaptiveRippleDrawable(
    int normalColor, int pressedColor) { 
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { 
     return new RippleDrawable(ColorStateList.valueOf(pressedColor), 
       null, getRippleMask(normalColor)); 
    } else { 
     return getStateListDrawable(normalColor, pressedColor); 
    } 
} 

private static Drawable getRippleMask(int color) { 
    float[] outerRadii = new float[8]; 
    // 3 is radius of final ripple, 
    // instead of 3 you can give required final radius 
    Arrays.fill(outerRadii, 3); 

    RoundRectShape r = new RoundRectShape(outerRadii, null, null); 
    ShapeDrawable shapeDrawable = new ShapeDrawable(r); 
    shapeDrawable.getPaint().setColor(color); 
    return shapeDrawable; 
} 

public static StateListDrawable getStateListDrawable(
    int normalColor, int pressedColor) { 
    StateListDrawable states = new StateListDrawable(); 
    states.addState(new int[]{android.R.attr.state_pressed}, 
     new ColorDrawable(pressedColor)); 
    states.addState(new int[]{android.R.attr.state_focused}, 
     new ColorDrawable(pressedColor)); 
    states.addState(new int[]{android.R.attr.state_activated}, 
     new ColorDrawable(pressedColor)); 
    states.addState(new int[]{}, 
     new ColorDrawable(normalColor)); 
    return states; 
} 

あなたは描画可能を取得し、view.setDrawableを使用して、任意のビューに適用することができます。
Lollipop +のデバイスでは、リップルが表示されます。それ以外の場合は、表示色が変わります。

+0

これはいいですね。欠点は、 'StateListDrawable'の' ColorDrawable'が形状を持たないため、プレロリポップデバイスに適用したときに丸みを帯びたコーナーが緩む可能性があるということです。 シェイプを保持する代わりに、色付きの 'ShapeDrawable'を提供することができます。しかし、これは少し重くなるかもしれません。その場合、さらに別の解決策は、 "setColor"メソッドを使用してカスタム "ColorStateDrawable"を作成して、StateListDrawableに必要なすべてのオブジェクトを再インスタンス化しないようにすることです。 – John

+0

ここに近いものが見つかりました:https://github.com/gabrielemariotti/colorpickercollection/blob/master/ColorPicker/src/it/gmariotti/android/example/colorpicker/calendarstock/ColorStateDrawable.java – John

2

基本的に、新しいRippleDrawableオブジェクトを作成する必要があります。プレLollipopデバイスの場合は、StateListDrawable(既に提案されているもの)が必要です。ほとんどの場合、あなたがそのシングルトンから#getBackgroundDrawable()を使用したいと思うでしょう https://gist.github.com/milosmns/6566ca9e3b756d922aa5

:私はドロウアブルおよび着色に関連する有用な方法の束とやや機知GISTを書きました。

関連する問題