|
|
|
|
@ -33,12 +33,8 @@ import android.preference.PreferenceManager;
|
|
|
|
|
import android.text.Spannable;
|
|
|
|
|
import android.text.SpannableString;
|
|
|
|
|
import android.text.TextUtils;
|
|
|
|
|
import android.text.Html;
|
|
|
|
|
import android.text.format.DateUtils;
|
|
|
|
|
import android.text.style.BackgroundColorSpan;
|
|
|
|
|
import android.text.style.StyleSpan;
|
|
|
|
|
import android.text.style.UnderlineSpan;
|
|
|
|
|
import android.graphics.Typeface;
|
|
|
|
|
import android.util.Log;
|
|
|
|
|
import android.view.LayoutInflater;
|
|
|
|
|
import android.view.Menu;
|
|
|
|
|
@ -68,7 +64,16 @@ import android.content.ContentResolver;
|
|
|
|
|
import android.content.res.Resources;
|
|
|
|
|
import android.graphics.Bitmap;
|
|
|
|
|
import android.graphics.BitmapFactory;
|
|
|
|
|
import android.graphics.Color;
|
|
|
|
|
import java.io.InputStream;
|
|
|
|
|
import java.io.FileOutputStream;
|
|
|
|
|
import java.io.OutputStream;
|
|
|
|
|
import android.os.Environment;
|
|
|
|
|
import android.text.format.DateUtils;
|
|
|
|
|
import android.view.ViewGroup;
|
|
|
|
|
import android.content.ActivityNotFoundException;
|
|
|
|
|
|
|
|
|
|
import jp.wasabeef.richeditor.RichEditor;
|
|
|
|
|
|
|
|
|
|
import net.micode.notes.R;
|
|
|
|
|
import net.micode.notes.data.Notes;
|
|
|
|
|
@ -161,22 +166,20 @@ public class NoteEditActivity extends Activity implements OnClickListener,
|
|
|
|
|
|
|
|
|
|
private static final String TAG = "NoteEditActivity"; // 日志标签
|
|
|
|
|
private static final int REQUEST_CODE_PICK_IMAGE = 100; // 图片选择请求码 OMO
|
|
|
|
|
private static final int PHOTO_REQUEST = 100; // 请求照片
|
|
|
|
|
|
|
|
|
|
private HeadViewHolder mNoteHeaderHolder; // 头部视图持有者
|
|
|
|
|
private View mHeadViewPanel; // 头部视图面板
|
|
|
|
|
private View mNoteBgColorSelector; // 背景颜色选择器
|
|
|
|
|
private View mFontSizeSelector; // 字体大小选择器
|
|
|
|
|
private EditText mNoteEditor; // 笔记编辑器
|
|
|
|
|
private RichEditor mNoteEditor; // 富文本编辑器
|
|
|
|
|
private View mNoteEditorPanel; // 笔记编辑器面板
|
|
|
|
|
private WorkingNote mWorkingNote; // 工作笔记对象
|
|
|
|
|
private SharedPreferences mSharedPrefs; // 共享偏好设置
|
|
|
|
|
private int mFontSizeId; // 字体大小ID
|
|
|
|
|
private ImageButton mBtnInsertImage; // 插入图片按钮 OMO
|
|
|
|
|
|
|
|
|
|
// 富文本工具栏按钮
|
|
|
|
|
private ImageButton mBtnBold; // 加粗按钮
|
|
|
|
|
private ImageButton mBtnItalic; // 斜体按钮
|
|
|
|
|
private ImageButton mBtnUnderline; // 下划线按钮
|
|
|
|
|
private String mText; // 用于存储富文本内容
|
|
|
|
|
private int mNoteLength; // 文本长度
|
|
|
|
|
|
|
|
|
|
private static final String PREFERENCE_FONT_SIZE = "pref_font_size"; // 字体大小偏好设置键
|
|
|
|
|
private static final int SHORTCUT_ICON_TITLE_MAX_LEN = 10; // 快捷图标标题最大长度
|
|
|
|
|
@ -348,96 +351,64 @@ public class NoteEditActivity extends Activity implements OnClickListener,
|
|
|
|
|
* 设置笔记编辑器的文本外观、内容和选择模式
|
|
|
|
|
*/
|
|
|
|
|
private void initNoteScreen() {
|
|
|
|
|
// 设置笔记编辑器的文本外观
|
|
|
|
|
mNoteEditor.setTextAppearance(this, TextAppearanceResources
|
|
|
|
|
.getTexAppearanceResource(mFontSizeId));
|
|
|
|
|
// 检查必要的视图是否已初始化
|
|
|
|
|
if (mHeadViewPanel == null || mNoteEditorPanel == null || mNoteEditor == null) {
|
|
|
|
|
Log.e(TAG, "Some views are not initialized! Check initResources method.");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 设置富文本编辑器字体大小
|
|
|
|
|
setRichEditorFontSize(mFontSizeId);
|
|
|
|
|
|
|
|
|
|
// 根据笔记模式设置显示方式
|
|
|
|
|
if (mWorkingNote.getCheckListMode() == TextNote.MODE_CHECK_LIST) {
|
|
|
|
|
switchToListMode(mWorkingNote.getContent()); // 切换到清单模式
|
|
|
|
|
mNoteEditor.setVisibility(View.GONE);
|
|
|
|
|
mEditTextList.setVisibility(View.VISIBLE);
|
|
|
|
|
} else {
|
|
|
|
|
// 设置笔记内容并高亮查询结果
|
|
|
|
|
String content = mWorkingNote.getContent();
|
|
|
|
|
Log.d(TAG, "Initializing note content: " + content);
|
|
|
|
|
// 切换到富文本模式
|
|
|
|
|
mEditTextList.setVisibility(View.GONE);
|
|
|
|
|
mNoteEditor.setVisibility(View.VISIBLE);
|
|
|
|
|
|
|
|
|
|
// 获取笔记原始内容(为空则赋空字符串,避免空指针)
|
|
|
|
|
String content = mWorkingNote.getContent() == null ? "" : mWorkingNote.getContent();
|
|
|
|
|
|
|
|
|
|
if (TextUtils.isEmpty(content)) {
|
|
|
|
|
mNoteEditor.setText("");
|
|
|
|
|
mNoteEditor.setSelection(0);
|
|
|
|
|
} else {
|
|
|
|
|
Spannable spannable;
|
|
|
|
|
|
|
|
|
|
// 检查是否是HTML格式(包含HTML标签)
|
|
|
|
|
if (content.contains("<") && content.contains(">")) {
|
|
|
|
|
try {
|
|
|
|
|
// 从HTML格式恢复SpannableString,保留样式(加粗、斜体、下划线)
|
|
|
|
|
// Html.fromHtml会自动将HTML标签转换为对应的Span
|
|
|
|
|
spannable = (Spannable) Html.fromHtml(content);
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
// 如果HTML解析失败,使用普通文本
|
|
|
|
|
Log.e(TAG, "Error parsing HTML content: " + e.getMessage());
|
|
|
|
|
spannable = new SpannableString(content);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
// 普通文本格式,直接创建SpannableString
|
|
|
|
|
spannable = new SpannableString(content);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 处理图片:将包含[IMAGE]标签的文本转换为包含ImageSpan的SpannableString
|
|
|
|
|
// 注意:convertTextToSpannableWithImages会处理[IMAGE]标记,但会保留文本内容
|
|
|
|
|
String textContent = spannable.toString();
|
|
|
|
|
SpannableString finalSpannable = convertTextToSpannableWithImages(textContent);
|
|
|
|
|
|
|
|
|
|
// 将样式从原始Spannable复制到处理后的SpannableString
|
|
|
|
|
// 由于convertTextToSpannableWithImages可能改变了文本长度(用空格替换了[IMAGE]标签),
|
|
|
|
|
// 我们需要基于文本内容来映射样式位置
|
|
|
|
|
if (textContent.length() == finalSpannable.length()) {
|
|
|
|
|
// 文本长度相同,直接复制样式
|
|
|
|
|
StyleSpan[] styleSpans = spannable.getSpans(0, spannable.length(), StyleSpan.class);
|
|
|
|
|
UnderlineSpan[] underlineSpans = spannable.getSpans(0, spannable.length(), UnderlineSpan.class);
|
|
|
|
|
|
|
|
|
|
for (StyleSpan span : styleSpans) {
|
|
|
|
|
int start = spannable.getSpanStart(span);
|
|
|
|
|
int end = spannable.getSpanEnd(span);
|
|
|
|
|
if (start >= 0 && end <= finalSpannable.length() && start < end) {
|
|
|
|
|
finalSpannable.setSpan(new StyleSpan(span.getStyle()), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (UnderlineSpan span : underlineSpans) {
|
|
|
|
|
int start = spannable.getSpanStart(span);
|
|
|
|
|
int end = spannable.getSpanEnd(span);
|
|
|
|
|
if (start >= 0 && end <= finalSpannable.length() && start < end) {
|
|
|
|
|
finalSpannable.setSpan(new UnderlineSpan(), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
// 文本长度不同,说明有图片被处理了
|
|
|
|
|
// 这种情况下,样式位置需要重新计算
|
|
|
|
|
// 为了简化,我们基于原始文本位置映射样式(可能会有偏差,但应该能处理大部分情况)
|
|
|
|
|
StyleSpan[] styleSpans = spannable.getSpans(0, spannable.length(), StyleSpan.class);
|
|
|
|
|
UnderlineSpan[] underlineSpans = spannable.getSpans(0, spannable.length(), UnderlineSpan.class);
|
|
|
|
|
|
|
|
|
|
for (StyleSpan span : styleSpans) {
|
|
|
|
|
int start = Math.max(0, Math.min(spannable.getSpanStart(span), finalSpannable.length()));
|
|
|
|
|
int end = Math.max(start, Math.min(spannable.getSpanEnd(span), finalSpannable.length()));
|
|
|
|
|
if (start < end) {
|
|
|
|
|
finalSpannable.setSpan(new StyleSpan(span.getStyle()), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (UnderlineSpan span : underlineSpans) {
|
|
|
|
|
int start = Math.max(0, Math.min(spannable.getSpanStart(span), finalSpannable.length()));
|
|
|
|
|
int end = Math.max(start, Math.min(spannable.getSpanEnd(span), finalSpannable.length()));
|
|
|
|
|
if (start < end) {
|
|
|
|
|
finalSpannable.setSpan(new UnderlineSpan(), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|
|
|
|
|
// 检查内容是否已经是HTML格式,如果是则直接加载
|
|
|
|
|
String finalHtml = content;
|
|
|
|
|
|
|
|
|
|
// 如果内容不是HTML格式(比如旧笔记),则处理图片标记
|
|
|
|
|
if (!TextUtils.isEmpty(content) && (!content.startsWith("<") || !content.contains("</"))) {
|
|
|
|
|
// 处理 [IMAGE] 标签,转换为 HTML img 标签
|
|
|
|
|
Pattern imgPattern = Pattern.compile("\\[IMAGE\\]([^\\[]+)\\[/IMAGE\\]");
|
|
|
|
|
Matcher imgMatcher = imgPattern.matcher(content);
|
|
|
|
|
StringBuffer htmlContent = new StringBuffer();
|
|
|
|
|
// 遍历替换所有[IMAGE]标记为<img>标签
|
|
|
|
|
while (imgMatcher.find()) {
|
|
|
|
|
String imgUri = imgMatcher.group(1); // 提取图片URI
|
|
|
|
|
// 检查是否为本地文件路径
|
|
|
|
|
if (imgUri.startsWith("file://") || imgUri.startsWith("/")) {
|
|
|
|
|
String imgPath = imgUri.startsWith("file://") ? imgUri.substring(7) : imgUri;
|
|
|
|
|
File imgFile = new File(imgPath);
|
|
|
|
|
if (imgFile.exists() && imgFile.isFile()) {
|
|
|
|
|
String imgHtmlUrl = "file://" + imgPath;
|
|
|
|
|
String imgHtmlTag = "<img src=\"" + imgHtmlUrl + "\" width=\"200\" height=\"200\"/><br/>";
|
|
|
|
|
imgMatcher.appendReplacement(htmlContent, imgHtmlTag);
|
|
|
|
|
} else {
|
|
|
|
|
// 如果文件不存在,保留原标记
|
|
|
|
|
imgMatcher.appendReplacement(htmlContent, imgMatcher.group(0));
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
// URI格式,直接使用
|
|
|
|
|
String imgHtmlTag = "<img src=\"" + imgUri + "\" width=\"200\" height=\"200\"/><br/>";
|
|
|
|
|
imgMatcher.appendReplacement(htmlContent, imgHtmlTag);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
mNoteEditor.setText(finalSpannable);
|
|
|
|
|
// 将光标定位到文本末尾
|
|
|
|
|
mNoteEditor.setSelection(finalSpannable.length());
|
|
|
|
|
imgMatcher.appendTail(htmlContent); // 拼接剩余文本
|
|
|
|
|
finalHtml = htmlContent.toString();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 用RichEditor加载HTML内容
|
|
|
|
|
mNoteEditor.setHtml(finalHtml);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 隐藏所有背景选择的选中状态
|
|
|
|
|
@ -641,7 +612,36 @@ public class NoteEditActivity extends Activity implements OnClickListener,
|
|
|
|
|
mNoteHeaderHolder.tvAlertDate = (TextView) findViewById(R.id.tv_alert_date);
|
|
|
|
|
mNoteHeaderHolder.ibSetBgColor = (ImageView) findViewById(R.id.btn_set_bg_color);
|
|
|
|
|
mNoteHeaderHolder.ibSetBgColor.setOnClickListener(this);
|
|
|
|
|
mNoteEditor = (EditText) findViewById(R.id.note_edit_view);
|
|
|
|
|
// 初始化富文本编辑器
|
|
|
|
|
mNoteEditor = (RichEditor) findViewById(R.id.note_edit_view);
|
|
|
|
|
if (mNoteEditor == null) {
|
|
|
|
|
Log.e(TAG, "RichEditor is null! Check layout file.");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 初始化富文本编辑器配置
|
|
|
|
|
initRichEditor();
|
|
|
|
|
|
|
|
|
|
// 设置富文本编辑器监听器
|
|
|
|
|
mNoteEditor.setOnTextChangeListener(new RichEditor.OnTextChangeListener() {
|
|
|
|
|
@Override
|
|
|
|
|
public void onTextChange(String text) {
|
|
|
|
|
mText = text;
|
|
|
|
|
mNoteLength = text.length();
|
|
|
|
|
// 更新修改时间和字符数显示
|
|
|
|
|
mNoteHeaderHolder.tvModified.setText(
|
|
|
|
|
DateUtils.formatDateTime(NoteEditActivity.this,
|
|
|
|
|
mWorkingNote.getModifiedDate(),
|
|
|
|
|
DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_NUMERIC_DATE
|
|
|
|
|
| DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_SHOW_YEAR)
|
|
|
|
|
+ "\n字符数:" + mNoteLength
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// 开启图文混排支持
|
|
|
|
|
mNoteEditor.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
|
|
|
|
|
|
|
|
|
|
mNoteEditorPanel = findViewById(R.id.sv_note_edit);
|
|
|
|
|
mNoteBgColorSelector = findViewById(R.id.note_bg_color_selector);
|
|
|
|
|
|
|
|
|
|
@ -680,21 +680,8 @@ public class NoteEditActivity extends Activity implements OnClickListener,
|
|
|
|
|
mBtnInsertImage.setOnClickListener(this);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 初始化富文本工具栏按钮
|
|
|
|
|
mBtnBold = (ImageButton) findViewById(R.id.btn_bold);
|
|
|
|
|
mBtnItalic = (ImageButton) findViewById(R.id.btn_italic);
|
|
|
|
|
mBtnUnderline = (ImageButton) findViewById(R.id.btn_underline);
|
|
|
|
|
|
|
|
|
|
// 为富文本工具栏按钮设置点击监听器
|
|
|
|
|
if (mBtnBold != null) {
|
|
|
|
|
mBtnBold.setOnClickListener(this);
|
|
|
|
|
}
|
|
|
|
|
if (mBtnItalic != null) {
|
|
|
|
|
mBtnItalic.setOnClickListener(this);
|
|
|
|
|
}
|
|
|
|
|
if (mBtnUnderline != null) {
|
|
|
|
|
mBtnUnderline.setOnClickListener(this);
|
|
|
|
|
}
|
|
|
|
|
// 初始化富文本功能按钮
|
|
|
|
|
initRichEditorButtons();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@ -765,22 +752,13 @@ public class NoteEditActivity extends Activity implements OnClickListener,
|
|
|
|
|
getWorkingText();
|
|
|
|
|
switchToListMode(mWorkingNote.getContent());
|
|
|
|
|
} else {
|
|
|
|
|
mNoteEditor.setTextAppearance(this,
|
|
|
|
|
TextAppearanceResources.getTexAppearanceResource(mFontSizeId));
|
|
|
|
|
// 设置富文本编辑器字体大小
|
|
|
|
|
setRichEditorFontSize(mFontSizeId);
|
|
|
|
|
}
|
|
|
|
|
mFontSizeSelector.setVisibility(View.GONE);
|
|
|
|
|
} else if (id == R.id.btn_insert_image) {
|
|
|
|
|
// 处理插入图片按钮点击事件 OMO
|
|
|
|
|
pickImageFromGallery();
|
|
|
|
|
} else if (id == R.id.btn_bold) {
|
|
|
|
|
// 富文本工具栏 - 加粗按钮
|
|
|
|
|
applyBoldStyle();
|
|
|
|
|
} else if (id == R.id.btn_italic) {
|
|
|
|
|
// 富文本工具栏 - 斜体按钮
|
|
|
|
|
applyItalicStyle();
|
|
|
|
|
} else if (id == R.id.btn_underline) {
|
|
|
|
|
// 富文本工具栏 - 下划线按钮
|
|
|
|
|
applyUnderlineStyle();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -969,7 +947,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
|
|
|
|
|
}
|
|
|
|
|
if (!isSyncMode()) {
|
|
|
|
|
// 非同步模式下直接删除
|
|
|
|
|
if (!DataUtils.batchDeleteNotes(getContentResolver(), ids)) {
|
|
|
|
|
if (!DataUtils.batchDeleteNotes(getContentResolver(), ids, NoteEditActivity.this)) {
|
|
|
|
|
Log.e(TAG, "Delete Note error");
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
@ -1007,7 +985,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
|
|
|
|
|
if (mWorkingNote.getNoteId() > 0) {
|
|
|
|
|
Intent intent = new Intent(this, AlarmReceiver.class);
|
|
|
|
|
intent.setData(ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, mWorkingNote.getNoteId()));
|
|
|
|
|
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, 0);
|
|
|
|
|
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_IMMUTABLE);
|
|
|
|
|
AlarmManager alarmManager = ((AlarmManager) getSystemService(ALARM_SERVICE));
|
|
|
|
|
showAlertHeader();
|
|
|
|
|
if(!set) {
|
|
|
|
|
@ -1221,8 +1199,9 @@ public class NoteEditActivity extends Activity implements OnClickListener,
|
|
|
|
|
String text = "";
|
|
|
|
|
if (newMode == TextNote.MODE_CHECK_LIST) {
|
|
|
|
|
// 安全获取文本,避免空指针异常(OMO)
|
|
|
|
|
if (mNoteEditor.getText() != null) {
|
|
|
|
|
text = mNoteEditor.getText().toString();
|
|
|
|
|
String htmlContent = mNoteEditor.getHtml();
|
|
|
|
|
if (htmlContent != null) {
|
|
|
|
|
text = htmlContent;
|
|
|
|
|
}
|
|
|
|
|
switchToListMode(text);
|
|
|
|
|
} else {
|
|
|
|
|
@ -1232,12 +1211,35 @@ public class NoteEditActivity extends Activity implements OnClickListener,
|
|
|
|
|
mWorkingNote.setWorkingText(content.replace(TAG_UNCHECKED + " ", ""));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
String content = mWorkingNote.getContent();
|
|
|
|
|
if (content != null) {
|
|
|
|
|
mNoteEditor.setText(getHighlightQueryResult(content, mUserQuery));
|
|
|
|
|
} else {
|
|
|
|
|
mNoteEditor.setText("");
|
|
|
|
|
String content = mWorkingNote.getContent() == null ? "" : mWorkingNote.getContent();
|
|
|
|
|
// 处理内容为HTML格式
|
|
|
|
|
String finalHtml = content;
|
|
|
|
|
if (!TextUtils.isEmpty(content) && (!content.startsWith("<") || !content.contains("</"))) {
|
|
|
|
|
// 处理 [IMAGE] 标签
|
|
|
|
|
Pattern imgPattern = Pattern.compile("\\[IMAGE\\]([^\\[]+)\\[/IMAGE\\]");
|
|
|
|
|
Matcher imgMatcher = imgPattern.matcher(content);
|
|
|
|
|
StringBuffer htmlContent = new StringBuffer();
|
|
|
|
|
while (imgMatcher.find()) {
|
|
|
|
|
String imgUri = imgMatcher.group(1);
|
|
|
|
|
if (imgUri.startsWith("file://") || imgUri.startsWith("/")) {
|
|
|
|
|
String imgPath = imgUri.startsWith("file://") ? imgUri.substring(7) : imgUri;
|
|
|
|
|
File imgFile = new File(imgPath);
|
|
|
|
|
if (imgFile.exists() && imgFile.isFile()) {
|
|
|
|
|
String imgHtmlUrl = "file://" + imgPath;
|
|
|
|
|
String imgHtmlTag = "<img src=\"" + imgHtmlUrl + "\" width=\"200\" height=\"200\"/><br/>";
|
|
|
|
|
imgMatcher.appendReplacement(htmlContent, imgHtmlTag);
|
|
|
|
|
} else {
|
|
|
|
|
imgMatcher.appendReplacement(htmlContent, imgMatcher.group(0));
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
String imgHtmlTag = "<img src=\"" + imgUri + "\" width=\"200\" height=\"200\"/><br/>";
|
|
|
|
|
imgMatcher.appendReplacement(htmlContent, imgHtmlTag);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
imgMatcher.appendTail(htmlContent);
|
|
|
|
|
finalHtml = htmlContent.toString();
|
|
|
|
|
}
|
|
|
|
|
mNoteEditor.setHtml(finalHtml);
|
|
|
|
|
mEditTextList.setVisibility(View.GONE);
|
|
|
|
|
mNoteEditor.setVisibility(View.VISIBLE);
|
|
|
|
|
}
|
|
|
|
|
@ -1266,16 +1268,10 @@ public class NoteEditActivity extends Activity implements OnClickListener,
|
|
|
|
|
}
|
|
|
|
|
mWorkingNote.setWorkingText(sb.toString());
|
|
|
|
|
} else {
|
|
|
|
|
// 保存时,将SpannableString转换为HTML格式以保留样式信息
|
|
|
|
|
Spannable spannable = mNoteEditor.getText();
|
|
|
|
|
if (spannable != null && spannable.length() > 0) {
|
|
|
|
|
// 将Spannable转换为HTML格式,保留加粗、斜体、下划线等样式
|
|
|
|
|
// Html.toHtml会自动处理StyleSpan和UnderlineSpan
|
|
|
|
|
String htmlContent = Html.toHtml(spannable);
|
|
|
|
|
mWorkingNote.setWorkingText(htmlContent);
|
|
|
|
|
} else {
|
|
|
|
|
mWorkingNote.setWorkingText("");
|
|
|
|
|
}
|
|
|
|
|
// 确保获取最新的富文本内容
|
|
|
|
|
String currentHtml = mNoteEditor.getHtml();
|
|
|
|
|
mWorkingNote.setWorkingText(currentHtml);
|
|
|
|
|
mText = currentHtml; // 更新mText变量,确保保存时使用最新内容
|
|
|
|
|
}
|
|
|
|
|
return hasChecked;
|
|
|
|
|
}
|
|
|
|
|
@ -1373,8 +1369,22 @@ public class NoteEditActivity extends Activity implements OnClickListener,
|
|
|
|
|
* 从相册选择图片 OMO
|
|
|
|
|
*/
|
|
|
|
|
private void pickImageFromGallery() {
|
|
|
|
|
Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
|
|
|
|
|
startActivityForResult(intent, REQUEST_CODE_PICK_IMAGE);
|
|
|
|
|
try {
|
|
|
|
|
// 意图:打开系统相册选择图片
|
|
|
|
|
Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
|
|
|
|
|
intent.setType("image/*"); // 只显示图片类型
|
|
|
|
|
startActivityForResult(intent, PHOTO_REQUEST); // 启动相册,等待返回结果
|
|
|
|
|
} catch (ActivityNotFoundException e) {
|
|
|
|
|
// 如果没有相册应用,尝试使用通用选择器
|
|
|
|
|
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
|
|
|
|
|
intent.setType("image/*");
|
|
|
|
|
try {
|
|
|
|
|
startActivityForResult(intent, PHOTO_REQUEST);
|
|
|
|
|
} catch (ActivityNotFoundException ex) {
|
|
|
|
|
showToast(R.string.error_note_not_exist);
|
|
|
|
|
Log.e(TAG, "No image picker available", ex);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@ -1383,204 +1393,177 @@ public class NoteEditActivity extends Activity implements OnClickListener,
|
|
|
|
|
@Override
|
|
|
|
|
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
|
|
|
|
super.onActivityResult(requestCode, resultCode, data);
|
|
|
|
|
if (requestCode == REQUEST_CODE_PICK_IMAGE && resultCode == RESULT_OK && data != null) {
|
|
|
|
|
Log.d(TAG, "Image selected successfully, data: " + data.toString());
|
|
|
|
|
Uri imageUri = data.getData();
|
|
|
|
|
if (imageUri != null) {
|
|
|
|
|
Log.d(TAG, "Image URI: " + imageUri.toString());
|
|
|
|
|
try {
|
|
|
|
|
// 将图片路径添加到笔记内容中
|
|
|
|
|
String currentContent = mNoteEditor.getText().toString();
|
|
|
|
|
String imagePath = "[IMAGE]" + imageUri.toString() + "[/IMAGE]";
|
|
|
|
|
String newContent = currentContent + (currentContent.isEmpty() ? "" : "\n") + imagePath;
|
|
|
|
|
Log.d(TAG, "New content: " + newContent);
|
|
|
|
|
|
|
|
|
|
// 直接设置文本,不使用ImageSpan,这样可以确保内容被保存
|
|
|
|
|
mNoteEditor.setText(newContent);
|
|
|
|
|
mNoteEditor.setSelection(newContent.length());
|
|
|
|
|
|
|
|
|
|
// 保存笔记内容,确保图片路径被正确存储
|
|
|
|
|
saveNote();
|
|
|
|
|
showToast(R.string.info_image_inserted);
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
Log.e(TAG, "Error inserting image: " + e.toString());
|
|
|
|
|
showToast(R.string.error_note_not_exist);
|
|
|
|
|
if (requestCode == PHOTO_REQUEST && resultCode == RESULT_OK && data != null) {
|
|
|
|
|
Uri uri = data.getData();
|
|
|
|
|
String localImagePath = saveImageToLocal(uri);
|
|
|
|
|
if (localImagePath == null) return; // 保存失败就退出
|
|
|
|
|
|
|
|
|
|
// 核心修改:适配RichEditor,替换EditText的ImageSpan逻辑
|
|
|
|
|
// 1. 拼接RichEditor支持的<img>标签(必须加file://前缀)
|
|
|
|
|
String imgUrl = "file://" + localImagePath;
|
|
|
|
|
String imgHtmlTag = "<img src=\"" + imgUrl + "\" width=\"200\" height=\"200\"/><br/>";
|
|
|
|
|
// 2. 插入图片到RichEditor
|
|
|
|
|
String curHtml = mNoteEditor.getHtml(); // 获取当前内容
|
|
|
|
|
String newHtml = curHtml + imgHtmlTag; // 追加图片标签
|
|
|
|
|
mNoteEditor.setHtml(newHtml); // 重新设置内容,实现插入
|
|
|
|
|
|
|
|
|
|
// 弹窗依然保留
|
|
|
|
|
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
|
|
|
|
builder.setTitle("图片选择成功!");
|
|
|
|
|
|
|
|
|
|
ImageView imageView = new ImageView(this);
|
|
|
|
|
imageView.setLayoutParams(new ViewGroup.LayoutParams(
|
|
|
|
|
ViewGroup.LayoutParams.MATCH_PARENT,
|
|
|
|
|
ViewGroup.LayoutParams.WRAP_CONTENT)); // 加布局参数,避免图片显示不全
|
|
|
|
|
imageView.setImageURI(Uri.fromFile(new File(localImagePath)));//弹窗也显示本地图片
|
|
|
|
|
imageView.setScaleType(ImageView.ScaleType.FIT_CENTER); // 适配图片大小
|
|
|
|
|
builder.setView(imageView);
|
|
|
|
|
|
|
|
|
|
builder.setPositiveButton("确认保存", (dialog, which) -> {
|
|
|
|
|
String currentHtml = mNoteEditor.getHtml(); // 替换原EditText的getText()
|
|
|
|
|
String newContent = mWorkingNote.getContent() == null ? "" : mWorkingNote.getContent();
|
|
|
|
|
newContent += "\n[IMAGE]" + localImagePath + "[/IMAGE]"; // 保留原有[IMAGE]标记,供后续加载解析
|
|
|
|
|
Log.d("NoteDebug", "准备保存的内容:" + newContent); // 看Logcat里的输出
|
|
|
|
|
|
|
|
|
|
// 执行保存操作
|
|
|
|
|
mWorkingNote.setWorkingText(newContent);
|
|
|
|
|
boolean isSaved = mWorkingNote.saveNote();
|
|
|
|
|
|
|
|
|
|
// 根据保存结果提示(更友好)
|
|
|
|
|
if (isSaved) {
|
|
|
|
|
Toast.makeText(this, "图片信息已保存!", Toast.LENGTH_SHORT).show();
|
|
|
|
|
} else {
|
|
|
|
|
Toast.makeText(this, "保存失败,请重试", Toast.LENGTH_SHORT).show();
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
Log.e(TAG, "Image URI is null");
|
|
|
|
|
showToast(R.string.error_note_not_exist);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
Log.d(TAG, "Image selection canceled or failed, resultCode: " + resultCode);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 应用文本样式(加粗、斜体、下划线)
|
|
|
|
|
* @param styleType 样式类型:Typeface.BOLD, Typeface.ITALIC, 或 -1 表示下划线
|
|
|
|
|
*/
|
|
|
|
|
private void applyTextStyle(int styleType) {
|
|
|
|
|
if (mNoteEditor == null) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 检查是否在清单模式,如果是则提示用户切换到普通模式
|
|
|
|
|
if (mWorkingNote.getCheckListMode() == TextNote.MODE_CHECK_LIST) {
|
|
|
|
|
showToast(R.string.error_formatting_not_supported_in_list_mode);
|
|
|
|
|
return;
|
|
|
|
|
builder.show();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Editable editable = mNoteEditor.getText();
|
|
|
|
|
if (editable == null) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int selectionStart = mNoteEditor.getSelectionStart();
|
|
|
|
|
int selectionEnd = mNoteEditor.getSelectionEnd();
|
|
|
|
|
|
|
|
|
|
// 如果没有选中文本,则选中光标所在的单词或当前字符
|
|
|
|
|
if (selectionStart == selectionEnd) {
|
|
|
|
|
// 尝试选中光标所在的单词
|
|
|
|
|
String text = editable.toString();
|
|
|
|
|
int start = selectionStart;
|
|
|
|
|
int end = selectionEnd;
|
|
|
|
|
|
|
|
|
|
// 向前查找单词开始位置
|
|
|
|
|
while (start > 0 && Character.isLetterOrDigit(text.charAt(start - 1))) {
|
|
|
|
|
start--;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 向后查找单词结束位置
|
|
|
|
|
while (end < text.length() && Character.isLetterOrDigit(text.charAt(end))) {
|
|
|
|
|
end++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 如果找到了单词,则选中它;否则选中当前字符
|
|
|
|
|
if (start < end) {
|
|
|
|
|
selectionStart = start;
|
|
|
|
|
selectionEnd = end;
|
|
|
|
|
mNoteEditor.setSelection(selectionStart, selectionEnd);
|
|
|
|
|
} else {
|
|
|
|
|
// 如果没有找到单词,提示用户先选择文本
|
|
|
|
|
showToast(R.string.error_please_select_text);
|
|
|
|
|
return;
|
|
|
|
|
// 新增工具方法:把临时URI的图片复制到应用私有目录,返回真实路径
|
|
|
|
|
private String saveImageToLocal(Uri uri) {
|
|
|
|
|
try {
|
|
|
|
|
// 1. 创建应用专属图片目录(不会被系统清理)
|
|
|
|
|
File appDir = new File(getExternalFilesDir(Environment.DIRECTORY_PICTURES), "note_images");
|
|
|
|
|
if (!appDir.exists()) appDir.mkdirs();
|
|
|
|
|
|
|
|
|
|
// 2. 生成唯一文件名(避免重复)
|
|
|
|
|
String fileName = "note_" + System.currentTimeMillis() + ".jpg";
|
|
|
|
|
File targetFile = new File(appDir, fileName);
|
|
|
|
|
|
|
|
|
|
// 3. 复制图片文件(从临时URI到本地目录)
|
|
|
|
|
InputStream is = getContentResolver().openInputStream(uri);
|
|
|
|
|
OutputStream os = new FileOutputStream(targetFile);
|
|
|
|
|
byte[] buffer = new byte[1024];
|
|
|
|
|
int len;
|
|
|
|
|
while ((len = is.read(buffer)) > 0) {
|
|
|
|
|
os.write(buffer, 0, len);
|
|
|
|
|
}
|
|
|
|
|
is.close();
|
|
|
|
|
os.close();
|
|
|
|
|
|
|
|
|
|
// 返回图片的真实本地路径(不是URI)
|
|
|
|
|
return targetFile.getAbsolutePath();
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
Log.e("NoteEdit", "保存图片失败", e);
|
|
|
|
|
Toast.makeText(this, "图片保存失败", Toast.LENGTH_SHORT).show();
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 确保选择范围有效
|
|
|
|
|
if (selectionStart < 0 || selectionEnd > editable.length() || selectionStart >= selectionEnd) {
|
|
|
|
|
showToast(R.string.error_please_select_text);
|
|
|
|
|
return;
|
|
|
|
|
// 自定义方法:给RichEditor设置字体大小(对应原EditText的setTextAppearance)
|
|
|
|
|
private void setRichEditorFontSize(int fontSizeId) {
|
|
|
|
|
switch (fontSizeId) {
|
|
|
|
|
case ResourceParser.TEXT_SMALL:
|
|
|
|
|
mNoteEditor.setEditorFontSize(14); // 小字体
|
|
|
|
|
break;
|
|
|
|
|
case ResourceParser.TEXT_MEDIUM:
|
|
|
|
|
mNoteEditor.setEditorFontSize(18); // 中字体(默认)
|
|
|
|
|
break;
|
|
|
|
|
case ResourceParser.TEXT_LARGE:
|
|
|
|
|
mNoteEditor.setEditorFontSize(22); // 大字体
|
|
|
|
|
break;
|
|
|
|
|
case ResourceParser.TEXT_SUPER:
|
|
|
|
|
mNoteEditor.setEditorFontSize(26); // 超大字体
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
mNoteEditor.setEditorFontSize(18); // 默认值
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 应用样式
|
|
|
|
|
if (styleType == -1) {
|
|
|
|
|
// 下划线样式
|
|
|
|
|
UnderlineSpan[] underlineSpans = editable.getSpans(selectionStart, selectionEnd, UnderlineSpan.class);
|
|
|
|
|
if (underlineSpans.length > 0) {
|
|
|
|
|
// 移除下划线
|
|
|
|
|
for (UnderlineSpan span : underlineSpans) {
|
|
|
|
|
int spanStart = editable.getSpanStart(span);
|
|
|
|
|
int spanEnd = editable.getSpanEnd(span);
|
|
|
|
|
editable.removeSpan(span);
|
|
|
|
|
// 如果移除的span范围大于选中范围,需要重新应用样式到剩余部分
|
|
|
|
|
if (spanStart < selectionStart) {
|
|
|
|
|
editable.setSpan(new UnderlineSpan(), spanStart, selectionStart, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|
|
|
|
|
}
|
|
|
|
|
if (spanEnd > selectionEnd) {
|
|
|
|
|
editable.setSpan(new UnderlineSpan(), selectionEnd, spanEnd, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
// 添加下划线
|
|
|
|
|
editable.setSpan(new UnderlineSpan(), selectionStart, selectionEnd, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
// 加粗或斜体样式
|
|
|
|
|
StyleSpan[] styleSpans = editable.getSpans(selectionStart, selectionEnd, StyleSpan.class);
|
|
|
|
|
|
|
|
|
|
// 检查选中范围内是否已经有该样式
|
|
|
|
|
boolean hasStyle = false;
|
|
|
|
|
int existingStyle = 0;
|
|
|
|
|
|
|
|
|
|
// 收集选中范围内的所有样式
|
|
|
|
|
for (StyleSpan span : styleSpans) {
|
|
|
|
|
int spanStart = editable.getSpanStart(span);
|
|
|
|
|
int spanEnd = editable.getSpanEnd(span);
|
|
|
|
|
|
|
|
|
|
// 如果span与选中范围重叠
|
|
|
|
|
if (spanStart < selectionEnd && spanEnd > selectionStart) {
|
|
|
|
|
int spanStyle = span.getStyle();
|
|
|
|
|
existingStyle |= spanStyle;
|
|
|
|
|
|
|
|
|
|
// 检查是否包含目标样式
|
|
|
|
|
if ((spanStyle & styleType) == styleType) {
|
|
|
|
|
hasStyle = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// 初始化富文本编辑器配置
|
|
|
|
|
private void initRichEditor() {
|
|
|
|
|
mNoteEditor.setEditorHeight(600); // 设置编辑器高度
|
|
|
|
|
mNoteEditor.setEditorFontSize(16); // 字体大小
|
|
|
|
|
mNoteEditor.setEditorFontColor(Color.BLACK); // 字体颜色
|
|
|
|
|
mNoteEditor.setPadding(10, 10, 10, 10); // 内边距
|
|
|
|
|
mNoteEditor.setPlaceholder("请输入笔记内容..."); // 占位提示
|
|
|
|
|
mNoteEditor.setInputEnabled(true); // 允许输入
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 添加富文本功能按钮初始化方法
|
|
|
|
|
private void initRichEditorButtons() {
|
|
|
|
|
// 撤销功能
|
|
|
|
|
findViewById(R.id.action_undo).setOnClickListener(new View.OnClickListener() {
|
|
|
|
|
@Override
|
|
|
|
|
public void onClick(View v) {
|
|
|
|
|
mNoteEditor.undo();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 移除选中范围内的所有StyleSpan,以便重新应用
|
|
|
|
|
for (int i = styleSpans.length - 1; i >= 0; i--) {
|
|
|
|
|
StyleSpan span = styleSpans[i];
|
|
|
|
|
int spanStart = editable.getSpanStart(span);
|
|
|
|
|
int spanEnd = editable.getSpanEnd(span);
|
|
|
|
|
|
|
|
|
|
// 如果span与选中范围重叠
|
|
|
|
|
if (spanStart < selectionEnd && spanEnd > selectionStart) {
|
|
|
|
|
editable.removeSpan(span);
|
|
|
|
|
|
|
|
|
|
// 处理span范围大于选中范围的情况,保留未选中部分的样式
|
|
|
|
|
int spanStyle = span.getStyle();
|
|
|
|
|
if (spanStart < selectionStart) {
|
|
|
|
|
// 保留选中范围之前的样式
|
|
|
|
|
editable.setSpan(new StyleSpan(spanStyle), spanStart, selectionStart, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|
|
|
|
|
}
|
|
|
|
|
if (spanEnd > selectionEnd) {
|
|
|
|
|
// 保留选中范围之后的样式
|
|
|
|
|
editable.setSpan(new StyleSpan(spanStyle), selectionEnd, spanEnd, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// 加粗功能
|
|
|
|
|
findViewById(R.id.action_bold).setOnClickListener(new View.OnClickListener() {
|
|
|
|
|
@Override
|
|
|
|
|
public void onClick(View v) {
|
|
|
|
|
mNoteEditor.setBold();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 切换样式:如果有则移除,如果没有则添加
|
|
|
|
|
int finalStyle = existingStyle;
|
|
|
|
|
if (hasStyle) {
|
|
|
|
|
// 移除目标样式
|
|
|
|
|
finalStyle &= ~styleType;
|
|
|
|
|
} else {
|
|
|
|
|
// 添加目标样式
|
|
|
|
|
finalStyle |= styleType;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// 斜体功能
|
|
|
|
|
findViewById(R.id.action_italic).setOnClickListener(new View.OnClickListener() {
|
|
|
|
|
@Override
|
|
|
|
|
public void onClick(View v) {
|
|
|
|
|
mNoteEditor.setItalic();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 应用最终样式
|
|
|
|
|
if (finalStyle != 0) {
|
|
|
|
|
editable.setSpan(new StyleSpan(finalStyle), selectionStart, selectionEnd, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// 背景色功能
|
|
|
|
|
findViewById(R.id.action_bg_color).setOnClickListener(new View.OnClickListener() {
|
|
|
|
|
@Override
|
|
|
|
|
public void onClick(View v) {
|
|
|
|
|
mNoteEditor.focusEditor(); // 获取焦点
|
|
|
|
|
new AlertDialog.Builder(NoteEditActivity.this)
|
|
|
|
|
.setTitle("选择字体背景颜色")
|
|
|
|
|
.setItems(new String[]{"红色", "黄色", "蓝色", "绿色", "黑色", "白色"},
|
|
|
|
|
new DialogInterface.OnClickListener() {
|
|
|
|
|
@Override
|
|
|
|
|
public void onClick(DialogInterface dialog, int which) {
|
|
|
|
|
switch (which) {
|
|
|
|
|
case 0: // 红
|
|
|
|
|
mNoteEditor.setTextBackgroundColor(Color.RED);
|
|
|
|
|
break;
|
|
|
|
|
case 1: // 黄
|
|
|
|
|
mNoteEditor.setTextBackgroundColor(Color.YELLOW);
|
|
|
|
|
break;
|
|
|
|
|
case 2: // 蓝
|
|
|
|
|
mNoteEditor.setTextBackgroundColor(Color.BLUE);
|
|
|
|
|
break;
|
|
|
|
|
case 3: // 绿
|
|
|
|
|
mNoteEditor.setTextBackgroundColor(Color.GREEN);
|
|
|
|
|
break;
|
|
|
|
|
case 4: // 黑
|
|
|
|
|
mNoteEditor.setTextBackgroundColor(Color.BLACK);
|
|
|
|
|
break;
|
|
|
|
|
case 5: // 白
|
|
|
|
|
mNoteEditor.setTextBackgroundColor(Color.WHITE);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
dialog.dismiss(); // 选择后关闭对话框
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
.show();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 保持选中状态
|
|
|
|
|
mNoteEditor.setSelection(selectionStart, selectionEnd);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 应用加粗样式
|
|
|
|
|
*/
|
|
|
|
|
private void applyBoldStyle() {
|
|
|
|
|
applyTextStyle(Typeface.BOLD);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 应用斜体样式
|
|
|
|
|
*/
|
|
|
|
|
private void applyItalicStyle() {
|
|
|
|
|
applyTextStyle(Typeface.ITALIC);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 应用下划线样式
|
|
|
|
|
*/
|
|
|
|
|
private void applyUnderlineStyle() {
|
|
|
|
|
applyTextStyle(-1); // -1 表示下划线
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|