Saya tidak berpikir Anda bisa melakukan ini dalam XML (setidaknya tidak di Android), tetapi saya telah menemukan solusi bagus yang diposting di sini yang sepertinya akan sangat membantu!
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);
Pada dasarnya, array int memungkinkan Anda untuk memilih beberapa pemberhentian warna, dan array float berikut menentukan posisi pemberhentian tersebut (dari 0 hingga 1). Anda kemudian dapat, seperti yang dinyatakan, cukup gunakan ini sebagai Drawable standar.
Sunting: Inilah cara Anda dapat menggunakan ini dalam skenario Anda. Katakanlah Anda memiliki Tombol yang didefinisikan dalam XML seperti:
<Button
android:id="@+id/thebutton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Press Me!"
/>
Anda kemudian memasukkan sesuatu seperti ini di metode onCreate () Anda:
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);
Saya tidak dapat menguji ini saat ini, ini adalah kode dari kepala saya, tetapi pada dasarnya hanya mengganti, atau menambahkan berhenti untuk warna yang Anda butuhkan. Pada dasarnya, dalam contoh saya, Anda akan mulai dengan hijau muda, memudar menjadi putih sedikit sebelum pusat (untuk memberikan memudar, daripada transisi yang keras), memudar dari putih ke hijau tengah antara 45% dan 55%, kemudian memudar dari hijau tengah ke hijau gelap dari 55% hingga akhir. Ini mungkin tidak persis seperti bentuk Anda (Saat ini, saya tidak memiliki cara untuk menguji warna-warna ini), tetapi Anda dapat memodifikasi ini untuk meniru contoh Anda.
Sunting: Juga, 0, 0, 0, theButton.getHeight()
merujuk pada koordinat gradien x0, y0, x1, y1. Jadi pada dasarnya, itu dimulai pada x = 0 (sisi kiri), y = 0 (atas), dan membentang ke x = 0 (kami menginginkan gradien vertikal, jadi tidak perlu sudut kiri ke kanan), y = tinggi dari tombol. Jadi gradien berjalan pada sudut 90 derajat dari bagian atas tombol ke bagian bawah tombol.
Sunting: Oke, jadi saya punya satu ide lagi yang berfungsi, haha. Saat ini berfungsi dalam XML, tetapi harus bisa dilakukan untuk bentuk di Jawa juga. Agak kompleks, dan saya membayangkan ada cara untuk menyederhanakannya menjadi satu bentuk, tapi inilah yang saya punya untuk saat ini:
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>
Oke, jadi pada dasarnya saya telah membuat gradien bentuk dalam XML untuk gradien hijau horizontal, ditetapkan pada sudut 0 derajat, pergi dari warna hijau kiri area atas, ke warna hijau kanan. Selanjutnya, saya membuat bentuk persegi panjang dengan abu-abu setengah transparan. Saya cukup yakin itu bisa dimasukkan ke dalam daftar lapisan XML, menghindarkan file tambahan ini, tapi saya tidak yakin bagaimana caranya. Tapi oke, maka jenis bagian hacky masuk pada file XML layer_list. Saya menempatkan gradien hijau sebagai lapisan bawah, lalu meletakkan setengah overlay sebagai lapisan kedua, diimbangi dari atas sebesar 50dp. Tentunya Anda ingin angka ini selalu setengah dari ukuran tampilan Anda, dan bukan 50dp tetap. Saya pikir Anda tidak dapat menggunakan persentase. Dari sana, saya baru saja memasukkan TextView ke tata letak test.xml saya, menggunakan file layer_list.xml sebagai latar belakang saya.
Tada!
Satu lagi edit : Saya menyadari Anda hanya bisa menanamkan bentuk ke dalam daftar layer yang dapat digambar sebagai item, artinya Anda tidak perlu 3 file XML terpisah lagi! Anda dapat mencapai hasil yang sama dengan menggabungkannya seperti:
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>
Anda dapat melapisi item sebanyak yang Anda suka dengan cara ini! Saya dapat mencoba untuk bermain-main dan melihat apakah saya bisa mendapatkan hasil yang lebih fleksibel melalui Java.
Saya pikir ini adalah suntingan terakhir ... : Oke, jadi Anda pasti dapat memperbaiki pemosisian melalui Java, seperti berikut:
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);
Namun! Ini mengarah ke masalah menjengkelkan lain di mana Anda tidak bisa mengukur TextView sampai setelah ditarik. Saya belum yakin bagaimana Anda bisa melakukan ini ... tetapi secara manual memasukkan nomor untuk topInset berfungsi.
Aku berbohong, satu lagi edit
Oke, temukan cara memperbarui lapisan ini secara manual agar sesuai dengan ketinggian wadah, uraian lengkap dapat ditemukan di sini . Kode ini harus masuk dalam metode onCreate () Anda:
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);
}
});
Dan saya sudah selesai! Wah! :)