Полный список
— создаем свой адаптер на основе BaseAdapter
Предоставляемые нам адаптеры универсальны и полезны, но иногда их возможностей не хватает для реализации задуманного. Тогда возникает необходимость написать свой адаптер. Попробуем и мы. Создавать будем не с нуля, а используя BaseAdapter.
Сделаем подобие интернет магазина. Будем выводить список товаров. Каждый пункт списка будет содержать название товара, цену и изображение. Также будет возможность отметить пункт галкой, поместив его тем самым в корзину.
Внизу списка сделаем кнопку, которая будет отображать содержимое корзины. В настоящем интернет-магазине мы повесили бы на нее, например, переход к созданию заказа.
Project name: P0541_CustomAdapter
Build Target: Android 2.3.3
Application name: CustomAdapter
Package name: ru.startandroid.develop.p0541customadapter
Create Activity: MainActivity
В файл strings.xml добавим текстовый параметр для названия кнопки.
layout для пункта списка – item.xml:
Чекбокс, пара текстовых полей и картинка.
Теперь пишем код. Можно все написать в MainActivity.java, но тогда он получится достаточно большим и неудобным для чтения. Я раскидаю весь код по трем классам.
Product.java – класс, описывающий товар:
Тут все просто – только конструктор и элементы класса. Не заморачиваюсь с доступом и методами Set/Get, чтобы не усложнять код.
BoxAdapter.java – созданный адаптер, который будем использовать
На всякий случай напомню общий принцип действия адаптера: он получает данные и выдает View для отображения пункта списка.
Смотрим код. В конструкторе мы заполняем наши внутренние переменные и получаем LayoutInflater для работы с layout-ресурсами. В objects у нас теперь хранится список товаров, которые надо отобразить в списке.
Методы, отмеченные аннотацией @Override, мы обязаны реализовать при наследовании BaseAdapter. Эти методы используются списком и должны работать корректно.
Метод getCount должен возвращать кол-во элементов. Мы возвращаем кол-во товаров.
Метод getItem должен возвращать элемент по указанной позиции. Используя позицию, получаем конкретный элемент из objects.
Метод getItemId должен возвращать id элемента. Здесь не заморачиваемся и возвращаем позицию. Кстати, также сделано в некоторых адаптерах. Поэтому мы и видели в обработчиках, что >
Метод getView должен возвращать View пункта списка. Для этого мы создавали layout-ресурс R.layout.item. В этом методе мы должны из R.layout.item создать View, заполнить его данными и отдать списку. Но перед тем как создавать, мы пробуем использовать convertView, который идет на вход метода. Это уже созданное ранее View, но неиспользуемое в данный момент. Например, при прокрутке списка, часть пунктов уходит за экран и их уже не надо прорисовывать. View из этих «невидимых» пунктов используются для новых пунктов. Нам остается только заполнить их данными. Это значительно ускоряет работу приложения, т.к. не надо прогонять inflate лишний раз.
Если же convertView в этот раз нам не дали (null), то создаем сами view. Далее заполняем наименования, цену и картинку из данных по товарам. Для чекбокса мы присваиваем обработчик, сохраняем в Tag позицию элемента и ставим галку, если товар уже в корзине.
Tag – это некое Object-хранилище у каждого View, куда вы можете поместить нужные вам данные. В нашем случае я для каждого чекбокса помещаю в его Tag номер позиции пункта списка. Далее в обработчике чекбокса я смогу этот номер позиции извлечь и определить, в каком пункте списка был нажат чекбокс.
В итоге, метод getView возвращает списку полностью заполненное view, и список его отобразит как очередной пункт.
Далее идет пара методов, которые не обязательно было создавать при наследовании BaseAdapter. Я их создал для удобства.
Метод getProduct – это аналог getItem, но он сразу конвертирует Object в Product. Он используется всего пару раз. И в принципе, можно было бы и без него обойтись.
Метод getBox проверяет, какие товары отмечены галками и формирует из них коллекцию-корзину.
myCheckChangeList – обработчик для чекбоксов. Когда мы нажимаем на чекбокс в списке, он срабатывает, читает из Tag позицию пункта списка и помечает соответствующий товар, как положенный в корзину.
Тут важно понимать, что без этого обработчика не работало бы помещение товаров в корзину. Да и на экране — значения чекбоксов в списке терялись бы при прокрутке. Потому что пункты списка пересоздаются, если они уйдут «за экран» и снова появятся. Это пересоздание обеспечивает метод getView, а он для заполнения View берет данные из товаров. Значит при нажатии на чекбокс, обязательно надо сохранить в данных о товаре то, что он теперь в корзине.
Остается накодить MainActivity.java:
Тут кода совсем мало.
В onCreate создаем адаптер и список.
В методе fillData генерируем данные для адаптера. В качестве картинки используем стандартную для всех пунктов. В идеале, для каждого товара своя картинка.
Метод showResult получает из адаптера список товаров корзины и выводит их наименования. Этот метод вызывается по нажатию кнопки на экране, т.к. прописан в ее свойстве onClick.
Все сохраняем и запускаем. Отмечаем товары и жмем кнопку для просмотра содержимого корзины.
Достаточно непростой получился пример из-за чекбокса.
Вполне может быть, что есть другой способ реализации этого примера. Но смысл был в том, чтобы показать создание своего адаптера. Для закрепления темы посмотрите еще этот гугловский пример.
На следующем уроке:
— используем Header и Footer в списках
— разбираемся, как и где используется HeaderViewListAdapter
Присоединяйтесь к нам в Telegram:
— в канале StartAndroid публикуются ссылки на новые статьи с сайта startandroid.ru и интересные материалы с хабра, medium.com и т.п.
— в чатах решаем возникающие вопросы и проблемы по различным темам: Android, Kotlin, RxJava, Dagger, Тестирование
— ну и если просто хочется поговорить с коллегами по разработке, то есть чат Флудильня
— новый чат Performance для обсуждения проблем производительности и для ваших пожеланий по содержанию курса по этой теме
Источник
Custom Array Adapters made Easy!
In the Field of Android Development, Array Adapters have always played an important role in populating and controlling the ListViews and Spinners. Whenever we need to show our data as a list to the user, Array Adapters always come handy to easily manage the behaviour of the ListView and their items. But does the default Adapter class help us to create our own list item that we want to show to the user?? I guess not..So I have created a sample project called Popular Movies in which we will create a custom array adapter which which will help us to add an Image and Text to the ListItem (For those who don’t know, ListItem is an item of your total list whose layout will remain the same for every item and data will change).
Why Custom Array Adapter??
Android framework by default provides us the ability to create listItems which includes only a single information or a single TextView. But we always come across apps that show multiple information in a single ListItem such as Instagram, BookMyShow, Whatsapp and many more. Implementing your own custom array adapter can seem an intimidating job at first but once you create some more, you will get hold. As a beginner when I started with ArrayAdapters it was very difficult to hold on to the concepts which were used to correctly implement it but I made atleast 4–5 implementations just to make sure I understand what exactly was going on in the code. I would suggest that you should practice it because custom array adapters are very important when it comes to showing information in List.
Lets Start!
We am going to make a custom project which is called PopularMovies App in which we will list the information of some movies with their poster. This will be the final stage of the app :
Create a layout xml file which will have the design of your ListItem.
All the files related to the layout of the app are contained in the layout folder of the res directory. So first navigate into the directory
Notice that this folder contains only single file i.e activity_main.xml. This file will contain the layout and design to your Main Activity which contains your ListView. We are going to make a list_item.xml file that contains the code to the basic structure and design of the list item of the List view. Here is a snippet of the list_item.xml file :
In this file we added a ImageView and 2 TextViews to display the movie details.
Create a Java class which will define your ListItem and store data for every Movie.
It is important to create a Java Class that will store the details for your movie. These classes are called pojos (plain old java objects). These are used to define a collection of related information which can be used to bind that information together and use it to show in Lists or store in databases. In a pojo you should define the type of information you are about to show in the list. For example, if I intent to show an image and textView so I will create variables that will store the image and the data. Pojo should contain getter() and setter() methods which are used to set values to the pojo object and get the data from the object. Here is a code snippet for a pojo class for Movie :
It is important that your Java class should be declared public because you will need to create an instance of it in the MainActivity Class. The variables should be declared as private as there are cases in which you need to make variables with same names in different objects. This is the reason we need to create the getter and setter methods which are used to add and extract to and from the object.
Create a Java class which will extend the Default ArrayAdapter class.
Now is the time when you implement your own array adapter. Create a java class and give it any relative name. I named it MovieAdapter.class . Your class should extend ArrayAdapter class where T should be replaced by the pojo class you just made. It is done to tell the adapter about what type of data the adapter has to display. The first step is to define a constructor. You can use any type of constructor mentioned in the documentation here. We will make a constructor which takes 2 arguments i.e the Context and the list of movies. The arguments received in the constructor should be saved in a private variable as they are used to inflate and add data into the view.
Next, you need to Override a method called getView() method. This view is called when a listItem needs to be created and populated with the data.In this method first the View is inflated using the LayoutInflator.inflate() method. It is important that you check that if the view you are trying to inflate is new or reused. If convertView == null then the view should be inflated. In this view, you should set the data into the views. First get the correct movie from the list of movies using the get() method on moviesList and passing position as the argument.
Now using the getter methods defined in the pojo class, store the information encapsulated in the object in different variables. This information is to be set in the view you just inflated so, findViewById() is called on the inflated view and the information is set. At last the view is returned. Here is code snippet of the MovieAdapter.class file :
Add a ListView in the appropriate layout where you want to show your list.
After creating the Custom Adapter you need a ListView which will show the adapter contents. So in the layout file of you Activity (in this case MainActivity) add a tag. Here is code snipet of the activity_main.xml file :
Create an instance of the Custom ArrayAdapter class which you just created and add it to the ListView
This is the final step. After the Custom Adapter is created and ListView is added to the layout file of the activity, an instance of the adapter is to be created and is set to the listView by calling setAdapter() method on the listView. Here is code snippet of the MainActivity.java file :
It is always a good practice to go through the documentation of the topic as you may find the best method for your use. You can now start by customizing the list item to the way you want to show your data and easily make a custom array adapter to control the flow of list.
Thank you for reading this far! If you found this useful , kindly show some love and share it! Stay tuned for more blogs…
Источник
How to create a custom filtered adapter in Android
Παρ 05 Απρίλιος 2019
Introduction
Android offers a nice component named AutoCompleteTextView that can be used to auto-fill a text box from a list of values. In its simplest form, you just create an array adapter passing it a list of objects (that have a proper toString() method). Then you type some characters to the textbox and by default it will filter the results searching in the beginning of the backing object’s toString() result.
However there are times that you don’t want to look at the beginning of the string (because you want to look at the middle of the string) or you don’t want to just to search in toString() method of the object or you want to do some more fancy things in object output. For this you must override the ArrayAdapter and add a custom Filter.
Unfurtunately this isn’t as straightforward as I’d like and I couldn’t find a quick and easy tutorial on how it can be done.
So here goes nothing: In the following I’ll show you a very simple android application that will have the minimum viable custom filtered adapter implementation. You can find the whole project in github: https://github.com/spapas/CustomFilteredAdapeter but I am going to discuss everything here also.
The application
Just create a new project with an empty activity from Android Studio. Use kotlin as the language.
The layout
I’ll keep it as simple as possible:
You should just care about the AutoCompleteTextView with an id of autoCompleteTextView.
The backing data object
I’ll use a simple PoiDao Kotlin data class for this:
I’d like to be able to search to both name, city and category_name of each object. To create a list of the pois to be used to the adapter I can do something like:
The custom adapter
This will be an ArrayAdapter
implementing also the Filterable interface:
You’ll see that we add an instance variable named mPois that gets initialized in the start with allPois (which is the initial list of all pois that is passed to the adapter). The mPois will contain the filtered results. Then, for getCount and getItem we return the corresponding valeus from mPois; the getItemId is used when you have an sqlite backed adapter but I’m including it here for completeness.
The getView will create the specific line for each item in the dropdown. As you’ll see the layout that is passed must have a text child which is set based on some of the attributes of the corresponding poi for each position. Notice that we can use whatever view layout we want for our dropdown result line (this is the layoutResource parameter) but we need to configure it (i.e bind it with the values of the backing object) here properly.
Finally we create a custom instance of the Filter, explained in the next section.
The custom filter
The getFilter creates an object instance of a Filter and returns it:
This object instance overrides two methods of Filter: performFiltering and publishResults. The performFiltering is where the actual filtering is done; it should return a FilterResults object containing a values attribute with the filtered values. In this method we retrieve the charSequence parameter and converit it to lowercase. Then, if this parameter is not empty we filter the corresponding elements of allPois (i.e name, city and category_name in our case) using contains. If the query parameter is empty then we just return all pois. Warning java developers; here the if is used as an expression (i.e its result will be assigned to filterResults.values).
After the performFiltering has finished, the publishResults method is called. This method retrieves the filtered results in its filterResults parameter. Thus it sets mPois of the custom adapter is set to the result of the filter operation and calls notifyDataSetChanged to display the results.
Using the custom adapter
To use the custom adapter you can do something like this in your activity’s onCreate:
We create the PoiAdapter passing it the poisArray and android.R.layout.simple_list_item_1 as the layout. That layout just contains a textview named text. As we’ve already discussed you can pass something more complex here. The thresold defined the number of characters that the user that needs to enter to do the filtering (default is 2).
Please notice that when the user clicks (selects) on an item of the dropdown we set the contents of the textview (or else it will just use the object’s toString() method to set it).
Posted by Serafeim Papastefanos Παρ 05 Απρίλιος 2019 android android, kotlin, adapter, filter
Источник