Android “yükseklik” gölge göstermiyor


273

Bir ListView var ve her liste öğesinin altında bir gölge göstermek istiyorum. Görünümde bir gölge oluşturmak istediğim bir Z ayarlamak için Android Lollipop'un yeni yükseklik özelliğini kullanıyorum ve bunu zaten ActionBar (teknik olarak Lollipop'ta bir Araç Çubuğu) ile etkili bir şekilde yapıyorum. Lollipop'un yüksekliğini kullanıyorum, ancak nedense liste öğelerinin altında bir gölge göstermiyor. Her bir liste öğesinin düzeni şu şekilde ayarlanır:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    style="@style/block"
    android:gravity="center"
    android:layout_gravity="center"
    android:background="@color/lightgray"
    >

    <RelativeLayout
        android:layout_width="300dp"
        android:layout_height="300dp"
        android:layout_marginLeft="40dp"
        android:layout_marginRight="40dp"
        android:layout_marginTop="20dp"
        android:layout_marginBottom="20dp"
        android:elevation="30dp"
        >

        <ImageView
            android:id="@+id/documentImageView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:scaleType="centerCrop" />

        <LinearLayout
            android:orientation="vertical"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@color/alphared"
            android:layout_alignParentBottom="true" >

            <appuccino.simplyscan.Extra.CustomTextView
                android:id="@+id/documentName"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:textColor="@color/white"
                app:typeface="light"
                android:paddingLeft="16dp"
                android:paddingTop="8dp"
                android:paddingBottom="4dp"
                android:singleLine="true"
                android:text="New Document"
                android:textSize="27sp"/>

            <appuccino.simplyscan.Extra.CustomTextView
                android:id="@+id/documentPageCount"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:textColor="@color/white"
                app:typeface="italic"
                android:paddingLeft="16dp"
                android:layout_marginBottom="16dp"
                android:text="1 page"
                android:textSize="20sp"/>

        </LinearLayout>

    </RelativeLayout>

</RelativeLayout>

Ancak, gölge olmadan liste öğesini şu şekilde gösterir: resim açıklamasını buraya girin

Ben de boşuna aşağıdaki denedim:

  1. Yüksekliği üst düzen yerine ImageView ve TextViews'e ayarlayın.
  2. ImageView öğesine bir arka plan uyguladı.
  3. Yükseklik yerine TranslationZ kullanılır.

Düzeninizi (özel görünümler olmadan) denedim ve telefonumdaki gölgeyi gösterdim, sorunu yeniden üreten minimal bir projeyi paylaşabilir misiniz?
rnrneverdies


Yanıtlar:


384

Bir süredir Lollipop'ta gölgelerle oynuyorum ve bulduğum şey bu:

  1. Bir ebeveynin ViewGroupsınırları bir nedenden ötürü çocuklarının gölgesini kesiyor gibi görünüyor ; ve
  2. ile ayarlanan gölgeler , kenar boşluğu boyunca uzanan sınırlar android:elevationtarafından Viewdeğil, sınırlarıyla kesilir;
  3. gölgeyi göstermek için bir alt görünüm elde etmenin doğru yolu, üst öğeye dolgu koymak android:clipToPadding="false"ve bu üst öğeye ayarlamaktır .

İşte bildiklerime dayanarak size önerim:

  1. En üst seviyenizi RelativeLayout, gölge göstermek istediğiniz göreceli düzende belirlediğiniz kenar boşluklarına eşit olacak şekilde ayarlayın;
  2. android:clipToPadding="false"aynı şekilde koymak RelativeLayout;
  3. RelativeLayoutYüksekliği ayarlanmış olan kenar boşluğunu kaldırın ;
  4. [EDIT] ayrıca alt düzeye yükseltilmesi gereken saydam olmayan bir arka plan rengi ayarlamanız gerekebilir.

Günün sonunda, üst düzey göreceli düzeniniz şöyle görünmelidir:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    style="@style/block"
    android:gravity="center"
    android:layout_gravity="center"
    android:background="@color/lightgray"
    android:paddingLeft="40dp"
    android:paddingRight="40dp"
    android:paddingTop="20dp"
    android:paddingBottom="20dp"
    android:clipToPadding="false"
    >

