Добавьте класс под названием SampleListAdapter:
// Класс предоставляющий возможность определения поведения адаптера для правильной привязки информации к виджетам
public class SampleListAdapter extends BaseAdapter {
// Объявление необходимых перенных получаемых через конструктор
// Объект Context необходим для получения ссылки на Activity в котором адаптер подключается к ListView
Context context;
// Массив для хранения элементов для привязки к ListView
List<DBItem> items = new ArrayList<>();
// Конструктор класса адаптера, принимает параметры контекста и элементов переданных с Activity
public SampleListAdapter(Context context, List<DBItem> items) {
// Присвоить полученные параметры локальным переменным класса
this.context = context;
this.items = items;
}
// Функция для возвращения количества элементов
@Override
public int getCount() {
return items.size();
}
// Получить элемент для показа в необходимой позиции
@Override
public DBItem getItem(int position) {
return items.get(position);
}
// Получить id элемента, обычно возвращается запрашиваемое значение переданное по параметру, потому что в массиве расположение элементов идёт по порядку и так и показывается в ListView на данный момент.
@Override
public long getItemId(int position) {
return position;
}
// Получить корневой View, в котором и распологаются виджеты
@Override
public View getView(int position, View view, ViewGroup parent) {
// Если View ещё не создавался создать иначе использовать уже созданный ранее view
if (view == null) {
// Получить ссылку к экземпляру LayoutInflater для получения xml файла макета
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
// Запросить файл макета и присвоить переменной view класса View теперь view это LinearLayout объявленный в файле adapter_item.xml. В файле adapter_item.xml определяется макет для одной строки списка потому что структура всех строк списка одинаковая
view = inflater.inflate(R.layout.adapter_item, parent, false);
}
// Найти ссылку на TextView внутри LinearLayout файла макета
TextView text = view.findViewById(R.id.text);
// Установить значение для TextView равной значению элемента массива соответствующей позиции данной строки
text.setText(items.get(position).title);
// установить в качестве тега TextView значение позиции элемента тег может хранить в себе объект и служит для дальнейшего определения этого объекта по тегу или хранения и обработки информации, которую нет нужды показывать в интерфейсе пользователю
text.setTag(items.get(position).id);
// Вернуть объект View - корневой LinearLayout из файла adapter_item.xml
return view;
}
}
Добавьте ещё один класс для фрагмента со списком элементов:
public class MasterFragment extends Fragment {
// Виджет для показа списка
ListView listView;
// Переменная для получения доступа к функциям работы с базой данных
Database db;
// Плавающая кнопка в интерфейсе для добавления новых записей
FloatingActionButton addNew;
// Текстовое поле
EditText searchField;
// Функция вызывается при показе фрагмента внутри (в контексте) Activity
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
// Инициализация переменной доступа к функциям работы с базой данных
db = new Database(getContext());
// Добавить файл макета master_fragment.xml к этому фрагменту
View v = inflater.inflate(R.layout.master_fragment, container, false);
// Присвоить переменной класса ссылку к текстовому полю в файле макета
searchField = v.findViewById(R.id.searchField);
// Привязать обработчик событий нажатия кнопки поиск (заменяет enter, при указании атрибутов imeOptions="actionSearch" и указании inputType="text") и при нажатии на кнопку поиска вызывается функция onEditorAction и передаётся actionId нажатой кнопки
searchField.setOnEditorActionListener(new TextView.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
// Проверить, если нажатая кнопка это кнопка поиск
if (actionId == EditorInfo.IME_ACTION_SEARCH) {
if (searchField.getText().length() > 0) {
// Передать функции search текст введенный в текстовом поле поиска
search(searchField.getText().toString());
} else {
// Если текстовое поле пустое показать список всех записей
setAdapterToList();
}
}
return true;
}
});
// Присвоить ссылку к объекту FloatingActionButton (круглая кнопка в правом нижнем углу экрана)
addNew = v.findViewById(R.id.addNewItem);
// Установить обработчик событий click по кнопке
addNew.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// Объявить и инициализировать переменную класса AddItemsDialog для показа диалогового окна добавления записей
AddItemsDialog addItems = new AddItemsDialog();
// Показать диаологовое окно для добавления новой записи
addItems.show(getActivity().getSupportFragmentManager(), "AddItemsDialog");
}
});
// Получение экземпляра ListView размещенного в макете
listView = v.findViewById(R.id.list);
// Заполнить listView всеми записями из базы данных
setAdapterToList();
// Зарегистрировать элемент для контекстного меню без этого при долгом нажатии контекстное меню не вызывается
registerForContextMenu(listView);
// Эту строку можно не писать она для примера использования нескольких контекстных меню в одном окне, но для разных элементов
registerForContextMenu(addNew);
// Указать обработчик кликов по элементам списка
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
// Каждый раз при клике на какой-либо элемент вызывается функция onItemClick
// и ей передаётся в качестве параметра корневой элемент макета, в данном случае LinearLayout
// позиция выбранного элемента и id элемента
// Через корневой элемент макета переданного через экземпляр класса View
// можно получить ссылку к любому объекту в макете. Например, через их id.
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
// Получить ссылку на TextView в файле макета по id
TextView textView = view.findViewById(R.id.text);
// Получисть и присвоить значение заголовка выбранного элемента переменной
String title = textView.getText().toString();
// Получить и присвоить значение ID из атрибута tag TextView переменной
int index = (int) textView.getTag();
// Объявлеине экземпляра переменной DetailFragment
DetailFragment detail = new DetailFragment();
// Переменная класса Bundle для передачи информации экземпляру класса DetailFragment
Bundle args = new Bundle();
// Добавить целочисленное значение с ключом id и индексом выбранного элемента из списка
args.putInt("id", index);
// Установить аргументы в экземпляр фрагмента
detail.setArguments(args);
// Получить ссылку на Activity в котором показывается данный фрагмент
getActivity()
// Получить доступ менеджеру фрагментов
.getSupportFragmentManager()
// Начать транзакцию фрагментов
.beginTransaction()
// Заменить этот фрагмент со списком заголовков на фрагмент с текстом описания
.replace(R.id.fragmentContainer, detail)
// Добавить в стэк инициализированных фрагментов, чтобы при нажатии на кнопку назад пользователю выводился этот фрагмент, если эту строку не писать при нажатии на кнопку назад Activity закрывается сразу
.addToBackStack(null)
// Установить анимацию для показа DetailFragment
.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
// Завершить транзакцию фрагмента
.commit();
}
});
// Вернуть View, в данном случае LinearLayout из файла master_fragment.xml
return v;
}
// Функция для получения искомой строки в базе данных, отправки запроса, получения результатов, создания нового адаптера с новыми результатами (с новым массивом) и привязки адаптера к ListView
void search(String s) {
// Получение ссылки к классу базы данных для отправки запроса
Database d = new Database(getContext());
// Объявить новый List для хранения объектов DBItem и присвоить значения полученные в результате поиска информации в базе данных
List<DBItem> results = d.findItems(s);
// Объявление и инициализация нового адаптера
SampleListAdapter adapter = new SampleListAdapter(getContext(), results);
// Привязать адаптер к ListView
listView.setAdapter(adapter);
}
// Функция для получения всех записей и показа в списке
void setAdapterToList() {
// Объявление и инициализация экземпляра адаптера класса SimpleListAdapter адаптер служит для соединения данных с виджетом для показа. Функция getTitles() написанная в классе Database служит для получения заголовков хранимой в базе данных информации
SampleListAdapter adapter = new SampleListAdapter(getContext(), db.getTitles());
// привязать адаптер к ListView
listView.setAdapter(adapter);
}
// Функция для показа контекстного меню
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
MenuInflater menuInflater = getActivity().getMenuInflater();
// Через MenuInflater привязваем файл меню с нужными пунктами к нашему View. В одном окне можно зарегистрировать несколько контекстных меню и какое показывать можете указать проверяя id элемента на которого было произведено долгое нажатие
if (v.getId() == R.id.list) {
menuInflater.inflate(R.menu.contextdelete, menu);
} else {
menuInflater.inflate(R.menu.anothermenu, menu);
}
}
// Функция вызывается при клике на элемент контекстного меню
@Override
public boolean onContextItemSelected(MenuItem item) {
// Этот объект нужен для получения позиции нажатого элемента в списке
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
// Проверяем id выбранного меню и делаем необходимые действия в зависимости от этого
if (item.getItemId() == R.id.delete) {
Database db = new Database(getContext());
// По выбранному элементу через выбранную позицию элемента с адаптера получаем объект и его id
int id = ((DBItem) listView.getAdapter().getItem(info.position)).id;
// id передаётся функции для удаления записи с базы данных и при правильном удалении список обновляется
if (db.deleteItemById(id)) {
setAdapterToList();
}
}
return super.onContextItemSelected(item);
}
}
Реклама