A — это представление для отображения прокручиваемого списка элементов, который может поступать из адаптера списка или адаптера массива. Выбор элемента в ListView вызывает событие, для которого вы можете написать прослушиватель.

Если действие содержит только одно представление, то вы можете расширить ListActivity вместо

как ваш класс активности. Использование ListActivity удобно, так как оно имеет ряд полезных функций.

В этой главе показано, как можно использовать ListView и ListActivity, а также создавать собственный ListAdapter и стилизовать ListView в трех примерах приложений.

Просмотр списка Android

Технически android.widget.ListView, шаблон для создания ListView, является потомком класса View. Вы можете использовать его так же, как и другие представления. Что делает ListView немного сложным в использовании, так это тот факт, что вам нужно получить для него источник данных в виде ListAdapter. ListAdapter также предоставляет макет для каждого элемента в ListView, поэтому ListAdapter действительно играет очень важную роль в жизни ListView.

Виджет android.widget. Интерфейс ListAdapter является подинтерфейсом android.widget. Адаптер. Близкие родственники этого интерфейса показаны на рис. 1.1.

Создание ListAdapter описано в следующем разделе «Создание ListAdapter». Когда у вас есть ListAdapter, вы можете передать его методу setAdapter ListView:

listView.setAdapter(listAdapter);

Вы также можете написать прослушиватель, реализующий AdapterView.OnItemClickListener, и передать его методу setOnItemClickListener в ListView. Слушатель будет уведомляться каждый раз, когда выбирается элемент списка, и вы можете написать код для его обработки, например.

listView.setOnItemClickListener(new
        AdapterView.OnItemClickListener() { 
    @Override 
    public void onItemClick(AdapterView<?> parent, final View view, 
            int position, long id) { 
        // handle item
    });

Создание адаптера списка

Как упоминалось в предыдущем разделе, самая сложная часть использования a — это создание для него источника данных. Вам нужен ListAdapter, и, как видно на рис. 1.1, у вас есть как минимум две реализации ListAdapter, которые вы можете использовать.

Одной из конкретных реализаций ListAdapter является класс ArrayAdapter. ArrayAdapter поддерживается массивом объектов. Строка, возвращаемая методом toString каждого объекта, используется для заполнения каждого элемента в ListView.

Класс ArrayAdapter предлагает несколько конструкторов. Все они требуют, чтобы вы передали a и идентификатор ресурса, указывающий на макет, содержащий файл . Это связано с тем, что каждый элемент в ListView является TextView. Это некоторые из конструкторов в классе ArrayAdapter.

public ArrayAdapter(android.content.Context context, int resourceId) 
public ArrayAdapter(android.content.Context context, int resourceId, 
        T[] objects)

Если вы не передадите массив объектов в конструктор, вам придется передать его позже. Что касается идентификатора ресурса, Android предоставляет несколько предопределенных макетов для ListAdapter. Идентификаторы этих макетов можно найти в классе android.R.layout. Например, вы можете создать ArrayAdapter, используя этот фрагмент кода в своей деятельности.

ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, objects);

Использование android.R.layout.simple_list_item_1 создаст ListView с простейшим макетом, в котором текст для каждого элемента напечатан черным цветом. Кроме того, вы можете использовать android.R.layout.simple_expandable_list_item_1. Однако вы, вероятно, захотите создать свой собственный макет и вместо этого передать его конструктору. Таким образом, у вас будет больше контроля над внешним видом вашего ListView.

Большую часть времени вы можете использовать массив строк в качестве источника данных для вашего ListView. Вы можете создать массив строк программно или декларативно. Сделать это программно просто, и вам не нужно иметь дело с внешним ресурсом:

String[] objects = { "item1", "item2","item-n" };

Недостатком этого подхода является то, что обновление массива потребует перекомпиляции класса. С другой стороны, декларативное создание строкового массива дает вам больше гибкости, поскольку вы можете легко редактировать элементы.

Чтобы создать массив строк декларативно, начните с создания элемента массива строк в файле strings.xml в разделе . Например, ниже приведен массив строк с именами игроков.

<string-array name="players"> 
    <item>Player 1</item> 
    <item>Player 2</item> 
    <item>Player 3</item> 
    <item>Player 4</item> 
</string-array>

Когда вы сохраните файл strings.xml, Android Studio обновит созданный вами класс и добавит статический окончательный класс с именем array, если он не существует, а также добавит идентификатор ресурса для string- элемент массива в класс массива. В результате теперь у вас есть этот идентификатор ресурса для доступа к массиву строк из вашего кода:

