SORU
7 Aralık 2010, Salı


Multi-degrade şekilleri

Aşağıdaki resim gibi bir şekil oluşturmak istiyorum

alt text

Renk renk 1 üst yarısı degrade renk 4 renk 3 geçişlerini 2, ama bir alt var yarısı dikkat edin. Tek bir degrade ile bir şekil oluşturmak için nasıl biliyorum, ama ikiye bölünmüş bir şekil ve 12 farklı eğimler şekil yapmak için nasıl emin değilim.

Herhangi bir fikir?

CEVAP
7 Aralık 2010, Salı


XML olarak bunu yapabileceğini sanmıyorum (en azından Android değil), ama çok yardımcı olacak gibi görünüyor bu iyi bir çözüm here ilan 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);

Temelde, int dizi birden çok renk vermiyor seçmenizi sağlar, ve aşağıdaki şamandıra dizi bu durur yerleştirilmiş durumda (1-0) tanımlar. Sonra da belirtildiği gibi, sadece standart bir Drawable olarak kullanabilirsiniz.

Edit: Burada senin senaryoda bu kullanabilirsiniz. Hadi bir Düğme XML gibi tanımlanmış olduğunu varsayalım:

<Button
    android:id="@ id/thebutton"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Press Me!"
    />

Sonra onCreate böyle bir şey koymak istiyorum() yöntemi:

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.setBackgroundDrawable((Drawable)p);

Ben şu anda bu, bu kafamdan kod, ama temelde sadece değiştirmek, ya da size ihtiyacınız olan renk durakları eklemek testi. Temelde, benim örnek, olur başlangıç ile bir açık yeşil, solmaya beyaz biraz önce merkezi (ver yavaş yavaş yerine sert bir geçiş), fade beyaz orta yeşil arasında 45% 55'i, sonra fade orta yeşil koyu yeşil 55'e sonunda. Bu tam da senin şekil gibi görünmeyebilir (işteyim, bu renkleri test ettim), ama bu örneği çoğaltmak için değiştirebilirsiniz.

Edit: Ayrıca, x 0, y0, x1, y1 0, 0, 0, theButton.getHeight() başvurduğu degrade koordinatları. Yani temelde, başlar x = 0 (Sol), y = 0 (üst), ve uzanır x = 0 (we're isteyen bir dikey degrade, yani soldan sağa doğru açı gerekli), y = yükseklik düğmesi. Degrade düğmesini alt alt üst 90 derecelik bir açıyla gider.

Edit: çalışan bir tane daha fikrim var, Tamam haha. Şimdi XML çalışır, ama Java şekiller için mümkün değil. Biraz karmaşık olduğunu ve tek bir şekil içine kolaylaştırmak için bir yolu yok sanırım, ama bu şimdilik bende ne varsa:

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, böylece temelde ettim oluşturulan bir şekli degrade XML için yatay yeşil degrade, set bir 0 derecelik bir açı ile, üst bölgenin sol yeşil renk, yeşil renk. İleri, yarı şeffaf gri ile şekil bir dikdörtgen yaptım. Bu liste katmanı XML, bu ek dosya obviating içine inlined olabilir eminim, ama nasıl emin değilim. Ama Tamam, hacky bölümü türünü layer_list XML dosyası geliyor. Alt tabaka olarak yeşil degrade koydum, ikinci kat, 50dp tarafından üstten uzaklığı yarım kaplamayı yerleştirin. Belli ki bu sayı her zaman ne olursa olsun görünümünüzü boyutu olsa da, yarı sabit bir 50dp yok olmak istersin. Yüzdeler, gerçi kullanabilirsiniz sanmıyorum. Oradan, sadece test.xml benim düzen içine bir TextView, benim arka plan olarak layer_list.xml dosyayı kullanarak eklenir. 100dp (kaplamanın uzaklık iki katı büyüklüğünde) yüksekliği, aşağıdaki sonuç kümesi:

alt text

Tada!

Bir daha DüzenleSadece öğeleri drawable olarak katman listesine şekilleri, 3 ayrı XML dosyaları artık ihtiyacınız yok! anlamı gömebilirsiniz fark ettim Aynı sonucu gibi onları birleştirerek 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>

Sizin gibi pek çok ürün bu şekilde katman! Oynamak için deneyin ve eğer Java ile daha verimli bir sonuç elde edebilirim diye.

Bu son düzenleme olduğunu düşünüyorumTamam, bu yüzden kesinlikle aşağıdaki gibi Java ile: konumlandırma çözebilirsiniz

    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 o TextView ölçmek çizilmiş edildikten sonra kadar olamaz başka bir can sıkıcı sorun yol açar. Bunu henüz tam olarak emin değilim...ama el ile topİnset için bir sayı ekleme işini yapar.

Bir daha düzenlemek yalan söyledim

Tamam, el ile bu katmanı drawable kabın yüksekliği maç için güncelleme nasıl öğrendi, tam açıklama here bulunabilir. Bu kodu onCreate gitmeli() yöntemi:

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 bitti! Vay! :)

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Awesomesauce Network

    Awesomesauce

    4 EKİM 2012
  • Julia Graf

    Julia Graf

    6 Mayıs 2006
  • REK Roth Productions

    REK Roth Pro

    8 Ocak 2011