diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 7ac81c2..576ae1c 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -15,8 +15,8 @@ android { minSdk = 23 //noinspection OldTargetApi targetSdk = 34 - versionCode = 3 - versionName = "1.0.1" + versionCode = 4 + versionName = "1.0.2" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" setProperty("archivesBaseName", "WallpapersHaven_V" + versionName + "(${versionCode})_$timestamp") } diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index c4f2b5a..b6bd385 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -27,10 +27,10 @@ -keepclassmembers class * { @androidx.room.Query ; } --keep class com.lh.wallpaper2.entity.AppDatabase { *; } +-keep class com.lh.wallpaper2.room.AppDatabase { *; } -keep class com.lh.wallpaper2.json.Info { *; } -keepclassmembers class com.lh.wallpaper2.json.Url { *; } --keep class com.lh.wallpaper2.db.Favorite { *; } +-keep class com.lh.wallpaper2.room.Favorite { *; } -keep class com.google.gson.** { *; } -keepattributes Signature diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 4ad91e3..09c09b8 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -4,9 +4,11 @@ - - + + + diff --git a/app/src/main/java/com/lh/wallpaper2/DetailsActivity.java b/app/src/main/java/com/lh/wallpaper2/DetailsActivity.java index 5fa00a2..9794169 100644 --- a/app/src/main/java/com/lh/wallpaper2/DetailsActivity.java +++ b/app/src/main/java/com/lh/wallpaper2/DetailsActivity.java @@ -40,7 +40,14 @@ public class DetailsActivity extends AppCompatActivity implements UrlWallpaperLi info = (Info) getIntent().getSerializableExtra(StaticValue.key_info); Log.d("99999999999", "onCreate: " + info.getList().size()); if (info != null) { - textView.setText(info.getName()); + String name = info.getName(); + if (name != null && !name.isEmpty()) { + // 将首字母转换为大写,其他字母保持不变 + String capitalized = name.substring(0, 1).toUpperCase() + name.substring(1); + textView.setText(capitalized); + } else { + textView.setText(name); // 如果 name 为 null 或空,直接设置 + } Log.d("99999999999", "onCreate: " + info.getName()); } setRecyclerView(); diff --git a/app/src/main/java/com/lh/wallpaper2/InitialActivity.java b/app/src/main/java/com/lh/wallpaper2/InitialActivity.java index d5b3cba..e10e163 100644 --- a/app/src/main/java/com/lh/wallpaper2/InitialActivity.java +++ b/app/src/main/java/com/lh/wallpaper2/InitialActivity.java @@ -23,7 +23,6 @@ import java.lang.annotation.Annotation; public class InitialActivity extends AppCompatActivity { private ProgressBar progressBar; // private int progressStatus = 0; - private CountDownTimer countDownTimer; private Handler handler = new Handler(Looper.getMainLooper()); private int progressStatus = 0; @@ -53,6 +52,7 @@ public class InitialActivity extends AppCompatActivity { } Intent intent = new Intent(InitialActivity.this, MainActivity.class); startActivity(intent); + finish(); } }).start(); } diff --git a/app/src/main/java/com/lh/wallpaper2/MainActivity.java b/app/src/main/java/com/lh/wallpaper2/MainActivity.java index 6f88100..d904023 100644 --- a/app/src/main/java/com/lh/wallpaper2/MainActivity.java +++ b/app/src/main/java/com/lh/wallpaper2/MainActivity.java @@ -21,6 +21,7 @@ import com.google.android.material.bottomnavigation.BottomNavigationView; import com.google.android.material.navigation.NavigationBarView; import com.lh.wallpaper2.fragment.FavoriteFragment; import com.lh.wallpaper2.fragment.HomeFragment; +import com.lh.wallpaper2.fragment.ImportFragment; import com.lh.wallpaper2.fragment.SettingFragment; import com.lh.wallpaper2.adapter.MyFragmentStateAdapter; @@ -40,8 +41,8 @@ public class MainActivity extends AppCompatActivity { viewPager = findViewById(R.id.viewPager); List fragments = new ArrayList<>(); fragments.add(new HomeFragment()); + fragments.add(new ImportFragment()); fragments.add(new FavoriteFragment()); - fragments.add(new SettingFragment()); //若跳转多个界面添加多个fragment MyFragmentStateAdapter adapter = new MyFragmentStateAdapter(getSupportFragmentManager(), fragments); viewPager.setAdapter(adapter); @@ -52,9 +53,9 @@ public class MainActivity extends AppCompatActivity { public boolean onNavigationItemSelected(@NonNull MenuItem item) { if (item.getItemId() == R.id.navigation_home) { viewPager.setCurrentItem(0); - } if (item.getItemId() == R.id.navigation_favorite){ + } if (item.getItemId() == R.id.navigation_import){ viewPager.setCurrentItem(1); - } if (item.getItemId() == R.id.navigation_setting) { + } if (item.getItemId() == R.id.navigation_favorite) { viewPager.setCurrentItem(2); } return true; @@ -72,10 +73,10 @@ public class MainActivity extends AppCompatActivity { navigationView.setSelectedItemId(R.id.navigation_home); break; case 1: - navigationView.setSelectedItemId(R.id.navigation_favorite); + navigationView.setSelectedItemId(R.id.navigation_import); break; case 2: - navigationView.setSelectedItemId(R.id.navigation_setting); + navigationView.setSelectedItemId(R.id.navigation_favorite); break; } } diff --git a/app/src/main/java/com/lh/wallpaper2/SettingActivity.java b/app/src/main/java/com/lh/wallpaper2/SettingActivity.java new file mode 100644 index 0000000..becb437 --- /dev/null +++ b/app/src/main/java/com/lh/wallpaper2/SettingActivity.java @@ -0,0 +1,92 @@ +package com.lh.wallpaper2; + +import android.annotation.SuppressLint; +import android.app.AlertDialog; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.net.Uri; +import android.os.Bundle; +import android.view.View; +import android.widget.ImageView; +import android.widget.RelativeLayout; + +import androidx.appcompat.app.AppCompatActivity; + +public class SettingActivity extends AppCompatActivity { + private RelativeLayout about; + private RelativeLayout feedBack; + private RelativeLayout privacy; + private ImageView back; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_setting); // 新布局文件 + + about = findViewById(R.id.about); + feedBack = findViewById(R.id.feedback); + privacy = findViewById(R.id.Privacy); + back = findViewById(R.id.setting_back); + + back.setOnClickListener(v -> {finish();}); + + privacy.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + Intent intent = new Intent(SettingActivity.this, PrivacyActivity.class); + startActivity(intent); + } + }); + + about.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + about(); + } + }); + + feedBack.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + @SuppressLint("IntentWithNullActionLaunch") + Intent intent = new Intent(Intent.ACTION_VIEW); + intent.setData(Uri.parse("https://play.google.com/store/apps/details?id=" + getPackageName())); + startActivity(intent); + } + }); + } + + public void about() { + final AlertDialog dialog; + AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setTitle("About"); + + builder.setMessage("The current version is " + getVersion()); + builder.setPositiveButton("CONFIRM", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); //关闭对话框 + } + }); + dialog = builder.create(); + dialog.show(); + } + + public String getVersion() { + try { + PackageInfo packageInfo = getPackageManager().getPackageInfo(getPackageName(), 0); + return packageInfo.versionName; + } catch (PackageManager.NameNotFoundException e) { + e.printStackTrace(); + } + return null; + } + + @Override + public void onBackPressed() { + super.onBackPressed(); + finish(); + } +} diff --git a/app/src/main/java/com/lh/wallpaper2/ViewActivity.java b/app/src/main/java/com/lh/wallpaper2/ViewActivity.java index 6c7cd36..9d57ca7 100644 --- a/app/src/main/java/com/lh/wallpaper2/ViewActivity.java +++ b/app/src/main/java/com/lh/wallpaper2/ViewActivity.java @@ -1,5 +1,5 @@ package com.lh.wallpaper2; -import android.Manifest; + import android.annotation.SuppressLint; import android.app.WallpaperManager; import android.content.Intent; @@ -13,6 +13,7 @@ import android.widget.ImageView; import android.widget.ProgressBar; import android.widget.TextView; import android.widget.Toast; + import androidx.activity.EdgeToEdge; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -21,19 +22,22 @@ import androidx.cardview.widget.CardView; import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentStatePagerAdapter; import androidx.viewpager.widget.ViewPager; + import com.bumptech.glide.Glide; +import com.bumptech.glide.load.resource.bitmap.CenterCrop; import com.bumptech.glide.request.target.CustomTarget; import com.bumptech.glide.request.transition.Transition; -import com.google.android.material.floatingactionbutton.FloatingActionButton; -import com.lh.wallpaper2.dao.TaskDao; -import com.lh.wallpaper2.db.Favorite; +import com.lh.wallpaper2.room.TaskDao; +import com.lh.wallpaper2.room.Favorite; import com.lh.wallpaper2.download.ImageDownloadTask; -import com.lh.wallpaper2.entity.AppDatabase; +import com.lh.wallpaper2.room.AppDatabase; import com.lh.wallpaper2.fragment.PreviewFragment; import com.lh.wallpaper2.json.Url; + import java.io.IOException; import java.util.ArrayList; import java.util.List; + public class ViewActivity extends AppCompatActivity { private ArrayList url; private int position; @@ -51,8 +55,10 @@ public class ViewActivity extends AppCompatActivity { private Favorite info; private Url homeInfo; private String topInfo; + private String importurl; private ImageDownloadTask downloadTask; private ProgressBar process; + @SuppressLint("MissingInflatedId") @Override protected void onCreate(Bundle savedInstanceState) { @@ -67,10 +73,11 @@ public class ViewActivity extends AppCompatActivity { download = findViewById(R.id.download); collect = findViewById(R.id.collection); textViewLoading = findViewById(R.id.textview_loading); - process=findViewById(R.id.progressbar); + process = findViewById(R.id.progressbar); //初始化db initDb(); - topInfo=(String) getIntent().getSerializableExtra("top_info"); + topInfo = (String) getIntent().getSerializableExtra("top_info"); + importurl = (String) getIntent().getSerializableExtra("import"); info = (Favorite) getIntent().getSerializableExtra("info"); url = (ArrayList) getIntent().getSerializableExtra(StaticValue.key_picture); homeInfo = (Url) getIntent().getSerializableExtra("home_info"); @@ -79,14 +86,18 @@ public class ViewActivity extends AppCompatActivity { if (info != null) { selectPreImg = info.getPicture(); judge(); - } else if (homeInfo != null) { + }else if (importurl != null){ + download.setVisibility(View.GONE); + selectPreImg = importurl; + judge(); + } + else if (homeInfo != null) { selectPreImg = homeInfo.getSourceUrl(); judge(); } else if (topInfo != null) { selectPreImg = topInfo; judge(); - } - else { + } else { selectPreImg = url.get(position).getSourceUrl(); judge(); } @@ -172,9 +183,10 @@ public class ViewActivity extends AppCompatActivity { } }); } + private void initDb() { //初始化db - AppDatabase db = AppDatabase.getDatabase(this); + AppDatabase db = AppDatabase.getInstance(this); dao = db.taskDao(); } @@ -184,7 +196,7 @@ public class ViewActivity extends AppCompatActivity { public void run() { Log.d("2323232", "run: " + selectPreImg); if (dao.getTaskByUrl(selectPreImg) != null) { - Log.d("2323232", "run: "+dao.getTaskByUrl(selectPreImg)); + Log.d("2323232", "run: " + dao.getTaskByUrl(selectPreImg)); runOnUiThread(new Runnable() { @Override public void run() { @@ -201,6 +213,7 @@ public class ViewActivity extends AppCompatActivity { Glide.with(this) .asBitmap() .load(selectPreImg) + .centerInside() .into(new CustomTarget() { @Override public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition transition) { diff --git a/app/src/main/java/com/lh/wallpaper2/action/FavoriteWallpaperListener.java b/app/src/main/java/com/lh/wallpaper2/action/FavoriteWallpaperListener.java index 325f273..f9a0055 100644 --- a/app/src/main/java/com/lh/wallpaper2/action/FavoriteWallpaperListener.java +++ b/app/src/main/java/com/lh/wallpaper2/action/FavoriteWallpaperListener.java @@ -1,7 +1,7 @@ package com.lh.wallpaper2.action; -import com.lh.wallpaper2.db.Favorite; +import com.lh.wallpaper2.room.Favorite; public interface FavoriteWallpaperListener { diff --git a/app/src/main/java/com/lh/wallpaper2/adapter/DetailsAdapter.java b/app/src/main/java/com/lh/wallpaper2/adapter/DetailsAdapter.java index bcdc4b2..05c5de0 100644 --- a/app/src/main/java/com/lh/wallpaper2/adapter/DetailsAdapter.java +++ b/app/src/main/java/com/lh/wallpaper2/adapter/DetailsAdapter.java @@ -51,6 +51,7 @@ public class DetailsAdapter extends RecyclerView.Adapter { Glide.with(myContext) .load(info.getPreUrl()) .transform(new RoundedCorners(ReadFile.dp2Px(7))) + .placeholder(R.drawable.preview) .into(imageView); holder.getItemRoot().setOnClickListener(new View.OnClickListener() { @Override diff --git a/app/src/main/java/com/lh/wallpaper2/adapter/FavoriteWallpaperAdapter.java b/app/src/main/java/com/lh/wallpaper2/adapter/FavoriteWallpaperAdapter.java index dfd8a29..b1b5964 100644 --- a/app/src/main/java/com/lh/wallpaper2/adapter/FavoriteWallpaperAdapter.java +++ b/app/src/main/java/com/lh/wallpaper2/adapter/FavoriteWallpaperAdapter.java @@ -13,7 +13,7 @@ import com.bumptech.glide.Glide; import com.bumptech.glide.load.resource.bitmap.RoundedCorners; import com.lh.wallpaper2.R; import com.lh.wallpaper2.action.FavoriteWallpaperListener; -import com.lh.wallpaper2.db.Favorite; +import com.lh.wallpaper2.room.Favorite; import com.lh.wallpaper2.file.ReadFile; import com.lh.wallpaper2.recycleView.DetailsWallpaperVH; @@ -45,6 +45,7 @@ public class FavoriteWallpaperAdapter extends RecyclerView.Adapter { + private List imagePaths; + private final Activity context; + private OnImageDeleteListener onImageDeleteListener; // 删除监听器 + + public ImageRecyclerViewAdapter(List imagePaths, Activity context) { + this.imagePaths = imagePaths; + this.context = context; + } + + @NonNull + @Override + public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(parent.getContext()) + .inflate(R.layout.item_import, parent, false); + return new ViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ViewHolder holder, int position) { + String imagePath = imagePaths.get(position); + + RequestOptions requestOptions = new RequestOptions() + .transform(new CenterCrop(), new RoundedCorners(20)); // 20 是圆角半径 + + if (imagePath.startsWith("/data/user/")) { + Glide.with(context) + .load(imagePath) + .diskCacheStrategy(DiskCacheStrategy.ALL) + .apply(requestOptions) + .placeholder(R.drawable.preview) + .into(holder.imageView); + } else { + Glide.with(context) + .load("file:///android_asset/" + imagePath) + .diskCacheStrategy(DiskCacheStrategy.ALL) + .apply(requestOptions) + .placeholder(R.drawable.preview) + .into(holder.imageView); + } + + holder.imageView.setOnClickListener(v -> { + Intent intent = new Intent(context, ViewActivity.class); + intent.putExtra("import", imagePath); + context.startActivity(intent); + }); + + // 设置删除按钮的点击事件 + holder.delete.setOnClickListener(v -> { + int adapterPosition = holder.getAdapterPosition(); // 动态获取当前位置 + if (adapterPosition != RecyclerView.NO_POSITION && onImageDeleteListener != null) { + onImageDeleteListener.onImageDelete(imagePaths.get(adapterPosition)); // 调用删除回调 + } + }); + } + + @Override + public int getItemCount() { + return imagePaths.size(); + } + + // 更新数据并通知数据集更改 + public void updateImagePaths(List newImagePaths) { + this.imagePaths = newImagePaths; + notifyDataSetChanged(); + } + + // 设置删除监听器 + public void setOnImageDeleteListener(OnImageDeleteListener listener) { + this.onImageDeleteListener = listener; + } + + public interface OnImageDeleteListener { + void onImageDelete(String imagePath); + } + + static class ViewHolder extends RecyclerView.ViewHolder { + ImageView imageView; + ImageView delete; + + ViewHolder(View view) { + super(view); + imageView = view.findViewById(R.id.imageView_wallpaper); + delete = view.findViewById(R.id.delete); + } + } +} diff --git a/app/src/main/java/com/lh/wallpaper2/adapter/InfoWallpaperAdapter.java b/app/src/main/java/com/lh/wallpaper2/adapter/InfoWallpaperAdapter.java index 961fefc..65eb2c4 100644 --- a/app/src/main/java/com/lh/wallpaper2/adapter/InfoWallpaperAdapter.java +++ b/app/src/main/java/com/lh/wallpaper2/adapter/InfoWallpaperAdapter.java @@ -38,6 +38,7 @@ public class InfoWallpaperAdapter extends RecyclerView.Adapter public void setInfoWallpaperListener(InfoWallpaperListener infoWallpaperListener) { this.infoWallpaperListener = infoWallpaperListener; } + public InfoWallpaperAdapter(List infoList, Context myCon) { dataInfo = infoList; myContext = myCon; @@ -53,7 +54,16 @@ public class InfoWallpaperAdapter extends RecyclerView.Adapter @Override public void onBindViewHolder(@NonNull InfoWallpaperVH holder, int position) { Info info = dataInfo.get(position); - holder.getText().setText(info.getName()); + String name = info.getName(); + + if (name != null && !name.isEmpty()) { + // 将首字母转换为大写,其他字母保持不变 + String capitalized = name.substring(0, 1).toUpperCase() + name.substring(1); + holder.getText().setText(capitalized); + } else { + holder.getText().setText(name); // 如果 name 为 null 或空,直接设置 + } + ImageView leftImage = holder.getLeftImage(); ImageView rightImage = holder.getRightImage(); Url homeLeftUrl = info.getList().get(0); diff --git a/app/src/main/java/com/lh/wallpaper2/fragment/FavoriteFragment.java b/app/src/main/java/com/lh/wallpaper2/fragment/FavoriteFragment.java index 9ba7d02..1cdcd20 100644 --- a/app/src/main/java/com/lh/wallpaper2/fragment/FavoriteFragment.java +++ b/app/src/main/java/com/lh/wallpaper2/fragment/FavoriteFragment.java @@ -19,9 +19,9 @@ import com.lh.wallpaper2.R; import com.lh.wallpaper2.ViewActivity; import com.lh.wallpaper2.action.FavoriteWallpaperListener; import com.lh.wallpaper2.adapter.FavoriteWallpaperAdapter; -import com.lh.wallpaper2.dao.TaskDao; -import com.lh.wallpaper2.db.Favorite; -import com.lh.wallpaper2.entity.AppDatabase; +import com.lh.wallpaper2.room.TaskDao; +import com.lh.wallpaper2.room.Favorite; +import com.lh.wallpaper2.room.AppDatabase; import com.lh.wallpaper2.file.MyItemSpace; import java.util.ArrayList; import java.util.List; @@ -47,7 +47,7 @@ public class FavoriteFragment extends Fragment implements FavoriteWallpaperListe likeBackground = view.findViewById(R.id.like_background); likeText = view.findViewById(R.id.like_text); - db = AppDatabase.getDatabase(requireContext()); + db = AppDatabase.getInstance(requireContext()); dao = db.taskDao(); setRecyclerviewWallpaper(); loadFavoriteImages(); diff --git a/app/src/main/java/com/lh/wallpaper2/fragment/HomeFragment.java b/app/src/main/java/com/lh/wallpaper2/fragment/HomeFragment.java index 2be6741..c4c0d0a 100644 --- a/app/src/main/java/com/lh/wallpaper2/fragment/HomeFragment.java +++ b/app/src/main/java/com/lh/wallpaper2/fragment/HomeFragment.java @@ -17,6 +17,7 @@ import android.widget.RelativeLayout; import com.bumptech.glide.Glide; import com.lh.wallpaper2.DetailsActivity; import com.lh.wallpaper2.R; +import com.lh.wallpaper2.SettingActivity; import com.lh.wallpaper2.StaticValue; import com.lh.wallpaper2.ViewActivity; import com.lh.wallpaper2.Wallpaper; @@ -30,10 +31,13 @@ public class HomeFragment extends Fragment implements InfoWallpaperListener { private Info info; private RelativeLayout relativeLayout; private ImageView imageView; + private ImageView setting; + @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } + @SuppressLint("MissingInflatedId") @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, @@ -41,19 +45,28 @@ public class HomeFragment extends Fragment implements InfoWallpaperListener { View view = inflater.inflate(R.layout.fragment_home, container, false); recyclerView = view.findViewById(R.id.home_recyclerView); relativeLayout = view.findViewById(R.id.top_info); - info=Wallpaper.getUserList().get(14); + setting = view.findViewById(R.id.setting); + info = Wallpaper.getUserList().get(14); String topInfo = info.getList().get(0).getSourceUrl(); setRecyclerView(); - imageView=view.findViewById(R.id.top_image); + imageView = view.findViewById(R.id.top_image); Glide.with(requireContext()).load(topInfo).into(imageView); relativeLayout.setOnClickListener(v -> { Intent intent = new Intent(requireContext(), ViewActivity.class); - intent.putExtra("top_info",topInfo); + intent.putExtra("top_info", topInfo); startActivity(intent); }); + setting.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Intent intent = new Intent(requireContext(), SettingActivity.class); + startActivity(intent); + } + }); return view; } - private void setRecyclerView(){ + + private void setRecyclerView() { GridLayoutManager gridLayoutManager = new GridLayoutManager(requireContext(), 1); InfoWallpaperAdapter infoWallpaperAdapter = new InfoWallpaperAdapter(Wallpaper.getUserList(), requireContext()); infoWallpaperAdapter.setInfoWallpaperListener(this); @@ -64,14 +77,14 @@ public class HomeFragment extends Fragment implements InfoWallpaperListener { @Override public void onItemClickAction(Info info) { Intent intent = new Intent(requireContext(), DetailsActivity.class); - intent.putExtra(StaticValue.key_info,info); + intent.putExtra(StaticValue.key_info, info); startActivity(intent); } @Override public void onHomeInfoClickAction(Url info) { Intent intent = new Intent(requireContext(), ViewActivity.class); - intent.putExtra("home_info",info); + intent.putExtra("home_info", info); startActivity(intent); } } \ No newline at end of file diff --git a/app/src/main/java/com/lh/wallpaper2/fragment/ImportFragment.java b/app/src/main/java/com/lh/wallpaper2/fragment/ImportFragment.java new file mode 100644 index 0000000..08de780 --- /dev/null +++ b/app/src/main/java/com/lh/wallpaper2/fragment/ImportFragment.java @@ -0,0 +1,231 @@ +package com.lh.wallpaper2.fragment; + +import android.content.Intent; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.net.Uri; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.Toast; + +import androidx.fragment.app.Fragment; +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.lh.wallpaper2.R; +import com.lh.wallpaper2.adapter.ImageRecyclerViewAdapter; +import com.lh.wallpaper2.file.MyItemSpace; +import com.lh.wallpaper2.room.AppDatabase; +import com.lh.wallpaper2.room.ImageEntry; +import com.lh.wallpaper2.room.ImageEntryDao; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; + +public class ImportFragment extends Fragment { + + private static final int PICK_IMAGE_REQUEST_CODE = 202; // 请求码,用于标识图片选择 + private ImageView btnSelectImage; // 选择图片按钮 + private RecyclerView recyclerView; // 显示图片的 RecyclerView + private ImageRecyclerViewAdapter adapter; // 图片适配器 + private List imagePaths = new ArrayList<>(); // 图片路径列表 + private AppDatabase appDatabase; // 数据库实例 + private ImageEntryDao imageEntryDao; // 图片条目 DAO + private LinearLayout linearLayout; // 空视图 + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + // 加载 Fragment 的布局 + View view = inflater.inflate(R.layout.fragment_import, container, false); + + // 初始化控件 + btnSelectImage = view.findViewById(R.id.btn_select_image); + recyclerView = view.findViewById(R.id.recycler_view); + linearLayout = view.findViewById(R.id.empty); + + // 设置 RecyclerView 的布局管理器和适配器 + recyclerView.setLayoutManager(new GridLayoutManager(getContext(), 2)); // 网格布局,每行显示两个图片 + MyItemSpace itemDecoration = new MyItemSpace(30, 50, 40); + recyclerView.addItemDecoration(itemDecoration); + + adapter = new ImageRecyclerViewAdapter(imagePaths, requireActivity()); + recyclerView.setAdapter(adapter); + + // 设置选择图片按钮的点击事件 + btnSelectImage.setOnClickListener(v -> openImagePicker()); + + // 初始化数据库和 DAO + appDatabase = AppDatabase.getInstance(requireContext()); + imageEntryDao = appDatabase.imageEntryDao(); + + // 加载图片路径 + loadImagePaths(); + + // 设置图片删除监听器 + adapter.setOnImageDeleteListener(imagePath -> { + // 从数据库中删除图片记录 + new Thread(() -> { + // 删除本地存储中的图片文件 + File imageFile = new File(imagePath); + if (imageFile.exists() && imageFile.delete()) { // 删除文件,成功返回 true + // 文件删除成功后,再删除数据库中的图片记录和更新列表 + imageEntryDao.deleteByPath(imagePath); // 删除数据库中的图片记录 + imagePaths.remove(imagePath); // 从列表中删除图片路径 + + requireActivity().runOnUiThread(() -> { + adapter.updateImagePaths(imagePaths); // 更新 RecyclerView + setView(!imagePaths.isEmpty()); // 更新视图 + Toast.makeText(getContext(), "Image deleted", Toast.LENGTH_SHORT).show(); + }); + } else { + // 文件删除失败时的处理 + requireActivity().runOnUiThread(() -> { + Toast.makeText(getContext(), "Failed to delete image file", Toast.LENGTH_SHORT).show(); + }); + } + }).start(); + }); + + + return view; + } + + @Override + public void onResume() { + super.onResume(); + adapter.notifyDataSetChanged(); // 重新加载适配器内容 + } + + // 打开图片选择器 + private void openImagePicker() { + Intent intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI); + startActivityForResult(intent, PICK_IMAGE_REQUEST_CODE); // 启动选择图片的活动 + } + + @Override + public void onActivityResult(int requestCode, int resultCode, Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (requestCode == PICK_IMAGE_REQUEST_CODE && resultCode == getActivity().RESULT_OK && data != null) { + Uri selectedImageUri = data.getData(); // 获取选中的图片 URI + if (selectedImageUri != null) { + try { + if (isImageSizeAcceptable(selectedImageUri)) { + saveImageToInternalStorage(selectedImageUri); // 保存图片到内部存储 + } else { + Toast.makeText(getContext(), "图片大小超过限制", Toast.LENGTH_SHORT).show(); + } + } catch (IOException e) { + e.printStackTrace(); + Toast.makeText(getContext(), "无法获取图片大小: " + e.getMessage(), Toast.LENGTH_SHORT).show(); + } + } + } + } + + // 检查图片大小是否在允许范围内 + private boolean isImageSizeAcceptable(Uri uri) throws IOException { + InputStream inputStream = requireContext().getContentResolver().openInputStream(uri); + if (inputStream == null) { + return false; + } + long fileSize = inputStream.available(); + inputStream.close(); + long maxFileSize = 10 * 1024 * 1024; // 最大 10MB + return fileSize <= maxFileSize; + } + + // 将选中的图片保存到内部存储 + private void saveImageToInternalStorage(Uri uri) { + try { + InputStream inputStream = requireContext().getContentResolver().openInputStream(uri); + Bitmap bitmap = BitmapFactory.decodeStream(inputStream); + if (bitmap == null) { + Toast.makeText(getContext(), "无法加载图片", Toast.LENGTH_SHORT).show(); + return; + } + File internalStorageDir = requireContext().getFilesDir(); + File imageFile = new File(internalStorageDir, System.currentTimeMillis() + ".jpg"); + FileOutputStream outputStream = new FileOutputStream(imageFile); + bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream); + outputStream.close(); + inputStream.close(); + + String imagePath = imageFile.getAbsolutePath(); + new Thread(() -> { + if (isImageAlreadyExists(imagePath)) { + requireActivity().runOnUiThread(() -> Toast.makeText(getContext(), "该图片已经存在", Toast.LENGTH_SHORT).show()); + imageFile.delete(); + return; + } + imagePaths.add(imagePath); + requireActivity().runOnUiThread(() -> { + adapter.updateImagePaths(imagePaths); + setView(!imagePaths.isEmpty()); + }); + imageEntryDao.insert(new ImageEntry(imagePath)); + }).start(); + + } catch (IOException e) { + e.printStackTrace(); + Toast.makeText(getContext(), "保存图片失败: " + e.getMessage(), Toast.LENGTH_SHORT).show(); + } + } + + // 检查图片是否已经存在 + private boolean isImageAlreadyExists(String imagePath) { + File newImageFile = new File(imagePath); + for (String path : imagePaths) { + File existingFile = new File(path); + if (filesAreIdentical(existingFile, newImageFile)) { + return true; + } + } + List imageEntries = imageEntryDao.getAllImages(); + for (ImageEntry imageEntry : imageEntries) { + File existingFile = new File(imageEntry.getImagePath()); + if (filesAreIdentical(existingFile, newImageFile)) { + return true; + } + } + return false; + } + + // 比较两个文件是否相同 + private boolean filesAreIdentical(File file1, File file2) { + return file1.length() == file2.length(); // 比较文件长度 + } + + // 加载图片路径列表 + private void loadImagePaths() { + new Thread(() -> { + imagePaths.clear(); // 清空列表,防止重复添加 + List imageEntries = imageEntryDao.getAllImages(); + for (ImageEntry imageEntry : imageEntries) { + imagePaths.add(imageEntry.getImagePath()); // 添加路径到列表 + } + requireActivity().runOnUiThread(() -> { + adapter.updateImagePaths(imagePaths); + setView(!imagePaths.isEmpty()); + }); + }).start(); + } + + // 更新视图,切换空视图与图片视图 + private void setView(Boolean hasData) { + if (hasData) { + recyclerView.setVisibility(View.VISIBLE); + linearLayout.setVisibility(View.GONE); + } else { + recyclerView.setVisibility(View.GONE); + linearLayout.setVisibility(View.VISIBLE); + } + } +} diff --git a/app/src/main/java/com/lh/wallpaper2/entity/AppDatabase.java b/app/src/main/java/com/lh/wallpaper2/room/AppDatabase.java similarity index 74% rename from app/src/main/java/com/lh/wallpaper2/entity/AppDatabase.java rename to app/src/main/java/com/lh/wallpaper2/room/AppDatabase.java index 1e92aa4..0af8d8f 100644 --- a/app/src/main/java/com/lh/wallpaper2/entity/AppDatabase.java +++ b/app/src/main/java/com/lh/wallpaper2/room/AppDatabase.java @@ -1,4 +1,4 @@ -package com.lh.wallpaper2.entity; +package com.lh.wallpaper2.room; import android.content.Context; @@ -6,16 +6,14 @@ import androidx.room.Database; import androidx.room.Room; import androidx.room.RoomDatabase; -import com.lh.wallpaper2.dao.TaskDao; -import com.lh.wallpaper2.db.Favorite; - -@Database(entities = {Favorite.class}, version = 1) +@Database(entities = {Favorite.class, ImageEntry.class}, version = 1) public abstract class AppDatabase extends RoomDatabase { public abstract TaskDao taskDao(); + public abstract ImageEntryDao imageEntryDao(); private static volatile AppDatabase INSTANCE; - public static AppDatabase getDatabase(final Context context) { + public static AppDatabase getInstance(final Context context) { if (INSTANCE == null) { synchronized (AppDatabase.class) { if (INSTANCE == null) { diff --git a/app/src/main/java/com/lh/wallpaper2/db/Favorite.java b/app/src/main/java/com/lh/wallpaper2/room/Favorite.java similarity index 94% rename from app/src/main/java/com/lh/wallpaper2/db/Favorite.java rename to app/src/main/java/com/lh/wallpaper2/room/Favorite.java index 93a54dd..69de5a9 100644 --- a/app/src/main/java/com/lh/wallpaper2/db/Favorite.java +++ b/app/src/main/java/com/lh/wallpaper2/room/Favorite.java @@ -1,4 +1,4 @@ -package com.lh.wallpaper2.db; +package com.lh.wallpaper2.room; import androidx.room.ColumnInfo; import androidx.room.Entity; import androidx.room.PrimaryKey; diff --git a/app/src/main/java/com/lh/wallpaper2/room/ImageEntry.java b/app/src/main/java/com/lh/wallpaper2/room/ImageEntry.java new file mode 100644 index 0000000..613d5d5 --- /dev/null +++ b/app/src/main/java/com/lh/wallpaper2/room/ImageEntry.java @@ -0,0 +1,31 @@ +package com.lh.wallpaper2.room; + +import androidx.room.Entity; +import androidx.room.PrimaryKey; + +@Entity(tableName = "image_entry") +public class ImageEntry { + @PrimaryKey(autoGenerate = true) + private int id; + private String imagePath; + + public ImageEntry(String imagePath) { + this.imagePath = imagePath; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getImagePath() { + return imagePath; + } + + public void setImagePath(String imagePath) { + this.imagePath = imagePath; + } +} \ No newline at end of file diff --git a/app/src/main/java/com/lh/wallpaper2/room/ImageEntryDao.java b/app/src/main/java/com/lh/wallpaper2/room/ImageEntryDao.java new file mode 100644 index 0000000..6b3c5aa --- /dev/null +++ b/app/src/main/java/com/lh/wallpaper2/room/ImageEntryDao.java @@ -0,0 +1,26 @@ +package com.lh.wallpaper2.room; + +import androidx.room.Dao; +import androidx.room.Delete; +import androidx.room.Insert; +import androidx.room.Query; + +import java.util.List; + +@Dao +public interface ImageEntryDao { + @Insert + void insert(ImageEntry imageEntry); + + @Delete + void delete(ImageEntry imageEntry); + + @Query("SELECT * FROM image_entry") + List getAllImages(); + + @Query("SELECT * FROM image_entry WHERE imagePath = :imagePath LIMIT 1") + ImageEntry findByPath(String imagePath); + + @Query("DELETE FROM image_entry WHERE imagePath = :imagePath") + void deleteByPath(String imagePath); +} diff --git a/app/src/main/java/com/lh/wallpaper2/dao/TaskDao.java b/app/src/main/java/com/lh/wallpaper2/room/TaskDao.java similarity index 88% rename from app/src/main/java/com/lh/wallpaper2/dao/TaskDao.java rename to app/src/main/java/com/lh/wallpaper2/room/TaskDao.java index 8402ed9..f349b63 100644 --- a/app/src/main/java/com/lh/wallpaper2/dao/TaskDao.java +++ b/app/src/main/java/com/lh/wallpaper2/room/TaskDao.java @@ -1,9 +1,9 @@ -package com.lh.wallpaper2.dao; +package com.lh.wallpaper2.room; import androidx.room.Dao; import androidx.room.Insert; import androidx.room.Query; import androidx.room.Update; -import com.lh.wallpaper2.db.Favorite; + import java.util.List; @Dao diff --git a/app/src/main/res/drawable/_delete.xml b/app/src/main/res/drawable/_delete.xml new file mode 100644 index 0000000..2820e62 --- /dev/null +++ b/app/src/main/res/drawable/_delete.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/frame.xml b/app/src/main/res/drawable/frame.xml new file mode 100644 index 0000000..8e3e1ce --- /dev/null +++ b/app/src/main/res/drawable/frame.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/import_icon.xml b/app/src/main/res/drawable/import_icon.xml new file mode 100644 index 0000000..490c6e9 --- /dev/null +++ b/app/src/main/res/drawable/import_icon.xml @@ -0,0 +1,19 @@ + + + + + + + diff --git a/app/src/main/res/drawable/setting.xml b/app/src/main/res/drawable/setting.xml new file mode 100644 index 0000000..0ec04a6 --- /dev/null +++ b/app/src/main/res/drawable/setting.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 95fbba0..9eb3049 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -3,13 +3,16 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" + android:fitsSystemWindows="true" tools:context=".MainActivity"> + android:layout_height="match_parent" + android:layout_above="@id/bottomNavigation" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_view.xml b/app/src/main/res/layout/activity_view.xml index 7c2a1f9..cdf68a7 100644 --- a/app/src/main/res/layout/activity_view.xml +++ b/app/src/main/res/layout/activity_view.xml @@ -38,6 +38,7 @@ android:layout_marginTop="45dp" android:background="@drawable/round_button" android:padding="5dp"> + - - - - + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintEnd_toStartOf="@+id/download" + app:layout_constraintHorizontal_bias="0.5"> + android:foreground="@drawable/share_icon" /> - + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintStart_toEndOf="@id/share" + app:layout_constraintEnd_toStartOf="@+id/collection_layout" + app:layout_constraintHorizontal_bias="0.5"> + + + + + + + android:foreground="@drawable/dislike" /> - + diff --git a/app/src/main/res/layout/details_vh.xml b/app/src/main/res/layout/details_vh.xml index 30de314..4d65363 100644 --- a/app/src/main/res/layout/details_vh.xml +++ b/app/src/main/res/layout/details_vh.xml @@ -1,15 +1,15 @@ + android:layout_height="match_parent" + android:scaleType="centerCrop"/>