You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
2Q1/ui/NotesListAdapter.java

213 lines
11 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

/*
* 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;
// NotesListAdapter类继承自CursorAdapter用于适配数据库游标数据到视图以便在列表等控件中展示笔记相关的数据
public class NotesListAdapter extends CursorAdapter {
// 用于日志记录的标签,方便在日志输出中识别该类相关的日志信息
private static final String TAG = "NotesListAdapter";
// 保存上下文信息,用于后续创建视图、获取资源等操作
private Context mContext;
// 使用HashMap来记录每个位置索引对应的选中状态键为位置索引整数值为是否选中布尔值
private HashMap<Integer, Boolean> mSelectedIndex;
// 记录笔记的数量,用于一些判断和统计相关操作
private int mNotesCount;
// 表示当前是否处于选择模式例如多选模式等true表示处于选择模式false表示不在选择模式
private boolean mChoiceMode;
// 内部静态类用于封装桌面小部件App Widget的相关属性这里包含小部件的ID和类型两个属性
public static class AppWidgetAttribute {
public int widgetId;
public int widgetType;
};
// 构造函数用于初始化NotesListAdapter实例
public NotesListAdapter(Context context) {
// 调用父类CursorAdapter的构造函数传入上下文和初始游标这里传入null可能后续会通过其他方法设置游标
super(context, null);
// 初始化mSelectedIndex创建一个新的HashMap用于记录选中状态
mSelectedIndex = new HashMap<Integer, Boolean>();
// 保存传入的上下文信息
mContext = context;
// 初始化笔记数量为0
mNotesCount = 0;
}
// 该方法用于创建一个新的视图View在列表中每个数据项对应的视图需要通过此方法创建这里返回一个NotesListItem类型的新视图实例传入当前上下文作为参数来创建视图
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
return new NotesListItem(context);
}
// 该方法用于将游标中的数据绑定到已创建的视图上,使得视图能够展示对应的数据内容
@Override
public void bindView(View view, Context context, Cursor cursor) {
// 如果视图是NotesListItem类型的实例
if (view instanceof NotesListItem) {
// 根据传入的上下文和游标数据创建一个NoteItemData实例用于获取和解析具体的数据信息
NoteItemData itemData = new NoteItemData(context, cursor);
// 调用NotesListItem的bind方法将相关数据和状态传递给视图进行绑定展示包括上下文、笔记数据项、是否处于选择模式以及当前位置对应的选中状态等信息
((NotesListItem) view).bind(context, itemData, mChoiceMode,
isSelectedItem(cursor.getPosition()));
}
}
// 用于设置指定位置的选中状态将指定位置和对应的选中状态存入mSelectedIndex中并通知数据集已发生改变使得视图能够根据新的选中状态进行更新显示
public void setCheckedItem(final int position, final boolean checked) {
mSelectedIndex.put(position, checked);
notifyDataSetChanged();
}
// 用于判断当前是否处于选择模式返回mChoiceMode的值true表示处于选择模式false表示不在选择模式
public boolean isInChoiceMode() {
return mChoiceMode;
}
// 用于设置选择模式的开关当设置为选择模式时传入参数mode为true先清空之前的选中状态记录mSelectedIndex然后更新mChoiceMode的值
public void setChoiceMode(boolean mode) {
mSelectedIndex.clear();
mChoiceMode = mode;
}
// 用于全选或全不选所有笔记数据项根据传入的checked参数决定遍历游标中的所有数据项对于类型为笔记Notes.TYPE_NOTE的数据项调用setCheckedItem方法设置其选中状态
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用于存储Long类型的ID遍历mSelectedIndex中所有已选中的位置通过getItemId方法获取对应的数据项ID并添加到HashSet中同时对根文件夹IDNotes.ID_ROOT_FOLDER进行特殊判断和日志记录如果出现则认为是错误情况
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;
}
// 用于获取所有已选中的桌面小部件App Widget相关属性的集合创建一个HashSet用于存储AppWidgetAttribute实例遍历mSelectedIndex中所有已选中的位置通过getItem方法获取对应的数据项游标Cursor然后从中解析出小部件的ID和类型信息封装成AppWidgetAttribute实例添加到HashSet中同时对无效游标情况进行日志记录和错误处理如果游标为null则返回null
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;
}
// 用于获取已选中的数据项的数量获取mSelectedIndex中所有值布尔值表示选中状态的集合通过迭代器遍历该集合统计值为true即选中的数量并返回
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;
}
// 用于判断是否所有的数据项都已被选中通过比较已选中的数据项数量getSelectedCount方法获取和总笔记数量mNotesCount来判断当已选中数量不为0且等于总笔记数量时返回true表示全选状态否则返回false
public boolean isAllSelected() {
int checkedCount = getSelectedCount();
return (checkedCount!= 0 && checkedCount == mNotesCount);
}
// 用于判断指定位置的数据项是否被选中根据mSelectedIndex中对应位置的键值布尔值来判断如果对应位置的值为null则返回false表示未选中否则返回该位置对应的实际选中状态值
public boolean isSelectedItem(final int position) {
if (null == mSelectedIndex.get(position)) {
return false;
}
return mSelectedIndex.get(position);
}
// 当数据集内容发生改变时触发的回调方法这里先调用父类的onContentChanged方法执行默认操作然后调用calcNotesCount方法重新计算笔记的数量
@Override
protected void onContentChanged() {
super.onContentChanged();
calcNotesCount();
}
// 当游标Cursor发生改变时触发的回调方法这里先调用父类的changeCursor方法执行默认操作然后调用calcNotesCount方法重新计算笔记的数量
@Override
public void changeCursor(Cursor cursor) {
super.changeCursor(cursor);
calcNotesCount();
}
// 私有方法用于计算笔记的数量先将mNotesCount重置为0然后遍历所有数据项通过getCount方法获取数量获取对应位置的数据项游标判断其数据类型是否为笔记Notes.TYPE_NOTE如果是则数量加1同时对无效游标情况进行日志记录和错误处理如果游标为null则直接返回
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;
}
}
}
}