From 3d88520af543dd53bad9fc06e26b15e8ddf4392b Mon Sep 17 00:00:00 2001 From: pz96pqh8i <3326392379@qq.com> Date: Tue, 31 Dec 2024 02:12:54 +0800 Subject: [PATCH] ADD file via upload --- NotesListAdapter.java | 382 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 382 insertions(+) create mode 100644 NotesListAdapter.java diff --git a/NotesListAdapter.java b/NotesListAdapter.java new file mode 100644 index 0000000..f90c5e6 --- /dev/null +++ b/NotesListAdapter.java @@ -0,0 +1,382 @@ +/* + * Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.micode.notes.ui; + +import android.content.Context; +import android.database.Cursor; +import android.util.Log; +import android.view.View; +import android.view.ViewGroup; +import android.widget.CursorAdapter; + +import net.micode.notes.data.Notes; + +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; + + +public class NotesListAdapter extends CursorAdapter { + private static final String TAG = "NotesListAdapter"; + private Context mContext; + private HashMap mSelectedIndex; + private int mNotesCount; + private boolean mChoiceMode; + + public static class AppWidgetAttribute { + public int widgetId; + public int widgetType; + }; + + public NotesListAdapter(Context context) { + super(context, null); + mSelectedIndex = new HashMap(); + mContext = context; + mNotesCount = 0; + } + + @Override + public View newView(Context context, Cursor cursor, ViewGroup parent) { + return new NotesListItem(context); + } + + @Override + public void bindView(View view, Context context, Cursor cursor) { + if (view instanceof NotesListItem) { + NoteItemData itemData = new NoteItemData(context, cursor); + ((NotesListItem) view).bind(context, itemData, mChoiceMode, + isSelectedItem(cursor.getPosition())); + } + } + + public void setCheckedItem(final int position, final boolean checked) { + mSelectedIndex.put(position, checked); + notifyDataSetChanged(); + } + + public boolean isInChoiceMode() { + return mChoiceMode; + } + + public void setChoiceMode(boolean mode) { + mSelectedIndex.clear(); + mChoiceMode = mode; + } + + public void selectAll(boolean checked) { + Cursor cursor = getCursor(); + for (int i = 0; i < getCount(); i++) { + if (cursor.moveToPosition(i)) { + if (NoteItemData.getNoteType(cursor) == Notes.TYPE_NOTE) { + setCheckedItem(i, checked); + } + } + } + } + + public HashSet getSelectedItemIds() { + HashSet itemSet = new HashSet(); + for (Integer position : mSelectedIndex.keySet()) { + if (mSelectedIndex.get(position) == true) { + Long id = getItemId(position); + if (id == Notes.ID_ROOT_FOLDER) { + Log.d(TAG, "Wrong item id, should not happen"); + } else { + itemSet.add(id); + } + } + } + + return itemSet; + } + + public HashSet getSelectedWidget() { + HashSet itemSet = new HashSet(); + for (Integer position : mSelectedIndex.keySet()) { + if (mSelectedIndex.get(position) == true) { + Cursor c = (Cursor) getItem(position); + if (c != null) { + AppWidgetAttribute widget = new AppWidgetAttribute(); + NoteItemData item = new NoteItemData(mContext, c); + widget.widgetId = item.getWidgetId(); + widget.widgetType = item.getWidgetType(); + itemSet.add(widget); + /** + * Don't close cursor here, only the adapter could close it + */ + } else { + Log.e(TAG, "Invalid cursor"); + return null; + } + } + } + return itemSet; + } + + public int getSelectedCount() { + Collection values = mSelectedIndex.values(); + if (null == values) { + return 0; + } + Iterator iter = values.iterator(); + int count = 0; + while (iter.hasNext()) { + if (true == iter.next()) { + count++; + } + } + return count; + } + + public boolean isAllSelected() { + int checkedCount = getSelectedCount(); + return (checkedCount != 0 && checkedCount == mNotesCount); + } + + public boolean isSelectedItem(final int position) { + if (null == mSelectedIndex.get(position)) { + return false; + } + return mSelectedIndex.get(position); + } + + @Override + protected void onContentChanged() { + super.onContentChanged(); + calcNotesCount(); + } + + @Override + public void changeCursor(Cursor cursor) { + super.changeCursor(cursor); + calcNotesCount(); + } + + private void calcNotesCount() { + mNotesCount = 0; + for (int i = 0; i < getCount(); i++) { + Cursor c = (Cursor) getItem(i); + if (c != null) { + if (NoteItemData.getNoteType(c) == Notes.TYPE_NOTE) { + mNotesCount++; + } + } else { + Log.e(TAG, "Invalid cursor"); + return; + } + } + } +} + + + +package net.micode.notes.ui; + +import android.content.Context; +import android.database.Cursor; +import android.util.Log; +import android.view.View; +import android.view.ViewGroup; +import android.widget.CursorAdapter; + +import net.micode.notes.data.Notes; + +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; + +// NotesListAdapter类继承自CursorAdapter,是一个用于适配便签列表数据到ListView等列表视图组件的适配器类, +// 它负责将从数据库查询获取的Cursor数据转换为适合展示的视图项,并处理了列表项的选择、计数以及与小部件相关属性获取等功能逻辑。 +public class NotesListAdapter extends CursorAdapter { + + // 用于日志记录的标签,方便在日志输出中识别该类相关的日志信息。 + private static final String TAG = "NotesListAdapter"; + // 用于存储上下文信息,方便后续在创建视图、获取资源等操作中使用。 + private Context mContext; + // 使用HashMap来存储列表项的选中状态,键为列表项的位置索引,值为布尔类型表示是否被选中,以此记录用户在多选模式下对各列表项的选择情况。 + private HashMap mSelectedIndex; + // 用于记录便签的数量,通过遍历游标数据统计得出,便于后续判断全选等相关逻辑时使用。 + private int mNotesCount; + // 用于标记当前列表是否处于多选模式,控制相关的界面交互和数据处理逻辑,例如是否显示多选菜单、是否响应多选相关操作等。 + private boolean mChoiceMode; + + // 内部静态类,用于封装与便签关联的小部件的属性信息,包含小部件的ID和类型两个成员变量,方便在处理便签与小部件关联操作时传递和使用相关数据。 + public static class AppWidgetAttribute { + public int widgetId; + public int widgetType; + }; + + // 构造函数,接收上下文对象作为参数,调用父类构造函数传入上下文和空游标初始化,同时初始化选中状态的HashMap和记录便签数量的变量,并保存传入的上下文信息。 + public NotesListAdapter(Context context) { + super(context, null); + mSelectedIndex = new HashMap(); + mContext = context; + mNotesCount = 0; + } + + // 重写父类的方法,用于创建一个新的视图对象来展示列表项,在这里返回一个自定义的`NotesListItem`视图对象,该对象负责具体的便签数据展示布局和渲染。 + @Override + public View newView(Context context, Cursor cursor, ViewGroup parent) { + return new NotesListItem(context); + } + + // 重写父类的方法,用于将数据绑定到已创建的视图对象上进行展示,在这里从游标中获取便签数据封装成`NoteItemData`对象, + // 然后调用`NotesListItem`的`bind`方法将数据、多选模式状态以及该项是否被选中的信息传递进去,完成数据与视图的绑定展示。 + @Override + public void bindView(View view, Context context, Cursor cursor) { + if (view instanceof NotesListItem) { + NoteItemData itemData = new NoteItemData(context, cursor); + ((NotesListItem) view).bind(context, itemData, mChoiceMode, + isSelectedItem(cursor.getPosition())); + } + } + + // 用于设置指定位置的列表项的选中状态,将位置索引和对应的选中状态存入`mSelectedIndex` HashMap中,并通知数据集已改变,使得列表视图能够更新相应的显示状态。 + public void setCheckedItem(final int position, final boolean checked) { + mSelectedIndex.put(position, checked); + notifyDataSetChanged(); + } + + // 用于判断当前列表是否处于多选模式,外部代码可以调用该方法获取相应的状态信息,以决定是否显示多选相关的界面元素或执行相应逻辑。 + public boolean isInChoiceMode() { + return mChoiceMode; + } + + // 用于设置列表的多选模式状态,当进入或退出多选模式时调用该方法,会先清空之前的选中状态记录,然后更新`mChoiceMode`变量,以切换相应的操作逻辑和界面显示。 + public void setChoiceMode(boolean mode) { + mSelectedIndex.clear(); + mChoiceMode = mode; + } + + // 用于全选或取消全选所有符合条件(通常是便签类型为普通便签)的列表项,通过遍历游标中的所有记录,根据便签类型判断是否进行选中状态设置,实现批量选中或取消选中的功能。 + public void selectAll(boolean checked) { + Cursor cursor = getCursor(); + for (int i = 0; i < getCount(); i++) { + if (cursor.moveToPosition(i)) { + if (NoteItemData.getNoteType(cursor) == Notes.TYPE_NOTE) { + setCheckedItem(i, checked); + } + } + } + } + + // 用于获取所有已选中列表项的ID集合,遍历`mSelectedIndex`中所有被标记为选中的位置索引,通过`getItemId`方法获取对应项的ID, + // 并添加到`HashSet`集合中返回,同时对特殊的根文件夹ID情况进行日志记录(因为可能不符合预期的选中逻辑)。 + public HashSet getSelectedItemIds() { + HashSet itemSet = new HashSet(); + for (Integer position : mSelectedIndex.keySet()) { + if (mSelectedIndex.get(position) == true) { + Long id = getItemId(position); + if (id == Notes.ID_ROOT_FOLDER) { + Log.d(TAG, "Wrong item id, should not happen"); + } else { + itemSet.add(id); + } + } + } + + return itemSet; + } + + // 用于获取所有已选中列表项关联的小部件属性集合,遍历`mSelectedIndex`中所有被标记为选中的位置索引,通过`getItem`方法获取对应位置的游标数据, + // 进而创建`AppWidgetAttribute`对象并填充小部件的ID和类型信息,添加到`HashSet`集合中返回,同时对游标无效的情况进行日志记录并返回`null`。 + public HashSet getSelectedWidget() { + HashSet itemSet = new HashSet(); + for (Integer position : mSelectedIndex.keySet()) { + if (mSelectedIndex.get(position) == true) { + Cursor c = (Cursor) getItem(position); + if (c!= null) { + AppWidgetAttribute widget = new AppWidgetAttribute(); + NoteItemData item = new NoteItemData(mContext, c); + widget.widgetId = item.getWidgetId(); + widget.widgetType = item.getWidgetType(); + itemSet.add(widget); + /** + * Don't close cursor here, only the adapter could close it + */ + } else { + Log.e(TAG, "Invalid cursor"); + return null; + } + } + } + return itemSet; + } + + // 用于获取当前已选中列表项的数量,通过获取`mSelectedIndex`中所有值(即各位置的选中状态)的集合,然后遍历该集合统计值为`true`(表示选中)的个数并返回。 + public int getSelectedCount() { + Collection values = mSelectedIndex.values(); + if (null == values) { + return 0; + } + Iterator iter = values.iterator(); + int count = 0; + while (iter.hasNext()) { + if (true == iter.next()) { + count++; + } + } + return count; + } + + // 用于判断是否所有符合条件(通常是便签类型相关限定)的列表项都已被选中,通过比较已选中的数量和总的便签数量来确定,若已选中数量不为0且等于便签数量则返回`true`,表示全选状态。 + public boolean isAllSelected() { + int checkedCount = getSelectedCount(); + return (checkedCount!= 0 && checkedCount == mNotesCount); + } + + // 用于判断指定位置的列表项是否被选中,先判断对应位置在`mSelectedIndex`中的值是否为`null`(未记录则视为未选中), + // 若不为`null`则返回该位置记录的选中状态(`true`表示选中,`false`表示未选中)。 + public boolean isSelectedItem(final int position) { + if (null == mSelectedIndex.get(position)) { + return false; + } + return mSelectedIndex.get(position); + } + + // 重写父类的方法,当数据集内容发生变化时会被调用,在这里调用`calcNotesCount`方法重新计算便签的数量,以保证相关统计数据的准确性。 + @Override + protected void onContentChanged() { + super.onContentChanged(); + calcNotesCount(); + } + + // 重写父类的方法,当游标数据发生改变(比如重新查询获取了新的数据)时会被调用,同样在这里调用`calcNotesCount`方法重新计算便签的数量,以适配新的数据情况。 + @Override + public void changeCursor(Cursor cursor) { + super.changeCursor(cursor); + calcNotesCount(); + } + + // 私有方法,用于计算便签的数量,通过遍历游标中的所有记录,根据记录对应的便签类型判断是否为普通便签,若是则数量加1,最终得到总的便签数量并更新`mNotesCount`变量。 + private void calcNotesCount() { + mNotesCount = 0; + for (int i = 0; i < getCount(); i++) { + Cursor c = (Cursor) getItem(i); + if (c!= null) { + if (NoteItemData.getNoteType(c) == Notes.TYPE_NOTE) { + mNotesCount++; + } + } else { + Log.e(TAG, "Invalid cursor"); + return; + } + } + } +} \ No newline at end of file