回答:
私はあなたがこれをXMLで(少なくともAndroidでは)実行できないと思いますが、ここに投稿された優れた解決策のように見える良い解決策を見つけました!
ShapeDrawable.ShaderFactory sf = new ShapeDrawable.ShaderFactory() {
@Override
public Shader resize(int width, int height) {
LinearGradient lg = new LinearGradient(0, 0, width, height,
new int[]{Color.GREEN, Color.GREEN, Color.WHITE, Color.WHITE},
new float[]{0,0.5f,.55f,1}, Shader.TileMode.REPEAT);
return lg;
}
};
PaintDrawable p=new PaintDrawable();
p.setShape(new RectShape());
p.setShaderFactory(sf);
基本的に、int配列では複数のカラーストップを選択でき、次のfloat配列はそれらのストップが配置される場所(0から1)を定義します。その後、前述のように、これを標準のDrawableとして使用できます。
編集:シナリオでこれを使用する方法は次のとおりです。次のようにXMLで定義されたボタンがあるとします。
<Button
android:id="@+id/thebutton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Press Me!"
/>
次に、onCreate()メソッドに次のようなものを配置します。
Button theButton = (Button)findViewById(R.id.thebutton);
ShapeDrawable.ShaderFactory sf = new ShapeDrawable.ShaderFactory() {
@Override
public Shader resize(int width, int height) {
LinearGradient lg = new LinearGradient(0, 0, 0, theButton.getHeight(),
new int[] {
Color.LIGHT_GREEN,
Color.WHITE,
Color.MID_GREEN,
Color.DARK_GREEN }, //substitute the correct colors for these
new float[] {
0, 0.45f, 0.55f, 1 },
Shader.TileMode.REPEAT);
return lg;
}
};
PaintDrawable p = new PaintDrawable();
p.setShape(new RectShape());
p.setShaderFactory(sf);
theButton.setBackground((Drawable)p);
現在、これをテストすることはできません。これは私の頭からのコードですが、基本的には、必要な色に置き換えたり、ストップを追加したりするだけです。基本的に、私の例では、ライトグリーンから始めて、中心より少し前に白にフェードし(過酷な遷移ではなくフェードを与えるため)、白からミッドグリーンに45%から55%の間でフェードし、次に中間の緑から濃い緑まで55%から最後まで。これはあなたの形と正確に同じではないかもしれませんが(今のところ、私はこれらの色をテストする方法がありません)、これを変更して例を複製することができます。
編集:また、0, 0, 0, theButton.getHeight()
はグラデーションのx0、y0、x1、y1座標を参照します。したがって、基本的には、x = 0(左側)、y = 0(上)から始まり、x = 0まで伸びます(垂直方向のグラデーションが必要なので、左から右への角度は必要ありません)、y =高さボタンの。したがって、グラデーションはボタンの上部からボタンの下部まで90度の角度で進みます。
編集:さて、私はうまくいくもう一つのアイデアを持っています、ハハ。現在はXMLで動作しますが、Javaの形状でも実行できるはずです。それは一種の複雑で、それを単一の形状に単純化する方法があると思いますが、これは私が今持っているものです:
green_horizontal_gradient.xml
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle"
>
<corners
android:radius="3dp"
/>
<gradient
android:angle="0"
android:startColor="#FF63a34a"
android:endColor="#FF477b36"
android:type="linear"
/>
</shape>
half_overlay.xml
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle"
>
<solid
android:color="#40000000"
/>
</shape>
layer_list.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list
xmlns:android="http://schemas.android.com/apk/res/android"
>
<item
android:drawable="@drawable/green_horizontal_gradient"
android:id="@+id/green_gradient"
/>
<item
android:drawable="@drawable/half_overlay"
android:id="@+id/half_overlay"
android:top="50dp"
/>
</layer-list>
test.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center"
>
<TextView
android:id="@+id/image_test"
android:background="@drawable/layer_list"
android:layout_width="fill_parent"
android:layout_height="100dp"
android:layout_marginLeft="15dp"
android:layout_marginRight="15dp"
android:gravity="center"
android:text="Layer List Drawable!"
android:textColor="@android:color/white"
android:textStyle="bold"
android:textSize="26sp"
/>
</RelativeLayout>
わかりましたので、基本的には、XMLで、上部の領域の左の緑色から右の緑色に向かって0度の角度で設定された水平の緑のグラデーションの形状グラデーションを作成しました。次に、半透明の灰色の長方形を作りました。レイヤーリストのXMLにインライン化して、この余分なファイルを取り除くことができると確信していますが、方法はわかりません。しかし、わかりました。このようなハックな部分は、layer_list XMLファイルに含まれています。緑のグラデーションを下のレイヤーとして配置し、次に半分のオーバーレイを2番目のレイヤーとして、上から50 dpオフセットします。もちろん、この数は常にビューサイズの半分であり、固定の50 dpではありません。ただし、パーセンテージは使用できないと思います。そこから、layer_list.xmlファイルを背景として使用して、TextViewをtest.xmlレイアウトに挿入しました。
多田!
もう1つ編集:図形を項目として描画可能なレイヤーリストに埋め込むだけでよいことに気づきました。つまり、3つの個別のXMLファイルはもう必要ありません。次のようにそれらを組み合わせて同じ結果を得ることができます:
layer_list.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list
xmlns:android="http://schemas.android.com/apk/res/android"
>
<item>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle"
>
<corners
android:radius="3dp"
/>
<gradient
android:angle="0"
android:startColor="#FF63a34a"
android:endColor="#FF477b36"
android:type="linear"
/>
</shape>
</item>
<item
android:top="50dp"
>
<shape
android:shape="rectangle"
>
<solid
android:color="#40000000"
/>
</shape>
</item>
</layer-list>
このように好きなだけアイテムを重ねることができます!私は遊んでみて、Javaを介してより用途の広い結果が得られるかどうかを確認するかもしれません。
これが最後の編集だと思います...:わかりました。次のように、Javaを使用して位置を確実に修正できます。
TextView tv = (TextView)findViewById(R.id.image_test);
LayerDrawable ld = (LayerDrawable)tv.getBackground();
int topInset = tv.getHeight() / 2 ; //does not work!
ld.setLayerInset(1, 0, topInset, 0, 0);
tv.setBackgroundDrawable(ld);
しかしながら!これは、描画が完了するまでTextViewを測定できないという別の厄介な問題につながります。どうすればこれを達成できるのかはまだよくわかりませんが、topInsetに手動で数値を挿入しても機能します。
私は嘘をついた、もう1つの編集
わかりました。コンテナの高さに合わせてこのドローアブルを手動で更新する方法を見つけました。詳しい説明はこちらにあります。このコードは、onCreate()メソッドに追加する必要があります。
final TextView tv = (TextView)findViewById(R.id.image_test);
ViewTreeObserver vto = tv.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
LayerDrawable ld = (LayerDrawable)tv.getBackground();
ld.setLayerInset(1, 0, tv.getHeight() / 2, 0, 0);
}
});
これで完了です。ふew!:)
レイヤーリストを使用して、グラデーションの形状をxmlにレイヤー化できます。次のデフォルト状態のボタンを想像してください。2番目の項目は半透明です。ケラレのようなものを追加します。(カスタム定義の色はお許しください。)
<!-- Normal state. -->
<item>
<layer-list>
<item>
<shape>
<gradient
android:startColor="@color/grey_light"
android:endColor="@color/grey_dark"
android:type="linear"
android:angle="270"
android:centerColor="@color/grey_mediumtodark" />
<stroke
android:width="1dp"
android:color="@color/grey_dark" />
<corners
android:radius="5dp" />
</shape>
</item>
<item>
<shape>
<gradient
android:startColor="#00666666"
android:endColor="#77666666"
android:type="radial"
android:gradientRadius="200"
android:centerColor="#00666666"
android:centerX="0.5"
android:centerY="0" />
<stroke
android:width="1dp"
android:color="@color/grey_dark" />
<corners
android:radius="5dp" />
</shape>
</item>
</layer-list>
</item>
xmlシェイプのみを使用してそれを行うことができます-次のようにレイヤーリストと負のパディングを使用するだけです:
<layer-list>
<item>
<shape>
<solid android:color="#ffffff" />
<padding android:top="20dp" />
</shape>
</item>
<item>
<shape>
<gradient android:endColor="#ffffff" android:startColor="#efefef" android:type="linear" android:angle="90" />
<padding android:top="-20dp" />
</shape>
</item>
</layer-list>
この方法を試してみると、あなたが望むすべてのことを行うことができます。
それは次のようである、スタックので、最初か最後になるどの項目に注意してください。
<?xml version="1.0" encoding="utf-8"?>
<layer-list
xmlns:android="http://schemas.android.com/apk/res/android">
<item android:right="50dp" android:start="10dp" android:left="10dp">
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="3dp" />
<solid android:color="#012d08"/>
</shape>
</item>
<item android:top="50dp">
<shape android:shape="rectangle">
<solid android:color="#7c4b4b" />
</shape>
</item>
<item android:top="90dp" android:end="60dp">
<shape android:shape="rectangle">
<solid android:color="#e2cc2626" />
</shape>
</item>
<item android:start="50dp" android:bottom="20dp" android:top="120dp">
<shape android:shape="rectangle">
<solid android:color="#360e0e" />
</shape>
</item>