R.array.players

Чтобы преобразовать пользовательский массив строк в массив строк Java, используйте этот код.

String[] values = getResources().getStringArray(R.array.players);

Затем вы можете использовать этот массив строк для создания ArrayAdapter.

Использование ListView

Приложение ListViewDemo1 показывает, как использовать объект, поддерживаемый ArrayAdapter. Массив, который предоставляет значения для ArrayAdapter, представляет собой массив строк, определенный в файле strings.xml. В листинге 1.1 показан файл strings.xml.

Листинг 1.1. Файл res/values/strings.xml для ListViewDemo1

<?xml version="1.0" encoding="utf-8"?> 
<resources>
<string name="app_name">ListViewDemo1</string> 
    <string name="action_settings">Settings</string> 
    
    <string-array name="players"> 
        <item>Player 1</item> 
        <item>Player 2</item> 
        <item>Player 3</item> 
        <item>Player 4</item> 
        <item>Player 5</item> 
    </string-array> 
</resources>

Макет для ArrayAdapter определен в файле list_item.xml, представленном в листинге 1.2. Он расположен под и содержит элемент. Этот макет будет использоваться в качестве макета для каждого элемента в ListView.

Листинг 1.2. Файл list_item.xml

<?xml version="1.0" encoding="utf-8"?> 
<TextView xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/list_item" 
        android:layout_width="fill_parent" 
        android:layout_height="fill_parent" 
        android:padding="7dip" 
        android:textSize="16sp" 
        android:textColor="@android:color/holo_green_dark" 
        android:textStyle="bold" > 
</TextView>

Приложение состоит только из одного действия, MainActivity. Файл макета ( activity_main.xml) для действия приведен в листинге 1.3, а класс MainActivity — в листинге 1.4.

Листинг 1.3. Файл activity_main.xml для ListViewDemo1

<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:orientation="vertical" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent"> 
    <ListView 
        android:id="@+id/listView1" 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" /> 
</LinearLayout>

Листинг 1.4. Класс MainActivity для ListViewDemo1

package com.example.listviewdemo1; 
import android.app.Activity; 
import android.app.AlertDialog; 
import android.os.Bundle; 
import android.util.Log; 
import android.view.Menu; 
import android.view.View; 
import android.widget.AdapterView; 
import android.widget.ArrayAdapter; 
import android.widget.ListView; 

public class MainActivity extends Activity {
@Override 
    protected void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState); 
        setContentView(R.layout.activity_main); 
        String[] values = getResources().getStringArray( 
                R.array.players); 

        ArrayAdapter<String> adapter = new ArrayAdapter<String>( 
                this, R.layout.list_item, values); 

        ListView listView = (ListView) findViewById(R.id.listView1); 
        listView.setAdapter(adapter); 
        listView.setOnItemClickListener(new 
                AdapterView.OnItemClickListener() { 
            @Override 
            public void onItemClick(AdapterView<?> parent, 
                    final View view, int position, long id) { 
                String item = (String) 
                        parent.getItemAtPosition(position); 
                AlertDialog.Builder builder = new 
                        AlertDialog.Builder(MainActivity.this); 
                builder.setMessage("Selected item: " 
                        + item).setTitle("ListView"); 
                builder.create().show(); 
                Log.d("ListView", "Selected item : " + item); 
            } 
        }); 
    } 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
        getMenuInflater().inflate(R.menu.menu_main, menu); 
        return true; 
    } 
}

На рис. 1.2 показано приложение.

Расширение ListActivity и написание пользовательского адаптера

Если ваша активность будет иметь только один компонент, представляющий собой ListView, вам следует рассмотреть возможность расширения класса ListActivity вместо Activity. С ListActivity вам не нужен файл макета для вашей активности. ListActivity уже содержит ListView, и вам не нужно присоединять к нему прослушиватель. Кроме того, класс ListActivity уже определяет метод setListAdapter, поэтому вам просто нужно вызвать его в своем методе. Кроме того, вместо того, чтобы создавать AdapterView.OnItemClickListener, вам просто нужно переопределить метод onListItemClick в ListActivity, который будет вызываться при выборе элемента в списке.

Приложение ListViewDemo2 показывает, как использовать ListActivity. Приложение также демонстрирует, как создать собственный ListAdapter, расширив класс ArrayAdapter и создав файл макета для пользовательского ListAdapter.

