Android ListView Divider

98

Eu tenho este código:

<ListView
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:id="@+id/cashItemsList"
     android:cacheColorHint="#00000000"
     android:divider="@drawable/list_divider"></ListView>

onde @drawable/list_dividerestá:

<shape
 xmlns:android="http://schemas.android.com/apk/res/android"
 android:shape="line">
 <stroke
   android:width="1dp"
   android:color="#8F8F8F"
   android:dashWidth="1dp"
   android:dashGap="1dp" />
</shape>

mas não consigo ver nenhuma divisória.

Oriharel
fonte
1
Não sei por que, mas falta o código. aqui está de novo:
oriharel
<ListView android: layout_width = "wrap_content" android: layout_height = "wrap_content" android: id = "@ + id / cashItemsList" android: cacheColorHint = "# 00000000" android: divider = "@ drawable / list_divider"> </ListView>
oriharel de
1
e o divisor da lista é: <shape xmlns: android = " schemas.android.com/apk/res/android " android: shape = "line"> <stroke android: width = "1dp" android: color = "# 8F8F8F" android: dashWidth = "1dp" android: dashGap = "1dp" /> </shape>
oriharel de
use o bloco de código (o ícone 101010) para inserir códigos, especialmente código XML / HTML / SGML. Eu consertei sua postagem por agora.
Lie Ryan
Talvez o motivo do seu problema esteja no ListAdapter. Apenas tente retornar true de areAllItemsEnabled () do adaptador. Ou assista stackoverflow.com/questions/5587826/…
grine4ka

Respostas:

176

Pessoal, aqui está porque você deve usar 1px em vez de 1dp ou 1dip: se você especificar 1dp ou 1dip, o Android irá reduzir isso. Em um dispositivo de 120 dpi, isso se torna algo como 0,75 px traduzido, que é arredondado para 0. Em alguns dispositivos, isso se traduz em 2-3 pixels e geralmente parece feio ou desleixado

Para divisores, 1px é a altura correta se você quiser um divisor de 1 pixel e é uma das exceções para a regra "tudo deve ser mergulhado". Será 1 pixel em todas as telas. Além disso, 1px geralmente fica melhor em telas hdpi e superiores

Edição "Não é mais 2012": você pode ter que mudar para dp / dip começando em uma certa densidade de tela

Joe Plante
fonte
4
Uau. Salvou a minha vida. Deve fazer parte do guia oficial do Android para usar "dip"
deeJ
Concordo. Eles deveriam pelo menos mencionar essa regra sobre px como um exemplo de por que eles têm.
Joe Plante
6
No ldpi, 1dp = 0,75 pixels, portanto, é arredondado para 0. O divisor não é desenhado, o que pode representar problemas para outros. Isso também se refere às outras declarações neste tópico de reclamação sobre o uso de px completamente. Esta pode ou não ser a solução para o seu problema e cabe a ele declarar se é ou não
Joe Plante
18
1px vai ser incrivelmente pequeno em um dispositivo xxhdpi e, em algum ponto (conforme os dispositivos continuam a obter densidade mais alta), será muito pequeno para ser visto. O Dip evita isso, e outra solução para dispositivos ldpi é usar 1px na pasta values-ldpi e 1dip para densidades mais altas.
eski
2
Quando postei essa resposta, acho que xxhdpi estava acabando de sair. No entanto, sua postagem faz sentido, especialmente com xxxhdpi e possivelmente xxxxhdpi no horizonte
Joe Plante
55

Esta é uma solução alternativa, mas funciona para mim:

Criado res / drawable / divider.xml da seguinte maneira:

<?xml version="1.0" encoding="UTF-8"?>
<shape
  xmlns:android="http://schemas.android.com/apk/res/android">
    <gradient android:startColor="#ffcdcdcd" android:endColor="#ffcdcdcd" android:angle="270.0" />
</shape>

E em styles.xml para listview item, adicionei as seguintes linhas:

    <item name="android:divider">@drawable/divider</item>
    <item name="android:dividerHeight">1px</item>