İç göreli düzen şu şekilde görünmelidir:

<RelativeLayout
    android:layout_width="300dp"
    android:layout_height="300dp"
    android:background="[some non-transparent color]"
    android:elevation="30dp"
    >

8
Bunun için teşekkürler! Ayrıca üst bağıl mizanpaja uygulandığında android: clipChildren = "false" buldum.
blaffie

1
@Blaffie'ye yardımcı olmaktan memnuniyet duyarız!
Justin Pollard

214
Google bu kadar kalitesiz bir kod üretecek kadar can sıkıcı. Bu çerçeve hatalarını yıllarca hesaba katmamız gerekecek.
miguel

8
Google yalnızca (ne yazık ki) der: " Gölgeler yükseltilmiş görünümün üst öğesi tarafından çizilir ve bu nedenle üst öğe tarafından varsayılan olarak kırpılan standart görünüm kırpma işlemine tabidir. "
John

5
Benim durumumda şeffaf renkti. Tamam, şeffaf şeyler gölgelenmiyor ... haha
Ferran Maylinch

286

Arka planı olmayan bir görünümünüz varsa, bu çizgi size yardımcı olacaktır

android:outlineProvider="bounds"

Varsayılan olarak gölge görünümün arka planına göre belirlenir, bu nedenle arka plan yoksa gölge de olmaz.


11
Ne tuhaf bir şey ki, Preview yükseklik gösterdi ama gerçek cihaz göstermedi. Teşekkürler, bu sorunu düzeltti.
Ioane Sharvadze

API seviyesi 21 ve üstü için çalışır
Pantelis Ieronimakis

10
Bu tür benim için çalıştı, ancak bir metin görünümüne uygulandığında yanlara çapraz bir kenarlık verdi. Arka planı bir renge ayarlamak (ebeveynlerin arka plan rengiyle aynı) daha iyi sonuç verdi.
Gober

4
Bu, arka planınız özelse ve hiç yoksa da geçerlidir <solid>.
David Lord

Bu tersten kullanılabilir. Yüksekliği olmayan şeffaf olmayan bir arka plan istediğinizde ve gölge istemiyorsanız. Basitçe olarak ayarlayın none. Teşekkürler!
Odys

101

Görünüşe göre, bir Görünüm üzerinde bir yükseklik ayarlayamaz ve görünmesini sağlayamazsınız. Ayrıca bir arka plan belirtmeniz gerekir.

LinearLayout'uma eklenen aşağıdaki satırlar sonunda bir gölge gösterdi:

android:background="@android:color/white"
android:elevation="10dp"

Bu beklenmedikti. ImageView'i src ile ayarladım ve çözüm arıyordum. Teşekkür ederim.
Andrew Grow

47

bilmeniz gereken başka bir şey, manifestte bu çizgiye sahipseniz gölgeler gösterilmez:

android: hardwareAccelerated = "false"

Tüm önerilen şeyleri denedim ama sadece çizgi kaldırıldığında benim için çalıştı, çizgi vardı nedeni benim app bitmap görüntüleri bir dizi çalışır ve onlar app çökmesine neden oldu çünkü.


1
Bu bayrağın olması gerekiyorsa, bu sorunu çözmez.
Clive Jefferies

teşekkür ederim!!
AppBar'ı

1
Tüm olası çözümleri denedim, ama benim için hiçbir işe yaramadı. Bu çözümler işe yaradı. Teşekkürler. Ayrıca android:clipToPadding="false"bu çözüm ile ihtiyaç .
Chirag Savsani

29

Arka planı olmayan bir görünümünüz varsa, bu çizgi size yardımcı olacaktır

android:outlineProvider="bounds"

Arka plana sahip bir görünümünüz varsa, bu çizgi size yardımcı olacaktır

android:outlineProvider="paddedBounds"

6
Bu çözüm benim için çalışan tek çözüm. Teşekkür ederim
Oleh Liskovych

