Сайт разработчика Александра Климова

/* Моя кошка замечательно разбирается в программировании. Стоит мне объяснить проблему ей - и все становится ясно. */
John Robbins, Debugging Applications, Microsoft Press, 2000

Стильный ListView

Попробуем сделать ListView красивым. Сначала создадим стандартную заготовку на основе ListActivity. Разметка будет стандартная:


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <ListView
        android:id="@android:id/listView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >
    </ListView>

</LinearLayout>

Теперь создадим массив кошачьих имён и через адаптер добавим имена в список:


package ru.alexanderklimov.listview;

import ...

public class MainActivity extends ListActivity {

	private static final String[] catNames = { "Васька", "Барсик", "Мурзик",
			"Рыжик", "Дорофей", "Маркиз" };

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		setContentView(R.layout.activity_main);

		ListView listView = getListView();
		listView.setAdapter(new ArrayAdapter<String>(this,
				android.R.layout.simple_list_item_1, catNames));
	}
}

Получим стандартное приложение со списком:

ListActivity

Займёмся стилизацией списка. В файле res/values/styles.xml добавим пару стилей для списка:


<style name="CustomListView" parent="@android:style/Widget.ListView">
    <item name="android:background">#2F3F66</item>
    <item name="android:fastScrollEnabled">true</item>
</style>

Теперь нужно присоединить стиль к ListView через атрибут style="@style/CustomListView" и посмотреть, что у нас получилось:

Стильный ListActivity

Мы поменяли фон для списка и добавили возможность быстрой прокрутки.

Однако, продолжим.

Создадим отдельную тему для активности (или всего приложения):


<style name="CustomTheme" parent="@android:style/Theme.Holo">
    <item name="android:listViewStyle">@style/CustomListView</item>
    <item name="android:textViewStyle">@style/CustomTextView</item>
</style>

<style name="CustomListView" parent="@android:style/Widget.ListView">
    <item name="android:background">#2F3F66</item>
    <item name="android:fastScrollEnabled">true</item>
</style>

<style name="CustomTextView" parent="@android:style/Widget.TextView">
    <item name="android:typeface">monospace</item>
    <item name="android:shadowColor">#000000</item>
    <item name="android:shadowRadius">2.</item>
    <item name="android:shadowDx">4</item>
    <item name="android:shadowDy">4</item>
</style>

Кроме новой темы мы добавили ещё один стиль для TextView, который отвечает за отдельный элемент списка. Теперь текст будет выглядеть объёмным за счёт тени. Прописываем атрибут android:theme="@style/CustomTheme" в манифесте для активности или для всего приложения (application). Смотрим на результат:

Стильный ListActivity

Также можете использовать градиент, который можно применить как ко всему ListView, так и отдельному элементу списка.

Создадим файл res/drawable/gradient.xml:


<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle" >

    <gradient
        android:angle="270"
        android:endColor="#111191"
        android:startColor="#EFEFEF"
        android:type="linear" />

</shape>

При желании можете также использовать атрибут android:middleColor.

Теперь нужно прописать созданный градиент в атрибуте android:background либо у ListView, либо в отдельной разметке для элемента списка. Разница видна невооружённым взглядом:

Стильный ListActivity Стильный ListActivity

Если через XML мы можем задать только три параметра для градиента, то программно через GradientDrawable можно задать больше опорных точек.

Нажатый элемент списка

В предыдущих примерах мы научились менять фон у списка, но при этом список утратил возможность выделять нажатый элемент. Это серьёзное упущение для профессиональных программ. Исправить ситуацию просто. Вы должны подготовить два файла - один для стандартного вида элемента списка, а второй для нажатого элемента.

drawable/row_default.xml


<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle" >

    <gradient
        android:angle="270"
        android:endColor="#989898"
        android:startColor="#EFEFEF"
        android:type="linear" />

</shape>

drawable/row_pressed.xml


<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle" >

    <gradient
        android:angle="270"
        android:endColor="#0661E5"
        android:startColor="#0B8CF2"
        android:type="linear" />

</shape>

Теперь нужно создать ещё один файл, в котором будут содержаться сведения о разных состояниях элемента списка:

drawable/row_background.xml


<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:drawable="@drawable/row_pressed" android:state_pressed="true"/>
    <item android:drawable="@drawable/row_default"/>

</selector>

Данный файл теперь можно присвоить атрибуту android:background у отдельной разметки для элемента списка и список будет реагировать на нажатия пользователя.

Реклама