Parte crucial foi incluir esta configuração de 1px. Claro, drawable usa gradiente (com 1px) e essa não é a solução ideal. Tentei usar o derrame, mas não fiz funcionar. (Parece que você não usa estilos, então apenas adicione o atributo android: dividerHeight = "1px" para ListView.

Mika Vatanen
fonte
14
Ou use 1dp para melhores práticas.
Tristan Warner-Smith
2
Por que você está usando um ângulo de 270? Os divisores da lista são linhas horizontais. 270 é um gradiente vertical.
Christopher Perry,
Não é um bug no Android? Uma forma de linha como divisor não deveria funcionar?
Diederik
8
Os recursos de 1px são a exceção à regra
Joe Plante,
1
@ TristanWarner-Smith isso está incorreto. você precisa usar 1px neste caso. veja a resposta aceita.
mpellegr de
27

Adicione android:dividerHeight="1px"e funcionará:

<ListView
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:id="@+id/cashItemsList"
     android:cacheColorHint="#00000000"
     android:divider="@drawable/list_divider" android:dividerHeight="1px"></ListView>
Martijn de Bruijn
fonte
15

O problema que você está tendo decorre do fato de que você está perdendo o android: dividerHeight, que você precisa, e do fato de que você está tentando especificar uma espessura de linha em seu drawable, o que não pode ser feito com divisores para alguns razão estranha. Essencialmente, para fazer seu exemplo funcionar, você poderia fazer algo como o seguinte:

Crie seu drawable como um retângulo ou uma linha; você simplesmente não pode tentar definir quaisquer dimensões nele, então:

<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="line">
     <stroke android:color="#8F8F8F" android:dashWidth="1dp" android:dashGap="1dp" />
</shape>

OU:

<shape xmlns:android="http://schemas.android.com/apk/res/android"  android:shape="rectangle">
     <solid android:color="#8F8F8F"/>
</shape>

Em seguida, crie um estilo personalizado (apenas uma preferência, mas gosto de poder reutilizar coisas)

<style name="dividedListStyle" parent="@android:style/Widget.ListView">
    <item name="android:cacheColorHint">@android:color/transparent</item>
    <item name="android:divider">@drawable/list_divider</item>
    <item name="android:dividerHeight">1dp</item>
</style>

Por fim, declare sua visualização de lista usando o estilo personalizado:

<ListView
     style="@style/dividedListStyle"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:id="@+id/cashItemsList">
</ListView>

Presumo que você saiba como usar esses trechos, se não me avise. Basicamente, a resposta à sua pergunta é que você não pode definir a espessura do divisor no drawable, você deve deixar a largura indefinida e usar android: dividerHeight para defini-la.

Justin Buser
fonte
8

Do doc:

public void setDivider(Drawable divider) on ListView

/**
 * Sets the drawable that will be drawn between each item in the list. If the drawable does
 * not have an intrinsic height, you should also call {@link #setDividerHeight(int)}
 *
 * @param divider The drawable to use.
 */

Parece que setDividerHeight()deve ser chamado para que o divisor apareça se não tiver altura intrínseca

Plantage
fonte
5

Você @drawable/list_dividedeve ter esta aparência:

<shape
 xmlns:android="http://schemas.android.com/apk/res/android"
 android:shape="line">
 <stroke
   android:height="1dp"
   android:color="#8F8F8F"
   android:dashWidth="1dp"
   android:dashGap="1dp" />
</shape>

Em sua versão, você fornece um android:width="1dp", simplesmente altere-o para um android:height="1dp"e deve funcionar!

cristão
fonte
5
android: a altura não é um atributo válido para o traço e largura significa apenas a largura do traço, não o comprimento. A única razão pela qual sua "solução" funciona é que o Android não reconhece esse valor de altura.
Justin Buser
4

Do doc :

localização de arquivo:

res / drawable / filename.xml

O nome do arquivo é usado como o ID do recurso .

basicamente, você precisará colocar um arquivo chamado list_divider.xmlem res/drawable/para que possa acessá-lo como R.drawable.list_divider; se você pode acessá-lo dessa forma, você pode usar android:divider="@drawable/list_divider"no XML para ListView.

Mentira ryan
fonte
Eu trabalho com eclipse, então se eu não tivesse feito isso, o código não compilaria. então, com o arquivo no lugar, ainda parece que a exibição de lista ignora meu divisor personalizado.
oriharel
2

Algumas pessoas podem estar enfrentando uma linha sólida. Eu contornei isso adicionando android:layerType="software"à vista que faz referência ao drawable.

JeremyDay
fonte
1

Os documentos do Android avisam sobre coisas que estão desaparecendo devido a um erro de arredondamento ... Talvez tente dp em vez de px, e talvez também tente> 1 primeiro para ver se é o problema de arredondamento.

consulte http://developer.android.com/guide/practices/screens_support.html#testing

para a seção "Imagens com altura / largura de 1 pixel"

dnunn0
fonte
Sim. SE você estiver usando 2 ou mais dp / dip, então tudo bem. No entanto, se você quiser apenas aquele divisor de 1 pixel, px é o caminho a seguir. Você também obtém mais espaço na tela com 1 px, além de 1 px geralmente parece melhor
Joe Plante,
1

Eu tive o mesmo problema. No entanto, fazer a visualização de 1px não pareceu funcionar no meu Nexus 7 original. Notei que a densidade da tela era 213, que é menor do que os 240 usados ​​em xhdpi. Então, ele estava pensando que o dispositivo tinha uma densidade mdpi.

Minha solução foi fazer com que a dimenspasta tivesse um dividerHeightparâmetro. Defino-o 2dpna values-mdpipasta, mas 1dpnas values-hdpipastas etc.

RCB
fonte
1

você esqueceu um "r" no final do divisor no seu layout xml do divisor

você chama o layout @ drawable / list_divider, mas seu divisor xml é denominado "list_divide"

KC
fonte
-1

definir android: dividerHeight = "1dp"

<ListView
            android:id="@+id/myphnview"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_below="@drawable/dividerheight"
            android:background="#E9EAEC"
            android:clickable="true"
    android:divider="@color/white"
                android:dividerHeight="1dp"
                android:headerDividersEnabled="true" >
    </ListView>
Nzala
fonte