4
Bu, görünümler arka planınızda bir yarıçapınız olmadığı sürece çalışır, bu durumda gölgenin dikdörtgen olarak gösterilmesi gerekir, ancak paddedBounds arka plana sahip bir görünüm için çalışır.
Trevor Hart

android:outlineProvider="paddedBounds"bu hat benim için çalıştı. Seçiciyi Çekilebilir olarak ayarladım.
Chirag Savsani

1
Bunu kullandığımda, gölge dışarıdan ziyade tamamen görünümün içine çekiliyor, bu benim istediğim şey değil.
androidguy


12

Ugh, bunu anlamaya çalışmak için bir saat harcadım. Benim durumumda bir arka plan seti vardı, ancak bir renk olarak ayarlandı. Bu yeterli değil, görünümün arka planının çekilebilir olarak ayarlanmış olması gerekir.

Örneğin bunun gölgesi olmayacak:

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="165dp"
    android:background="@color/ight_grey"
    android:elevation="20dp"
    android:orientation="vertical"
    />

ama bu olacak

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="165dp"
    android:background="@drawable/selector_grey"
    android:elevation="20dp"
    android:orientation="vertical"
    />

EDIT: Arka plan olarak bir seçici kullanırsanız, köşe ayarını yapmadıysanız, gölgenin Önizleme penceresinde görünmeyeceğini, ancak cihazda görüneceğini de keşfettiniz.

Örneğin, önizlemede gölge yoktur:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape android:shape="rectangle">
            <solid android:color="@color/white" />
            <stroke
                android:width="1dp"
                android:color="@color/grey"/>
        </shape>
    </item>
</selector>

ancak bu:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape android:shape="rectangle">
            <solid android:color="@color/white" />
            <corners android:radius="1dp" />
            <stroke
                android:width="1dp"
                android:color="@color/grey"/>
        </shape>
    </item>
</selector>

1
İlk noktanızın tam tersi bir RecyclerView öğesinde benim için doğruydu ... 5 yıllık profesyonel Android geliştirmesinden sonra bu API'larla savaşmak zorunda kaldığım davaları hala nasıl bulduğum şaşırtıcı :(
aProperFox

7

Arka plan rengi eklemek bana yardımcı oldu.

<CalendarView
    android:layout_width="match_parent"
    android:id="@+id/calendarView"
    android:layout_alignParentTop="true"
    android:layout_alignParentStart="true"
    android:layout_height="wrap_content"
    android:elevation="5dp"

    android:background="@color/windowBackground"

    />

4

Bazen işe background="@color/***"ya background="#ff33**"da çalışmayarak, background_colorçekilebilir ile değiştiriyorum , sonra çalışıyor


4

Hala yükseklik göstermiyorsa deneyin

    android:hardwareAccelerated="true" 

bu kesinlikle size yardımcı olacaktır.


Bu benim için düzeltildi. En azından benim durumumda TRUE'nun varsayılan ayar olduğunu, ancak görünüşe göre olmadığını varsaymıştım.
Matt Robertson

3

Saydam arka plana sahip olmak istiyor ve android:outlineProvider="bounds"sizin için çalışmıyorsa, özel ViewOutlineProvider oluşturabilirsiniz:

class TransparentOutlineProvider extends ViewOutlineProvider {

    @Override
    public void getOutline(View view, Outline outline) {
        ViewOutlineProvider.BACKGROUND.getOutline(view, outline);
        Drawable background = view.getBackground();
        float outlineAlpha = background == null ? 0f : background.getAlpha()/255f;
        outline.setAlpha(outlineAlpha);
    }
}

Ve bu sağlayıcıyı şeffaf görünümünüze ayarlayın:

transparentView.setOutlineProvider(new TransparentOutlineProvider());

Kaynaklar: https://code.google.com/p/android/issues/detail?id=78248#c13

[EDIT] Drawable.getAlpha () belgeleri, Drawable'ın alfa nasıl tehdit ettiğine özgü olduğunu söylüyor. Her zaman 255 döndürmesi mümkündür. Bu durumda alfa'yı manuel olarak sağlayabilirsiniz:

