Корзина для android studio

Полный список

— создаем свой адаптер на основе 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 позицию пункта списка и помечает соответствующий товар, как положенный в корзину.

Читайте также:  Android async await java

Тут важно понимать, что без этого обработчика не работало бы помещение товаров в корзину. Да и на экране — значения чекбоксов в списке терялись бы при прокрутке. Потому что пункты списка пересоздаются, если они уйдут «за экран» и снова появятся. Это пересоздание обеспечивает метод getView, а он для заполнения View берет данные из товаров. Значит при нажатии на чекбокс, обязательно надо сохранить в данных о товаре то, что он теперь в корзине.

Остается накодить MainActivity.java:

Тут кода совсем мало.

В onCreate создаем адаптер и список.

В методе fillData генерируем данные для адаптера. В качестве картинки используем стандартную для всех пунктов. В идеале, для каждого товара своя картинка.

Метод showResult получает из адаптера список товаров корзины и выводит их наименования. Этот метод вызывается по нажатию кнопки на экране, т.к. прописан в ее свойстве onClick.

Все сохраняем и запускаем. Отмечаем товары и жмем кнопку для просмотра содержимого корзины.

Достаточно непростой получился пример из-за чекбокса.

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

На следующем уроке:

— используем Header и Footer в списках
— разбираемся, как и где используется HeaderViewListAdapter

Присоединяйтесь к нам в Telegram:

— в канале StartAndroid публикуются ссылки на новые статьи с сайта startandroid.ru и интересные материалы с хабра, medium.com и т.п.

— в чатах решаем возникающие вопросы и проблемы по различным темам: Android, Kotlin, RxJava, Dagger, Тестирование

— ну и если просто хочется поговорить с коллегами по разработке, то есть чат Флудильня

— новый чат Performance для обсуждения проблем производительности и для ваших пожеланий по содержанию курса по этой теме

Источник

Android programmers blog

Simply about difficult

Поиск по этому блогу

четверг, 26 апреля 2018 г.

Создание корзины для мобильного интернет магазина

Вот такой у нас будет мини магазин, в котором у нас будет два экрана. Простенько и красивенько, дак еще и с дизайном 🙂
За основу корзины я взял готовое решение корзины с github’a . Точно не помню с какого, так как там наплодилось куча подобных решений от разных мастеров копипасты. По этому укажу тот который нашел у себя в фейворитах и который больше всех похож на то что я использовал.

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

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

И дальше создаем две модели в которых описываем остальные параметры которые нам нужны для хранения данных о продукте.

Тут у нас два объекта, количество, и второй объект который в купе будет иметь название, цену и т.д. Как я писал выше.

Создали объект в котором будем хранить все детали покупки, сделали ее Serializable для доступости передачи этого объекта в Intent’aх или SharedPreferences и Saleable для того что бы хранить его в HashMap в дальнейшем, так как у нас все наши покупки будут находиться внутри этого объекта, который будет находиться внутри HashMap, и по ключу мы будем доставать его.

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

Читайте также:  Семейный поиск яндекса включить андроид

Для создания сообщения в логах что продукт не найден.

Для отображения выход за пределы определенных границ.

Ну и теперь нам осталось создать главный класс helper который будет в себе содержать создание, обновление, удаление и полное очищение БД. Ну и там дальше еще можно будет получить количество покупок, общее количество денег которые затрачено на весь товар в корзине и т. д.

Здесь у нас все методы для работы с записью, обновлением и удалением продуктов из списка продуктов. Каждый метод отвечает за свою функцию, по этому объяснять я не вижу смысла что оно делает. У нас есть хешмеп — cartItemMap, в который мы записывает, из которого удаляем, и в котором обновляем по ключу — объекту наши данные.

Ну и дальше у нас будет класс синглтон, который будет статичным объектом в котором мы по созданию будем хранить данные о продуктах который купил пользователь.

Тут у нас два метода, getCart() который возвращает объект CartEntity, который мы создали выше, что бы мы могли делать все возможные функции из этого класса. И getCartItems() который возвращает список товаров которые пользователь выбрал в корзину. Собственно и все. Теперь у нас корзина полностью готова, теперь будем учиться его использовать.

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

Начнем из далека, нам нужно подключить библиотеки которые мы будем использовать для работы, по традиции это как всегда будет ButterKnife, Picasso и RecyclerView.

Значит у нас подключены библиотеки в dependencies, и мы еще подключили Java 8 для красивого сокращения кода, возможно какие-то функции понадобятся, в любом случае ретролямбда уже не нужна как раньше, теперь у нас это есть из коробки при помощи Java 8.

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

Вот собственно о том что я говорил. В onCreate() мы подключаем баттернайф, указали абстрактный метод для прописывания леяута, и вызвали в конце onCreateView() который у нас будет проходить вся логика при создании активити.
onOptionsItemSelected() — выполняет стандартную функцию по для отслеживания клика пользователя на меню.
setupBadge() — у нас создает бадж на иконке если у нас есть товары в корзине, и если нету то прячет его.
onCreateOptionsMenu() — создает кастомную иконку с баджем поверх ее. По клику на нее мы вызываем onOptionsItemSelected().

