|
|
|
@ -31,154 +31,198 @@ import java.util.HashSet;
|
|
|
|
|
import java.util.Iterator;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public class NotesListAdapter extends CursorAdapter {
|
|
|
|
|
private static final String TAG = "NotesListAdapter";
|
|
|
|
|
private Context mContext;
|
|
|
|
|
private HashMap<Integer, Boolean> 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<Integer, Boolean>();
|
|
|
|
|
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<Long> getSelectedItemIds() {
|
|
|
|
|
HashSet<Long> itemSet = new HashSet<Long>();
|
|
|
|
|
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<AppWidgetAttribute> getSelectedWidget() {
|
|
|
|
|
HashSet<AppWidgetAttribute> itemSet = new HashSet<AppWidgetAttribute>();
|
|
|
|
|
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<Boolean> values = mSelectedIndex.values();
|
|
|
|
|
if (null == values) {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
Iterator<Boolean> 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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//定义一个公共类NotesListAdapter,它继承自CursorAdapter
|
|
|
|
|
public class NotesListAdapter extends CursorAdapter {
|
|
|
|
|
// 定义一个静态的字符串标签,用于日志记录
|
|
|
|
|
private static final String TAG = "NotesListAdapter";
|
|
|
|
|
// 定义一个Context对象,用于与应用程序环境交互
|
|
|
|
|
private Context mContext;
|
|
|
|
|
// 定义一个HashMap对象,用于存储选中的项目及其对应的索引
|
|
|
|
|
private HashMap<Integer, Boolean> mSelectedIndex;
|
|
|
|
|
// 定义一个变量,用于存储笔记的数量
|
|
|
|
|
private int mNotesCount;
|
|
|
|
|
// 定义一个布尔变量,表示是否处于选择模式
|
|
|
|
|
private boolean mChoiceMode;
|
|
|
|
|
|
|
|
|
|
// 定义一个内部类AppWidgetAttribute,包含widgetId和widgetType两个成员变量
|
|
|
|
|
public static class AppWidgetAttribute {
|
|
|
|
|
public int widgetId;
|
|
|
|
|
public int widgetType;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 定义一个构造函数,接收一个Context对象作为参数
|
|
|
|
|
public NotesListAdapter(Context context) {
|
|
|
|
|
// 调用父类的构造函数,传入上下文、null的游标和null的父视图
|
|
|
|
|
super(context, null);
|
|
|
|
|
// 初始化mSelectedIndex为空的HashMap对象
|
|
|
|
|
mSelectedIndex = new HashMap<Integer, Boolean>();
|
|
|
|
|
// 保存传入的上下文对象
|
|
|
|
|
mContext = context;
|
|
|
|
|
// 初始化笔记数量为0
|
|
|
|
|
mNotesCount = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 重写父类的newView方法,用于创建新的视图对象
|
|
|
|
|
@Override
|
|
|
|
|
public View newView(Context context, Cursor cursor, ViewGroup parent) {
|
|
|
|
|
// 返回一个新的NotesListItem对象
|
|
|
|
|
return new NotesListItem(context);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 重写父类的bindView方法,用于将数据绑定到视图上
|
|
|
|
|
@Override
|
|
|
|
|
public void bindView(View view, Context context, Cursor cursor) {
|
|
|
|
|
// 如果视图是NotesListItem的实例
|
|
|
|
|
if (view instanceof NotesListItem) {
|
|
|
|
|
// 从游标中获取数据,并创建一个新的NoteItemData对象
|
|
|
|
|
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中添加或修改对应位置的选中状态
|
|
|
|
|
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); // 设置该项是否被选中
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//获取所有被选中的项目的id,并返回一个HashSet集合
|
|
|
|
|
public HashSet<Long> getSelectedItemIds() {
|
|
|
|
|
HashSet<Long> itemSet = new HashSet<Long>(); // 创建一个HashSet集合用于存放被选中的项目id
|
|
|
|
|
for (Integer position : mSelectedIndex.keySet()) { // 遍历所有被选中的项目的位置
|
|
|
|
|
if (mSelectedIndex.get(position) == true) { // 如果该位置的项被选中
|
|
|
|
|
Long id = getItemId(position); // 获取该位置的项目id
|
|
|
|
|
if (id == Notes.ID_ROOT_FOLDER) { // 如果获取的id是根文件夹的id,则记录一个错误日志,因为根文件夹不应该被选中
|
|
|
|
|
Log.d(TAG, "Wrong item id, should not happen");
|
|
|
|
|
} else {
|
|
|
|
|
itemSet.add(id); // 否则,将该id添加到HashSet集合中
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return itemSet; // 返回HashSet集合
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//获取所有选中的小部件属性
|
|
|
|
|
public HashSet<AppWidgetAttribute> getSelectedWidget() {
|
|
|
|
|
HashSet<AppWidgetAttribute> itemSet = new HashSet<AppWidgetAttribute>(); // 创建一个HashSet集合用于存放选中的小部件属性
|
|
|
|
|
for (Integer position : mSelectedIndex.keySet()) { // 遍历所有被选中的项目的位置
|
|
|
|
|
if (mSelectedIndex.get(position) == true) { // 如果该位置的项被选中
|
|
|
|
|
Cursor c = (Cursor) getItem(position); // 获取该位置的项目,以Cursor对象的形式返回
|
|
|
|
|
if (c != null) { // 如果Cursor不为空
|
|
|
|
|
AppWidgetAttribute widget = new AppWidgetAttribute(); // 创建一个新的AppWidgetAttribute对象
|
|
|
|
|
NoteItemData item = new NoteItemData(mContext, c); // 使用Cursor对象创建一个NoteItemData对象
|
|
|
|
|
widget.widgetId = item.getWidgetId(); // 从NoteItemData对象获取小部件ID,并设置到AppWidgetAttribute对象中
|
|
|
|
|
widget.widgetType = item.getWidgetType(); // 从NoteItemData对象获取小部件类型,并设置到AppWidgetAttribute对象中
|
|
|
|
|
itemSet.add(widget); // 将创建的AppWidgetAttribute对象添加到HashSet集合中
|
|
|
|
|
/**
|
|
|
|
|
* 这里不要关闭Cursor,只有适配器可以关闭它
|
|
|
|
|
*/
|
|
|
|
|
} else {
|
|
|
|
|
Log.e(TAG, "Invalid cursor"); // 如果Cursor为空,记录错误日志
|
|
|
|
|
return null; // 返回null,表示获取失败
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return itemSet; // 返回HashSet集合,包含所有选中的小部件属性
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//获取被选中的项目数量
|
|
|
|
|
public int getSelectedCount() {
|
|
|
|
|
Collection<Boolean> values = mSelectedIndex.values(); // 获取所有被选中的项目(布尔值)的集合
|
|
|
|
|
if (null == values) { // 如果集合为空(没有被选中的项目)
|
|
|
|
|
return 0; // 返回0,表示被选中的项目数量为0
|
|
|
|
|
}
|
|
|
|
|
Iterator<Boolean> iter = values.iterator(); // 创建一个迭代器来遍历布尔值的集合
|
|
|
|
|
int count = 0; // 初始化计数器为0
|
|
|
|
|
while (iter.hasNext()) { // 当还有下一个布尔值时
|
|
|
|
|
if (true == iter.next()) { // 如果布尔值为true(表示被选中)
|
|
|
|
|
count++; // 计数器加1
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return count; // 返回被选中的项目数量
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//检查是否所有项目都被选中
|
|
|
|
|
public boolean isAllSelected() {
|
|
|
|
|
int checkedCount = getSelectedCount(); // 获取被选中的项目数量
|
|
|
|
|
return (checkedCount != 0 && checkedCount == mNotesCount); // 如果被选中的项目数量不为0且等于总的项目数量,则返回true,表示所有项目都被选中;否则返回false。
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//定义一个方法,用于判断指定位置的项目是否被选中
|
|
|
|
|
public boolean isSelectedItem(final int position) {
|
|
|
|
|
// 如果指定位置的项目在mSelectedIndex映射中对应的值为null,返回false,表示未被选中
|
|
|
|
|
if (null == mSelectedIndex.get(position)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
// 返回mSelectedIndex映射中指定位置对应的值,如果为true则表示被选中,为false则表示未被选中
|
|
|
|
|
return mSelectedIndex.get(position);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//重写onContentChanged方法,该方法在内容发生变化时被调用
|
|
|
|
|
@Override
|
|
|
|
|
protected void onContentChanged() {
|
|
|
|
|
// 调用父类的onContentChanged方法,执行默认的内容变化处理
|
|
|
|
|
super.onContentChanged();
|
|
|
|
|
// 调用calcNotesCount方法,重新计算笔记数量
|
|
|
|
|
calcNotesCount();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//重写changeCursor方法,该方法在Cursor发生变化时被调用
|
|
|
|
|
@Override
|
|
|
|
|
public void changeCursor(Cursor cursor) {
|
|
|
|
|
// 调用父类的changeCursor方法,执行默认的Cursor变化处理
|
|
|
|
|
super.changeCursor(cursor);
|
|
|
|
|
// 调用calcNotesCount方法,重新计算笔记数量
|
|
|
|
|
calcNotesCount();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//定义一个私有方法,用于计算笔记数量
|
|
|
|
|
private void calcNotesCount() {
|
|
|
|
|
// 初始化笔记数量为0
|
|
|
|
|
mNotesCount = 0;
|
|
|
|
|
// 遍历所有的项目(从0到getCount()-1)
|
|
|
|
|
for (int i = 0; i < getCount(); i++) {
|
|
|
|
|
// 获取指定位置的项目,以Cursor对象的形式返回
|
|
|
|
|
Cursor c = (Cursor) getItem(i);
|
|
|
|
|
// 如果Cursor不为空
|
|
|
|
|
if (c != null) {
|
|
|
|
|
// 如果当前项目的类型为“笔记”(TYPE_NOTE),则笔记数量加1
|
|
|
|
|
if (NoteItemData.getNoteType(c) == Notes.TYPE_NOTE) {
|
|
|
|
|
mNotesCount++;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
// 如果Cursor为空,记录错误日志,并退出方法
|
|
|
|
|
Log.e(TAG, "Invalid cursor");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|