package com.example.labmemotest;
import androidx.appcompat.app.AppCompatActivity;
import androidx.annotation.Nullable;
import androidx.core.content.FileProvider;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.text.Selection;
import android.text.Spannable;
import android.util.Log;
import android.view.ContextMenu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.DataSource;
import com.bumptech.glide.load.engine.GlideException;
import com.bumptech.glide.request.RequestListener;
import com.bumptech.glide.request.target.Target;
import com.example.labmemotest.db.labDbHelper;
import com.github.chrisbanes.photoview.PhotoView;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;
public class DetailActivity extends AppCompatActivity {
private labDbHelper mhelper;
private List<String> imagePaths = new ArrayList<>();
private TextView contentTextView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_detail);
// 启用文本选择和上下文菜单
contentTextView = findViewById(R.id.detail_content);
contentTextView.setTextIsSelectable(true);
registerForContextMenu(contentTextView);
Bundle bundle = getIntent().getExtras();
if (bundle != null) {
String memo_id = bundle.getString("memo_id");
String title = bundle.getString("title");
String content = bundle.getString("content");
String time = bundle.getString("time");
String location = bundle.getString("location");
TextView memo_idTextView = findViewById(R.id.detail_memo_id);
memo_idTextView.setText("编号:" + memo_id);
TextView titleTextView = findViewById(R.id.detail_title);
titleTextView.setText(title);
TextView locationTextView = findViewById(R.id.detail_location);
if (location != null && !location.isEmpty()) {
locationTextView.setText("地点:" + location);
} else {
locationTextView.setText("地点:未设置");
}
contentTextView.setText(content);
TextView timeTextView = findViewById(R.id.detail_time);
timeTextView.setText(time);
LinearLayout imagesContainer = findViewById(R.id.detail_images_container);
imagesContainer.removeAllViews();
// 初始化数据库帮助类
mhelper = new labDbHelper(this);
loadImages(memo_id, imagesContainer);
}
}
// 创建上下文菜单
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
if (v.getId() == R.id.detail_content) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.text_context_menu, menu);
}
}
// 处理菜单项点击
@Override
public boolean onContextItemSelected(MenuItem item) {
if (item.getItemId() == R.id.menu_select_all) {
// 使用Spannable文本操作替代setSelection()
setSelectAllText();
return true;
} else if (item.getItemId() == R.id.menu_copy) {
copyTextToClipboard();
return true;
}
return super.onContextItemSelected(item);
}
// 设置全选文本
private void setSelectAllText() {
if (contentTextView.getText() instanceof Spannable) {
Spannable text = (Spannable) contentTextView.getText();
Selection.setSelection(text, 0, text.length());
Toast.makeText(this, "已全选文本", Toast.LENGTH_SHORT).show();
}
}
// 复制文本到剪贴板
private void copyTextToClipboard() {
String textToCopy = "";
if (contentTextView.getText() instanceof Spannable) {
Spannable text = (Spannable) contentTextView.getText();
int start = Selection.getSelectionStart(text);
int end = Selection.getSelectionEnd(text);
if (start != -1 && end != -1 && start != end) {
textToCopy = text.subSequence(start, end).toString();
} else {
textToCopy = contentTextView.getText().toString();
}
} else {
textToCopy = contentTextView.getText().toString();
}
ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
ClipData clip = ClipData.newPlainText("Memo Content", textToCopy);
clipboard.setPrimaryClip(clip);
Toast.makeText(this, "已复制到剪贴板", Toast.LENGTH_SHORT).show();
}
private void loadImages(String memo_id, LinearLayout container) {
SQLiteDatabase db = mhelper.getReadableDatabase();
imagePaths.clear();
try (Cursor cursor = db.query(
"tb_image",
new String[]{"imgpath"},
"memo_id = ?",
new String[]{memo_id},
null, null, null
)) {
if (cursor.moveToFirst()) {
do {
String imgPath = cursor.getString(cursor.getColumnIndexOrThrow("imgpath"));
imagePaths.add(imgPath);
} while (cursor.moveToNext());
}
} catch (Exception e) {
Log.e("ImageLoad", "数据库查询失败", e);
addErrorImage(container, "图片加载失败: 数据库错误");
return;
} finally {
db.close();
}
for (String imgPath : imagePaths) {
try {
Uri uri = handlePermissions(imgPath);
addImageView(uri, container, imgPath);
} catch (Exception e) {
Log.e("ImageLoad", "图片处理错误: " + imgPath, e);
addErrorImage(container, "加载失败: " + e.getMessage());
}
}
}
private Uri handlePermissions(String imgPath) throws FileNotFoundException {
Uri uri;
// 处理文件路径和URI路径
if (imgPath.startsWith("/")) {
File file = new File(imgPath);
if (file.exists()) {
// 转换为FileProvider提供的URI
uri = FileProvider.getUriForFile(
this,
getPackageName() + ".fileprovider",
file
);
} else {
throw new FileNotFoundException("文件不存在: " + imgPath);
}
} else {
uri = Uri.parse(imgPath);
}
// 添加持久化权限处理
try {
// 检查是否已有持久化权限
int modeFlags = Intent.FLAG_GRANT_READ_URI_PERMISSION;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
// 尝试获取持久化权限
getContentResolver().takePersistableUriPermission(uri, modeFlags);
} else {
// 旧版本临时权限
grantUriPermission(getPackageName(), uri, modeFlags);
}
} catch (SecurityException e) {
Log.w("PermissionWarning", "无法获取URI权限: " + uri, e);
}
return uri;
}
private void addImageView(Uri uri, LinearLayout container, final String imgPath) {
// 使用PhotoView替代原有ImageView
PhotoView photoView = new PhotoView(this);
// 设置布局参数 - 初始高度为600dp
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
600
);
params.bottomMargin = 16;
photoView.setLayoutParams(params);
photoView.setScaleType(ImageView.ScaleType.CENTER_CROP);
photoView.setBackgroundColor(Color.parseColor("#F5F5F5"));
// 添加点击事件
photoView.setOnClickListener(v -> openImageFullscreen(imgPath));
// Glide加载带详细错误处理
Glide.with(this)
.load(uri)
.placeholder(R.drawable.ic_default_image)
.error(R.drawable.ic_error_image)
.listener(new RequestListener<Drawable>() {
@Override
public boolean onLoadFailed(
@Nullable GlideException e, Object model,
Target<Drawable> target, boolean isFirstResource
) {
Log.e("GlideError", "加载失败: " + model, e);
addErrorImage(container, "图片加载失败: " + (e != null ? e.getMessage() : "未知错误"));
return false;
}
@Override
public boolean onResourceReady(
Drawable resource, Object model,
Target<Drawable> target, DataSource dataSource,
boolean isFirstResource
) {
// 动态计算高度保持宽高比
int bitmapWidth = resource.getIntrinsicWidth();
int bitmapHeight = resource.getIntrinsicHeight();
if (bitmapWidth > 0 && bitmapHeight > 0) {
int screenWidth = getResources().getDisplayMetrics().widthPixels;
int newHeight = (int) ((float) screenWidth * bitmapHeight / bitmapWidth);
// 限制最大高度(屏幕高度的60%)
int maxHeight = (int) (getResources().getDisplayMetrics().heightPixels * 0.6);
if (newHeight > maxHeight) newHeight = maxHeight;
// 更新布局参数
LinearLayout.LayoutParams newParams = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
newHeight
);
newParams.bottomMargin = 16;
photoView.setLayoutParams(newParams);
}
return false;
}
})
.into(photoView);
container.addView(photoView);
}
private void addErrorImage(LinearLayout container, String errorMsg) {
TextView errorView = new TextView(this);
errorView.setText(errorMsg);
errorView.setTextColor(Color.RED);
errorView.setPadding(16, 16, 16, 16);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT
);
params.bottomMargin = 16;
container.addView(errorView, params);
}
// 打开全屏图片查看器
private void openImageFullscreen(String imagePath) {
Intent intent = new Intent(this, FullscreenImageActivity.class);
intent.putExtra("image_path", imagePath);
intent.putStringArrayListExtra("all_images", new ArrayList<>(imagePaths));
startActivity(intent);
}
@Override
protected void onDestroy() {
super.onDestroy();
if (mhelper != null) {
mhelper.close();
}
}
}在不改变原有代码的基础上,添加以下功能:
文本复制功能缺失:需要支持文本选择
启用TextView文本选择功能
最新发布