Ну и два абстрактных метода для переопределения функций getViewId() и onCreateView().

Добавили иконку в меню, задали кастомный леяут с баджем, ну и добавили иконку поверх чисто для вида. Дальше нам нужно создать view_custom_action_cart.xml в котором у нас будет иконка и поверх нее бадж.

Ну тут в общем понятно, иконка поверх которой у нас текствью у которого фон зарисован оранжевым цветом и оно все обведено в черный кружочек. Далее нам нужно создать badge_background.xml.

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

По красоте все, у нас будет стильно 🙂 Далее создаем базовый фрагмент, он простой до ужаса.

Тут тоже самое что мы делали в BaseActivity только без подключения меню. setHasOptionsMenu(true) — вызываем для того что бы меню можно было вызывать из фрагмента, тут нам оно не нужно, но на всякий случай я вставил и забыл его удалить. 🙂

Пустой как моя жизнь. Тут нам ничего не надо, но вообще тут можно что-то добавить что-то что душе угодно, любой функционал. Вся логика будет в ProductFragment. XML будет выглядеть так:

Прицепили фрагмент к активити, что бы отображать его внутри активти. Я так делаю во всех проектах, как по мне на много гибче чем делать в одной активити все.

Читайте также:  Звездные войны герои для андроид

В onViewCreated() — создаем адаптер который мы еще не создали, но он у нас должен быть. Сетим его в ресайклер вью и показываем по красоте. Да, а еще у нас есть еще класс который содержит в себе продукты которые у нас отображает адаптер, ну вообще в идеале конечно у нас должно подтягиваться из серверной части, но тут у нас будет все локально.

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

Это объект который у нас описывает как будет выглядить продукт — айди, имя, описание, цена и картинка.

В общем то, тут объяснять нечего просто создали несколько продуктов для красоты, продолжим рассматривать ProductFragment.
onItemClick() — у нас по клику на кнопку бай переходит в корзину, в которой у нас уже будет отображаться список покупок для отправки. Каждый клик добавляем 1 товар в корзину, и обновляем меню что бы отображался бадж.

И давайте создадим адаптер. В нем мы просто отображаем наш список товаров.

Собственно все тривиально, те кто писали адаптеры кастомные — не должно составить труда понять что тут происходит. В onCreateViewHolder() — проинициализировали леяут. В onBindViewHolder() — забиндили все данные что мы передали в catalogModels. Ну и в ReceiveViewHolder забиндили все вьюхи что нам нужны и устанавливаем на что у нас будет клик.

XML у нас будет крутой. У нас тут будет и картинка, и описание, и цена. И это все будет выглядит круто и красивенько.

Давайте кстати еще посмотрим что у нас в string.xml, а то я не знаю куда его засунуть, у нас же оно в разных классах используется.

Собственно это нам понадобится в дальнейшем, по этому пусть будет тут.

Теперь у нас есть все что нужно для отображения корзины. По этому создаем экран на котором у нас будет отображаться наша корзина.

onCreateView() — отображаем кнопку назад. Собственно и все.

Тоже самое что и в продукте, по этому ничего нового 🙂 Просто цепляем фрагмент к активити, для разделения логики и жизненного цикла.

Тут у нас вообще прям работа тетаническая выполнена. В onViewCreated() у нас вызывается onUpdateList() который у нас создается адаптер и сетим данные в него. Нам нужен метод onUpdateList() для того что бы обновлять данные в списке когда мы изменяем количество по клику на кнопку «+» или «-«. Ну и передаем в адаптер CartHelper.getCartItems() который у нас хранит все наши товары.
onItemMinusClicked() — у нас по клику уменьшает количество айтемов в адаптере, и в самой корзине.
onItemPlusClicked() — соответственно увеличивает количество.
onBuyClick() — по клику на кнопку Buy, мы отображаем тост с количеством купленного товара, и общую сумму на которую мы купили. Дальше стираем для вида что купили из списка все, и возвращаемся в список товаров.

Список и кнопка. Что еще нужно для счастья? Дальше создаем адаптер для отображения, выбранных товаров с кнопочкой увеличить количество или уменьшить.

Значит то что у нас в конструкторе мы сетим список который у нас в корзине я думаю понятно. Дальше в методе updateItem() мы или увеличиваем количество определенного товара или уменьшаем. Если уменьшаем до 0 то просто стираем товар из списка. Ну а дальше по старинке onCreateViewHolder() — сетит леяут. onBindViewHolder() биндит то что у нас в списке в вьюхи.

Ну тут у нас в общем все тоже самое что было и в продукте, только немного изменили до вида корзины, добавили кнопки «+» и «-«.

Ну и не забываем добавить в манифест пермишен на работу с интернетом, а то у нас картинки не будут отображаться.

Добавили активити которые мы используем, добавили пермишены и собственно все.

Исходники:
GitHub

Источник

Оцените статью