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.
git/java/net/micode/notes/ui/NotesListItem.java

277 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.
*/
// NotesListItem.java - 便签列表项自定义视图
// 主要功能:显示便签或文件夹列表项的完整视图,包括图标、文本、时间等
package net.micode.notes.ui;
// ======================= 导入区域 =======================
// Android基础
import android.content.Context; // 上下文
import android.text.format.DateUtils; // 日期工具,用于相对时间显示
// Android视图
import android.view.View; // 视图基类
// Android控件
import android.widget.CheckBox; // 复选框
import android.widget.ImageView; // 图片视图
import android.widget.LinearLayout; // 线性布局容器
import android.widget.TextView; // 文本视图
// 应用内部资源
import net.micode.notes.R; // 资源文件R类
// 应用数据模型
import net.micode.notes.data.Notes; // Notes主类
// 应用工具
import net.micode.notes.tool.DataUtils; // 数据工具
// 应用资源解析
import net.micode.notes.tool.ResourceParser.NoteItemBgResources; // 列表项背景资源
// ======================= 便签列表项视图 =======================
/**
* NotesListItem - 便签列表项自定义视图
* 继承自LinearLayout表示便签列表中的单个项
* 功能:显示便签/文件夹的完整信息,包括标题、时间、图标、背景等
* 职责:数据绑定、视图更新、背景选择
*/
public class NotesListItem extends LinearLayout {
// ======================= 成员变量 =======================
/** 提醒图标 - 显示便签是否有提醒 */
private ImageView mAlert;
/** 置顶图标 - 显示便签是否置顶 */
private ImageView mPinned;
/** 标题文本 - 显示便签摘要或文件夹名称 */
private TextView mTitle;
/** 时间文本 - 显示修改时间(相对时间) */
private TextView mTime;
/** 联系人姓名文本 - 通话记录专用,显示联系人姓名 */
private TextView mCallName;
/** 便签数据项 - 当前项绑定的数据 */
private NoteItemData mItemData;
/** 复选框 - 多选模式下显示,用于选择操作 */
private CheckBox mCheckBox;
// ======================= 构造函数 =======================
/**
* 构造函数
* 初始化列表项视图,加载布局并查找子视图
* @param context 上下文
*/
public NotesListItem(Context context) {
super(context);
// 1. 加载布局文件
// R.layout.note_item: 列表项布局
// 第三个参数true: 将布局添加到当前LinearLayout
inflate(context, R.layout.note_item, this);
// 2. 查找并保存子视图引用
mAlert = (ImageView) findViewById(R.id.iv_alert_icon);
mPinned = (ImageView) findViewById(R.id.iv_pinned_icon);
mTitle = (TextView) findViewById(R.id.tv_title);
mTime = (TextView) findViewById(R.id.tv_time);
mCallName = (TextView) findViewById(R.id.tv_name);
mCheckBox = (CheckBox) findViewById(android.R.id.checkbox);
}
// ======================= 数据绑定方法 =======================
/**
* 绑定数据到视图
* 根据便签数据类型和状态更新所有UI元素
* 绑定流程:
* 1. 处理选择模式复选框
* 2. 根据便签类型设置不同显示
* 3. 更新标题、时间、图标
* 4. 设置合适的背景
*
* @param context 上下文,用于获取资源和字符串
* @param data 便签数据项
* @param choiceMode 是否在选择模式中
* @param checked 该项是否被选中
*/
public void bind(Context context, NoteItemData data, boolean choiceMode, boolean checked) {
// 1. 处理选择模式复选框
if (choiceMode && data.getType() == Notes.TYPE_NOTE) {
// 选择模式且是便签类型:显示复选框
mCheckBox.setVisibility(View.VISIBLE);
mCheckBox.setChecked(checked);
} else {
// 非选择模式或非便签类型:隐藏复选框
mCheckBox.setVisibility(View.GONE);
}
// 保存数据引用
mItemData = data;
// 2. 根据便签类型设置不同显示
if (data.getId() == Notes.ID_CALL_RECORD_FOLDER) {
// 情况1通话记录文件夹
bindCallRecordFolder(context, data);
} else if (data.getParentId() == Notes.ID_CALL_RECORD_FOLDER) {
// 情况2通话记录文件夹中的便签
bindCallRecordNote(context, data);
} else {
// 情况3普通文件夹或便签
bindNormalItem(context, data);
}
// 3. 更新时间显示(所有类型都显示)
mTime.setText(DateUtils.getRelativeTimeSpanString(data.getModifiedDate()));
// 4. 设置背景
setBackground(data);
}
// ======================= 通话记录文件夹绑定 =======================
/**
* 绑定通话记录文件夹
* 特殊显示:文件夹图标 + 便签数量
* @param context 上下文
* @param data 文件夹数据
*/
private void bindCallRecordFolder(Context context, NoteItemData data) {
// 隐藏联系人姓名
mCallName.setVisibility(View.GONE);
// 显示提醒图标(文件夹图标)
mAlert.setVisibility(View.VISIBLE);
// 设置主标题样式
mTitle.setTextAppearance(context, R.style.TextAppearancePrimaryItem);
// 设置标题文本:文件夹名称 + 文件数量
mTitle.setText(context.getString(R.string.call_record_folder_name)
+ context.getString(R.string.format_folder_files_count, data.getNotesCount()));
// 设置文件夹图标
mAlert.setImageResource(R.drawable.call_record);
}
// ======================= 通话记录便签绑定 =======================
/**
* 绑定通话记录便签
* 特殊显示:联系人姓名 + 提醒图标
* @param context 上下文
* @param data 便签数据
*/
private void bindCallRecordNote(Context context, NoteItemData data) {
// 显示联系人姓名
mCallName.setVisibility(View.VISIBLE);
mCallName.setText(data.getCallName());
// 设置副标题样式
mTitle.setTextAppearance(context,R.style.TextAppearanceSecondaryItem);
// 设置标题文本(格式化摘要)
mTitle.setText(DataUtils.getFormattedSnippet(data.getSnippet()));
// 根据是否有提醒设置图标
if (data.hasAlert()) {
mAlert.setImageResource(R.drawable.clock);
mAlert.setVisibility(View.VISIBLE);
} else {
mAlert.setVisibility(View.GONE);
}
}
// ======================= 普通项绑定 =======================
/**
* 绑定普通文件夹或便签
* 通用显示逻辑
* @param context 上下文
* @param data 便签/文件夹数据
*/
private void bindNormalItem(Context context, NoteItemData data) {
// 隐藏联系人姓名
mCallName.setVisibility(View.GONE);
// 设置主标题样式
mTitle.setTextAppearance(context, R.style.TextAppearancePrimaryItem);
if (data.getType() == Notes.TYPE_FOLDER) {
// 文件夹:显示名称 + 文件数量
mTitle.setText(data.getSnippet()
+ context.getString(R.string.format_folder_files_count,
data.getNotesCount()));
mAlert.setVisibility(View.GONE); // 文件夹不显示提醒图标
} else {
// 普通便签:显示格式化摘要
mTitle.setText(DataUtils.getFormattedSnippet(data.getSnippet()));
// 根据是否有提醒设置图标
if (data.hasAlert()) {
mAlert.setImageResource(R.drawable.clock);
mAlert.setVisibility(View.VISIBLE);
} else {
mAlert.setVisibility(View.GONE);
}
// 根据是否置顶设置置顶图标
if (data.isPinned()) {
mPinned.setVisibility(View.VISIBLE);
} else {
mPinned.setVisibility(View.GONE);
}
}
}
// ======================= 背景设置 =======================
/**
* 设置列表项背景
* 根据便签类型和位置选择不同的背景图片
* 背景选择规则:
* 1. 便签:根据位置选择不同背景(首项、中间项、末项、单独项)
* 2. 文件夹:统一使用文件夹背景
*
* @param data 便签数据项
*/
private void setBackground(NoteItemData data) {
int id = data.getBgColorId(); // 获取背景颜色ID
if (data.getType() == Notes.TYPE_NOTE) {
// 便签类型:根据位置选择背景
if (data.isSingle() || data.isOneFollowingFolder()) {
// 单独项或文件夹后的唯一便签:单独项背景
setBackgroundResource(NoteItemBgResources.getNoteBgSingleRes(id));
} else if (data.isLast()) {
// 最后一项:底部圆角背景
setBackgroundResource(NoteItemBgResources.getNoteBgLastRes(id));
} else if (data.isFirst() || data.isMultiFollowingFolder()) {
// 第一项或文件夹后的多个便签之一:顶部圆角背景
setBackgroundResource(NoteItemBgResources.getNoteBgFirstRes(id));
} else {
// 中间项:普通直角背景
setBackgroundResource(NoteItemBgResources.getNoteBgNormalRes(id));
}
} else {
// 文件夹类型:统一使用文件夹背景
setBackgroundResource(NoteItemBgResources.getFolderBgRes());
}
}
// ======================= 数据获取方法 =======================
/**
* 获取便签数据项
* 用于获取当前视图绑定的数据
* @return 便签数据项
*/
public NoteItemData getItemData() {
return mItemData;
}
}