Разделитель ListView для Android


98

У меня есть такой код:

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

где @drawable/list_dividerнаходится:

<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>

но я не вижу разделителя.


1
Не знаю почему, но код отсутствует. вот он снова:
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

1
а разделитель списка: <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

используйте блок кода (значок 101010) для вставки кодов, особенно кода XML / HTML / SGML. Я исправил ваш пост на данный момент.
Ли Райан,

Возможно, причина вашей проблемы в вашем ListAdapter. Просто попробуйте вернуть true для areAllItemsEnabled () адаптера. Или посмотрите stackoverflow.com/questions/5587826/…
grine4ka

Ответы:


176

Ребята, вот почему вы должны использовать 1px вместо 1dp или 1dip: если вы укажете 1dp или 1dip, Android уменьшит его. На устройстве с разрешением 120 точек на дюйм это переводится примерно как 0,75 пикселя, что округляется до 0. На некоторых устройствах это переводится в 2-3 пикселя и обычно выглядит некрасиво или неаккуратно.

Для разделителей высота 1 пиксель является правильной, если вы хотите разделитель в 1 пиксель, и является одним из исключений из правила «все должно быть наклонено». На всех экранах будет 1 пиксель. Кроме того, 1px обычно лучше смотрится на экранах hdpi и выше.

Правка «Это больше не 2012 год»: возможно, вам придется переключиться на dp / dip, начиная с определенной плотности экрана.


4
Вот это да. Спас мою жизнь. Должен быть частью официального руководства Android по использованию "dip"
deeJ

Я согласен. Им следует хотя бы упомянуть это правило о пикселях как пример того, почему они у них есть.
Джо Планте,

6
В ldpi 1dp = 0,75 пикселя, поэтому округляется до 0. В этом случае разделитель не прорисовывается, что может создать проблемы для других. Это также относится к другим утверждениям в этой ветке, в которых жалуются на использование px в целом. Это может быть или не быть решением его проблемы, и он должен объявить, так ли это
Джо Планте

18
1px будет невероятно маленьким на устройстве xxhdpi, и в какой-то момент (поскольку устройства продолжают получать более высокую плотность) будет слишком маленьким, чтобы его вообще можно было увидеть. Dip позволяет избежать этого, и другое решение для устройств ldpi - использовать 1px в папке values-ldpi и 1dip для более высоких плотностей.
eski

2
Когда я опубликовал этот ответ, я думаю, что xxhdpi как раз выходил. Тем не менее, ваш пост имеет смысл, особенно с xxxhdpi и, возможно, xxxxhdpi на горизонте
Джо Планте

55

Это обходной путь, но он работает для меня:

Создан файл res / drawable / diverr.xml следующим образом:

<?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>

А в styles.xml для элемента listview я добавил следующие строки:

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

Важнейшей частью было включение этой настройки 1px. Конечно, drawable использует градиент (с 1 пикселем), и это не оптимальное решение. Я пробовал использовать инсульт, но не получилось. (Кажется, вы не используете стили, поэтому просто добавьте атрибут android: dividerHeight = "1px" для ListView.


14
Или используйте 1dp для лучшей практики.
Тристан Уорнер-Смит

2
Почему вы используете угол 270? Разделителями списка являются горизонтальные линии. 270 - вертикальный градиент.
Кристофер Перри,

Разве это не ошибка Android? Разве линия не должна работать как разделитель?
Diederik

8
Ресурсы размером 1px являются исключением из правил,
Джо Планте

1
@ TristanWarner-Smith, это неверно. в этом случае вам нужно использовать 1px. см. принятый ответ.
mpellegr

27

Добавьте android:dividerHeight="1px"и все заработает:

<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>

15

Проблема, с которой вы сталкиваетесь, проистекает из того факта, что вам не хватает android: dividerHeight, который вам нужен, и того факта, что вы пытаетесь указать вес линии в своем чертеже, что вы не можете сделать с разделителями для некоторых странная причина. По сути, чтобы ваш пример заработал, вы можете сделать что-то вроде следующего:

Создайте свой объект для рисования как прямоугольник или линию, либо работает, вы просто не можете попытаться установить на нем какие-либо размеры, поэтому либо:

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

ИЛИ:

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

Затем создайте собственный стиль (просто предпочтение, но мне нравится иметь возможность повторно использовать материал)

<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>

Наконец, объявите представление списка, используя пользовательский стиль:

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

Я предполагаю, что вы знаете, как использовать эти фрагменты, если не дайте мне знать. В основном ответ на ваш вопрос заключается в том, что вы не можете установить толщину разделителя в чертеже, вы должны оставить ширину undefined и использовать android: dividerHeight, чтобы установить ее вместо этого.


8

Из документа:

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.
 */

Похоже, он setDividerHeight()должен быть вызван, чтобы разделитель появился, если у него нет собственной высоты.


5

Вы @drawable/list_divideдолжны выглядеть так:

<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>

В своей версии вы указываете android:width="1dp", просто измените его на, android:height="1dp"и он должен работать!


5
android: height не является допустимым атрибутом для обводки, а ширина просто означает ширину обводки, а не ее длину. Единственная причина, по которой ваше «решение» работает, заключается в том, что Android не распознает это значение высоты.
Джастин Базер

4

Из документа :

расположение файла:

рез / вытяжка / filename.xml

Имя файла используется как идентификатор ресурса .

в основном вам нужно поместить файл с именем list_divider.xmlin, res/drawable/чтобы вы могли получить к нему доступ как R.drawable.list_divider; если вы можете получить к нему доступ таким образом, вы можете использовать android:divider="@drawable/list_divider"в XML для ListView.


Я работаю с eclipse, поэтому, если бы я этого не сделал, код бы не компилировался. Итак, с файлом на месте все еще кажется, что представление списка игнорирует мой настраиваемый разделитель.
oriharel

2

Некоторые люди могут видеть сплошную линию. Я обошел это, добавив android:layerType="software"к представлению ссылку на drawable.


1

Документы Android предупреждают о том, что что-то исчезает из-за ошибки округления ... Возможно, попробуйте dp вместо px, и, возможно, сначала попробуйте> 1, чтобы увидеть, является ли это проблемой округления.

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

для раздела «Изображения с высотой / шириной 1 пиксель»


Ага. ЕСЛИ вы используете 2 или более dp / dip, тогда все в порядке. Однако, если вам просто нужен разделитель в 1 пиксель, используйте px. Вы также получаете больше экранной площади с 1 пикселем, плюс 1 пиксель обычно выглядит лучше,
Джо Планте

1

Я была такая же проблема. Однако на моем оригинальном Nexus 7 настройка вида 1px, похоже, не работала. Я заметил, что плотность экрана была 213, что меньше 240, используемой в xhdpi. Значит, он думал, что у устройства плотность mdpi.

Мое решение заключалось в том, чтобы у dimensпапки был dividerHeightпараметр. Я установил его 2dpв values-mdpiпапку, но 1dpв values-hdpiпапки etc.


1

вы забыли букву "r" в конце разделителя в XML-макете разделителя

вы вызываете макет @ drawable / list_divider, но ваш XML-разделитель называется "list_divide"


-1

установить 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>
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.