Я не думаю, що ви можете це зробити в 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 масив дозволяє вибрати декілька кольорових зупинок, а наступний поплавковий масив визначає місце розташування цих зупинок (від 0 до 1). Потім ви можете, як зазначено, просто використовувати це як стандартний Dravable.
Редагувати: Ось як ви могли це використовувати у своєму сценарії. Скажімо, у вас є кнопка, визначена в 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, усуваючи цей додатковий файл, але я не знаю як. Але гаразд, тоді така різновид хекійна частина входить у XML-файл шару_логу. Я поклав зелений градієнт як нижній шар, потім поклав половину накладання як другий шар, зміщений зверху на 50dp. Очевидно, ви хочете, щоб це число завжди було наполовину, не залежно від розміру вашого перегляду, а не фіксованим 50dp. Я не думаю, що ви можете використовувати відсотки. Звідти я щойно вставив TextView у мій тест test.xml, використовуючи файл layer_list.xml як фон.
Тада!
Ще одна редакція : я зрозумів, що ви можете просто вставити фігури в список шарів, що можна малювати як елементи, тобто більше вам не потрібні 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 справді працює.
Я збрехав, ще одна редакція
Гаразд, дізнайтеся, як вручну оновити цей шар, який можна малювати, щоб він відповідав висоті контейнера, повний опис можна знайти тут . Цей код повинен міститись у вашому методі 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);
}
});
І я закінчив! Вау! :)