Файл макета для пользовательского ListAdapter в ListViewDemo2 представлен в листинге 1.5. Он называется файлом pretty_adapter.xml и находится в папке .

Листинг 1.5. Файл pretty_adapter.xml

<?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">
    
    <ImageView 
	  android:id="@+id/icon" 
	  android:layout_width="36dp" 
	  android:layout_height="fill_parent"/> 
    <TextView 
	 android:id="@+id/label" 
        android:layout_width="fill_parent" 
        android:layout_height="fill_parent" 
        android:gravity="center_vertical" 
        android:padding="12dp" 
        android:textSize="18sp" 
        android:textColor="@android:color/holo_blue_bright"/> 
</LinearLayout>

В листинге 1.6 показан пользовательский класс адаптера с именем PrettyAdapter.

Листинг 1.6. Класс PrettyAdapter

package com.example.listviewdemo2; 
import android.content.Context; 
import android.graphics.drawable.Drawable; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.ArrayAdapter; 
import android.widget.ImageView; 
import android.widget.TextView;
public class PrettyAdapter extends ArrayAdapter<String> { 
    private LayoutInflater inflater;
    private String[] items; 
    private Drawable icon; 
    private int viewResourceId; 

    public PrettyAdapter(Context context, 
            int viewResourceId, String[] items, Drawable icon) { 
        super(context, viewResourceId, items); 
        inflater = (LayoutInflater) context 
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
        this.items = items; 
        this.icon = icon; 
        this.viewResourceId = viewResourceId; 
    } 

    @Override 
    public int getCount() { 
        return items.length; 
    } 

    @Override 
    public String getItem(int position) { 
        return items[position]; 
    } 

    @Override 
    public long getItemId(int position) { 
        return 0; 
    } 

    @Override 
    public View getView(int position, View convertView, 
            ViewGroup parent) { 
        convertView = inflater.inflate(viewResourceId, null); 

        ImageView imageView = (ImageView) 
                convertView.findViewById(R.id.icon); 
        imageView.setImageDrawable(icon); 

        TextView textView = (TextView) 
                convertView.findViewById(R.id.label); 
        textView.setText(items[position]); 
        return convertView; 
    } 
}

Пользовательский адаптер должен переопределить несколько методов, в частности метод, который должен возвращать представление, которое будет использоваться для каждого элемента в . В этом примере представление содержит ImageView и файл . Текст для TextView берется из массива, переданного экземпляру PrettyAdapter.

Последняя часть приложения — это класс MainActivity в листинге 1.7. Он расширяет ListActivity и является единственным действием в приложении.

Листинг 1.7. Класс MainActivity для ListViewDemo2

package com.example.listviewdemo2; 
import android.app.ListActivity;
import android.content.Context; 
import android.content.res.Resources; 
import android.graphics.drawable.Drawable; 
import android.os.Bundle; 
import android.util.Log; 
import android.view.View; 
import android.widget.ListView; 

public class MainActivity extends ListActivity { 
    
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState); 
        // Since we're extending ListActivity, we do 
        // not need to call setContentView(); 
        
        Context context = getApplicationContext(); 
        Resources resources = context.getResources(); 

        String[] items = resources.getStringArray( 
                R.array.players); 
        Drawable drawable = resources.getDrawable( 
                R.drawable.pretty); 
        
        setListAdapter(new PrettyAdapter(context, 
                R.layout.pretty_adapter, items, drawable)); 
    } 
    
    @Override 
    public void onListItemClick(ListView listView, 
            View view, int position, long id) { 
        Log.d("listView2", "listView:" + listView + 
                ", view:" + view.getClass() + 
                ", position:" + position ); 
    } 
}

Если вы запустите приложение, вы увидите действие, подобное изображенному на рис. 1.3.

Стилизация выбранного элемента

Часто желательно, чтобы пользователь мог четко видеть выбранный в данный момент элемент в файле . Чтобы выбранный элемент выглядел иначе, чем остальные элементы, установите для режима выбора ListView значение CHOICE_MODE_SINGLE, например.

listView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);

Затем при создании базового ListAdapter используйте макет с соответствующим стилем. Проще всего передать поле simple_list_item_activated_1. Например, при использовании в ListView следующий ArrayAdapter заставит выбранный элемент иметь синий фон.

Полную статью смотрите здесь: https://www.djuices.com/android-tutorial-listview/

Первоначально опубликовано на https://www.djuices.com 26 ноября 2021 г.