Aşağıdaki resme benzeyen bir şekil oluşturmak istiyorum:
Renk 1'den renk 2'ye üst yarı degradelere dikkat edin, ancak renk 3'ten renk 4'e degradelerin bir alt yarısı vardır. iki yarım ve 2 farklı gradyan ile 1 şekil yapmak.
Herhangi bir fikir?
Aşağıdaki resme benzeyen bir şekil oluşturmak istiyorum:
Renk 1'den renk 2'ye üst yarı degradelere dikkat edin, ancak renk 3'ten renk 4'e degradelerin bir alt yarısı vardır. iki yarım ve 2 farklı gradyan ile 1 şekil yapmak.
Herhangi bir fikir?
Yanıtlar:
Bunu XML'de yapabileceğinizi düşünmüyorum (en azından Android'de değil), ancak burada yayınlanan , çok yardımcı olacak gibi görünen iyi bir çözüm buldum !
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);
Temel olarak, int dizisi birden çok renk durağı seçmenize izin verir ve aşağıdaki kayan dizi, bu durakların nereye yerleştirileceğini tanımlar (0'dan 1'e). Daha sonra, belirtildiği gibi, bunu standart bir Çekilebilir olarak kullanabilirsiniz.
Düzenleme: Senaryoda bunu nasıl kullanabilirsiniz. XML'de şu şekilde tanımlanmış bir Button'ınız olduğunu varsayalım:
<Button
android:id="@+id/thebutton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Press Me!"
/>
Daha sonra onCreate () yönteminize böyle bir şey koyardınız:
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);
Bunu şu anda test edemiyorum, bu kafamdan gelen kod, ancak temel olarak sadece değiştirin veya ihtiyacınız olan renkler için duraklar ekleyin. Temel olarak, örneğimde, açık yeşil ile başlayacaksınız, merkezden biraz önce beyaza doğru solmaya (sert bir geçiş yerine solmaya vermek),% 45 ile% 55 arasında beyazdan orta yeşile solmaya, sonra solmaya orta yeşilden koyu yeşile% 55'ten sonuna kadar. Bu tam olarak şeklinize benzemeyebilir (Şu anda bu renkleri test etmenin bir yolu yok), ancak örneğinizi çoğaltmak için bunu değiştirebilirsiniz.
Düzenle: Ayrıca, 0, 0, 0, theButton.getHeight()
degradenin x0, y0, x1, y1 koordinatlarını ifade eder. Temel olarak, x = 0 (sol taraf), y = 0 (üst) ile başlar ve x = 0'a uzanır (dikey bir degrade istiyoruz, bu nedenle soldan sağa açı gerekli değildir), y = yükseklik düğmesinin. Böylece degrade düğmenin üstünden düğmenin altına 90 derecelik bir açıyla gider.
Edit: Tamam, bu yüzden işe yarar bir fikrim daha var, haha. Şu anda XML'de çalışıyor, ancak Java'daki şekiller için de yapılabilir. Bu biraz karmaşık ve tek bir şekle sadeleştirmenin bir yolu olduğunu hayal ediyorum, ama şimdilik bu var:
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>
Tamam, temelde XML'de yatay yeşil degrade için, üst alanın sol yeşil renginden sağ yeşil renge doğru 0 derecelik bir açıya ayarlanmış bir şekil gradyanı oluşturdum. Sonra, yarı şeffaf gri bir şekil dikdörtgeni yaptım. Bu ekstra dosyayı ortadan kaldırarak, katman listesi XML içine satır içine olabilir eminim, ama nasıl emin değilim. Ama tamam, o zaman hacky kısmı tür layer_list XML dosyasında geliyor. Yeşil degradeyi alt katman olarak koydum, sonra yarım katmanı ikinci katman olarak koydum, üstten 50dp ile dengeledim. Açıkçası, bu sayının her zaman görüntüleme boyutunuzun yarısı olmasına ve sabit bir 50dp olmasını istemezsiniz. Yine de yüzdeleri kullanabileceğinizi sanmıyorum. Oradan, layer_list.xml dosyasını arka planım olarak kullanarak test.xml düzenime bir TextView ekledim.
Tada!
Bir düzenleme daha : Şekilleri öğeler olarak çizilebilen katman listesine gömebildiğinizi fark ettim, yani artık 3 ayrı XML dosyasına ihtiyacınız yok! Bunları bir araya getirerek aynı sonucu elde edebilirsiniz:
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>
Bu şekilde istediğiniz kadar öğe katlayabilirsiniz! Oynamaya çalışabilir ve Java aracılığıyla daha çok yönlü bir sonuç alıp alamayacağımı görebilirim.
Sanırım bu son düzenleme ... : Tamam, bu yüzden Java gibi konumlandırmayı kesinlikle düzeltebilirsiniz:
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);
Ancak! Bu, TextView çizilene kadar ölçemediğiniz için başka bir can sıkıcı soruna yol açar. Bunu nasıl başarabileceğinizden henüz emin değilim ... ancak topInset için manuel olarak bir sayı eklemek işe yarıyor.
Yalan söyledim, bir tane daha düzenleme
Tamam, kabın yüksekliğine uyacak şekilde çizilebilir bu katmanı manuel olarak nasıl güncelleyeceğinizi öğrendim, tam açıklama burada bulunabilir . Bu kod onCreate () yönteminize eklenmelidir:
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);
}
});
Ve işim bitti! Whew! :)
Bir katman listesi kullanarak xml'deki degrade şekilleri katmanlayabilirsiniz. İkinci öğenin yarı saydam olduğu varsayılan duruma sahip bir düğme düşünün. Bir çeşit vinyet etkisi ekler. (Lütfen özel tanımlı renkleri affedin.)
<!-- 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>
Bunu sadece xml şekilleri kullanarak yapabilirsiniz - sadece katman listesi VE negatif dolguları aşağıdaki gibi kullanın:
<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>
Bu yöntemi deneyin, sonra istediğiniz her şeyi yapabilirsiniz.
Bir yığın gibi, bu yüzden hangi öğenin önce veya son olarak geldiğine dikkat edin.
<?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>
Bir degradeyi, yeşil degrade için opak opaklıkla başka bir görüntünün üzerindeki vurgu için neredeyse saydam bir opaklıkla kaplamayı denediniz mi?