/* * 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 子类,用于将笔记数据(从数据库中获取的游标)绑定到视图(如 ListView)。 * 它管理笔记项的显示、选择模式以及选中的项。 */ 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; // 小部件ID public int widgetType; // 小部件类型 }; /** * 构造函数,初始化 NotesListAdapter。 * @param context 上下文 */ public NotesListAdapter(Context context) { super(context, null); mSelectedIndex = new HashMap(); // 初始化选中项的索引 mContext = context; mNotesCount = 0; // 初始化笔记数量 } /** * 创建新的视图用于展示数据项。 * @param context 上下文 * @param cursor 游标,指向数据库中的当前记录 * @param parent 父视图 * @return 新的视图 */ @Override public View newView(Context context, Cursor cursor, ViewGroup parent) { return new NotesListItem(context); // 返回自定义的列表项视图 } /** * 将数据绑定到视图上。 * @param view 当前的视图 * @param context 上下文 * @param cursor 当前游标,指向当前记录 */ @Override public void bindView(View view, Context context, Cursor cursor) { if (view instanceof NotesListItem) { // 使用游标数据创建 NoteItemData 对象 NoteItemData itemData = new NoteItemData(context, cursor); // 绑定数据到列表项视图 ((NotesListItem) view).bind(context, itemData, mChoiceMode, isSelectedItem(cursor.getPosition())); } } /** * 设置指定位置项的选中状态。 * @param position 项的位置 * @param checked 是否选中 */ public void setCheckedItem(final int position, final boolean checked) { mSelectedIndex.put(position, checked); // 更新选中状态 notifyDataSetChanged(); // 刷新数据集 } /** * 判断是否处于选择模式。 * @return 是否处于选择模式 */ public boolean isInChoiceMode() { return mChoiceMode; } /** * 设置选择模式。 * @param mode 是否开启选择模式 */ public void setChoiceMode(boolean mode) { mSelectedIndex.clear(); // 清除之前的选择状态 mChoiceMode = mode; // 更新选择模式 } /** * 全选或全不选。 * @param checked 是否选中所有项 */ 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 集合。 * @return 选中项的 ID 集合 */ public HashSet getSelectedItemIds() { HashSet itemSet = new HashSet(); // 遍历选中项索引,获取所有选中的项的 ID for (Integer position : mSelectedIndex.keySet()) { if (mSelectedIndex.get(position) == true) { Long id = getItemId(position); // 排除根文件夹项的 ID if (id == Notes.ID_ROOT_FOLDER) { Log.d(TAG, "Wrong item id, should not happen"); } else { itemSet.add(id); // 添加到集合中 } } } return itemSet; } /** * 获取当前选中的小部件集合。 * @return 选中的小部件集合 */ 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); } else { Log.e(TAG, "Invalid cursor"); return null; // 如果游标无效,返回 null } } } return itemSet; } /** * 获取选中的项数。 * @return 选中的项数 */ public int getSelectedCount() { Collection values = mSelectedIndex.values(); if (null == values) { return 0; // 如果没有选中项,返回 0 } Iterator iter = values.iterator(); int count = 0; // 统计选中的项数 while (iter.hasNext()) { if (true == iter.next()) { count++; } } return count; } /** * 判断是否所有项都已选中。 * @return 是否所有项都选中 */ public boolean isAllSelected() { int checkedCount = getSelectedCount(); return (checkedCount != 0 && checkedCount == mNotesCount); // 如果选中的项数等于总项数,返回 true } /** * 判断指定位置的项是否被选中。 * @param position 项的位置 * @return 是否选中 */ public boolean isSelectedItem(final int position) { if (null == mSelectedIndex.get(position)) { return false; // 如果没有记录选中状态,则返回 false } return mSelectedIndex.get(position); // 返回选中状态 } /** * 当内容发生变化时,调用该方法来重新计算笔记数量。 */ @Override protected void onContentChanged() { super.onContentChanged(); calcNotesCount(); // 重新计算笔记数量 } /** * 更改游标时,重新计算笔记数量。 * @param cursor 新的游标 */ @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; } } } }