class TransparentOutlineProvider extends ViewOutlineProvider {

    private float mAlpha;

    public TransparentOutlineProvider(float alpha) {
        mAlpha = alpha;
    }

    @Override
    public void getOutline(View view, Outline outline) {
        ViewOutlineProvider.BACKGROUND.getOutline(view, outline);
        outline.setAlpha(mAlpha);
    }
}

Görünüm arka planınız varsayılan renk # DDFF0000 olan alfa DDx0 / FFx0 == 0,86 olan bir StateListDrawable ise

transparentView.setOutlineProvider(new TransparentOutlineProvider(0.86f));

2

benim için çalıştı düzeni için biraz arka plan rengi vermek:

    android:background="@color/catskill_white"
    android:layout_height="?attr/actionBarSize"
    android:elevation="@dimen/dimen_5dp"

1

clipChildren="false"Üst düzen ayarında biraz şans vardı .


1

Üzerinde çalışmak için biraz zaman harcadım ve sonunda arka plan karanlık olduğunda gölgenin görünmediğini fark ettim


1

Kabul edilen cevaba ek olarak, telefondaki Bluelight filtre özelliği AÇIK ise hangi yükselmenin beklendiği gibi çalışmayabileceği için bir neden daha vardır.

Cihazımda yükseklik tamamen bozuk ve dayanılmaz göründüğünde bu sorunla karşı karşıya kaldım. Ancak önizlemede yükseklik iyiydi. Telefonda Bluelight filtresini kapatmak sorunu çözdü.

Ayarladıktan sonra bile

android:outlineProvider="bounds"

Yükseklik düzgün çalışmıyor, ardından telefonun renk ayarlarıyla tamir etmeye çalışabilirsiniz.


0

Sorununuzun, yükseltme öğesini üst öğesini dolduran göreceli bir düzene uyguladığınızdan kaynaklandığına inanıyorum. Ebeveyninin tüm çocuk görünümleri kendi çizim tuvalinde kliplenir (ve çocuğun gölgesini işleyen görünümdür). RelativeLayoutGörünüm xml'inizde (kök etiket) en üste bir yükselme özelliği uygulayarak bunu düzeltebilirsiniz .


0

Benim durumumda yazı tipleri problemdi.

1) olmadan fontFamilyBen android:backgroundbir değere ayarlamak gerekiyordu.

<TextView
    android:layout_width="match_parent"
    android:layout_height="44dp"
    android:background="@android:color/white"
    android:elevation="3dp"
    android:gravity="center"
    android:text="@string/fr_etalons_your_tickets"
    android:textAllCaps="true"
    android:textColor="@color/blue_4" />

2) ile ayar fontFamilyeklemek zorunda kaldım android:outlineProvider="bounds":

<TextView
    android:fontFamily="@font/gilroy_bold"
    android:layout_width="match_parent"
    android:layout_height="44dp"
    android:background="@android:color/white"
    android:elevation="3dp"
    android:gravity="center"
    android:outlineProvider="bounds"
    android:text="@string/fr_etalons_your_tickets"
    android:textAllCaps="true"
    android:textColor="@color/blue_4" />

0

Benim durumumda, bunun nedeni oluşturma katmanı türünü "Yazılım" olarak ayarlayan özel bir üst bileşendi:

setLayerType(View.LAYER_TYPE_SOFTWARE, null);

Bu çizgiyi kaldırmak hile yaptı. Veya elbette bunun neden ilk etapta olduğunu değerlendirmeniz gerekiyor. Benim durumumda, projem için mevcut minimum SDK'nın çok gerisinde olan Honeycomb'u desteklemekti.


0

Ayrıca o görünümde alfa değiştirip değiştirmediğinizi kontrol edin. Bazı görünümlerde, alfa ile yükseklik değiştirdiğimde sorunu araştırıyorum. Alfa değiştiğinde ve 1f'ye döndüğünde yüksekliği kaybederler.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.