JM更新
This commit is contained in:
@@ -45,7 +45,6 @@
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||
<uses-permission android:name="android.permission.WRITE_SETTINGS" tools:ignore="ProtectedPermissions"/>
|
||||
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:fullBackupContent="@xml/backup_rules"
|
||||
@@ -123,6 +122,7 @@
|
||||
android:screenOrientation="fullSensor"
|
||||
android:theme="@style/Theme.AppCompat.Light.NoActionBar"
|
||||
tools:ignore="MissingClass" />
|
||||
<activity android:name=".ui.JMActivity" android:theme="@style/Theme.FindMaimaiUltra.NoActionBar" android:label="FindMaimai Engine"/>
|
||||
<service
|
||||
android:hardwareAccelerated="true"
|
||||
android:name="org.astral.findmaimaiultra.utill.updater.vpn.core.LocalVpnService"
|
||||
|
||||
@@ -0,0 +1,259 @@
|
||||
package org.astral.findmaimaiultra.adapter;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.net.Uri;
|
||||
import android.os.Environment;
|
||||
import android.provider.MediaStore;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.Toast;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.bumptech.glide.request.target.CustomTarget;
|
||||
import com.bumptech.glide.request.transition.Transition;
|
||||
import org.astral.findmaimaiultra.R;
|
||||
import org.astral.findmaimaiultra.been.pixiv.jm.Album;
|
||||
import org.astral.findmaimaiultra.utill.FileUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class PhotoAdapter extends RecyclerView.Adapter<PhotoAdapter.PhotoViewHolder> {
|
||||
private Context context;
|
||||
private Album album;
|
||||
private List<String> imageUrls;
|
||||
private List<Integer> nums;
|
||||
private static List<Integer> loading = new ArrayList<>();
|
||||
|
||||
public void clearLoad() {
|
||||
loading.clear();
|
||||
}
|
||||
|
||||
public PhotoAdapter(Context context, List<String> imageUrls, List<Integer> nums, Album a) {
|
||||
this.context = context;
|
||||
this.imageUrls = imageUrls;
|
||||
this.nums = nums;
|
||||
this.album = a;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public PhotoViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
View view = LayoutInflater.from(context).inflate(R.layout.photo_item, parent, false);
|
||||
return new PhotoViewHolder(view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull PhotoViewHolder holder, @SuppressLint("RecyclerView") int position) {
|
||||
String imageUrl = imageUrls.get(position);
|
||||
int num = nums.get(position);
|
||||
String fileName = "image_" + album.getAlbum_id() + "_" + position + ".jpg";
|
||||
File cacheFile = FileUtils.getCacheDir(context, fileName);
|
||||
|
||||
Log.d("HHHHHHHHHH", "Loading image at position: " + loading.toString());
|
||||
if (cacheFile.exists() && (!loading.contains(position))) {
|
||||
Log.d("HHHHHHHHHH", "Loading cached image at position: " + position);
|
||||
// 加载缓存的图片并压缩到屏幕大小
|
||||
Glide.with(context)
|
||||
.asBitmap()
|
||||
.load(cacheFile)
|
||||
.override(holder.itemView.getWidth(), holder.itemView.getHeight()) // 压缩图片到屏幕大小
|
||||
.into(new CustomTarget<Bitmap>() {
|
||||
@Override
|
||||
public void onResourceReady(@NonNull Bitmap resource, Transition<? super Bitmap> transition) {
|
||||
Log.d("PhotoAdapter", "Image loaded successfully at position: " + position);
|
||||
if (!loading.contains(position)) {
|
||||
loading.add(position);
|
||||
}
|
||||
holder.imageView.setImageBitmap(resource);
|
||||
holder.imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
|
||||
|
||||
// 设置长按监听器
|
||||
holder.imageView.setOnLongClickListener(v -> {
|
||||
saveImageToMediaStore(resource, fileName);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadCleared(Drawable placeholder) {
|
||||
Log.d("PhotoAdapter", "Image load cleared at position: " + position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadFailed(Drawable errorDrawable) {
|
||||
super.onLoadFailed(errorDrawable);
|
||||
Log.e("PhotoAdapter", "Image load failed at position: " + position);
|
||||
}
|
||||
});
|
||||
} else if ((!loading.contains(position))) {
|
||||
// 从网络加载并处理图片
|
||||
Glide.with(context)
|
||||
.asBitmap()
|
||||
.load(imageUrl)
|
||||
.override(holder.itemView.getWidth(), holder.itemView.getHeight()) // 压缩图片到屏幕大小
|
||||
.into(new CustomTarget<Bitmap>() {
|
||||
@Override
|
||||
public void onResourceReady(@NonNull Bitmap resource, Transition<? super Bitmap> transition) {
|
||||
Log.d("PhotoAdapter", "Image loaded successfully at position: " + position);
|
||||
if (!loading.contains(position)) {
|
||||
loading.add(position);
|
||||
}
|
||||
|
||||
Bitmap decodedBitmap = decodeImage(resource, num);
|
||||
holder.imageView.setImageBitmap(decodedBitmap);
|
||||
holder.imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
|
||||
|
||||
// 保存处理后的图片到缓存
|
||||
saveBitmapToCache(decodedBitmap, cacheFile);
|
||||
|
||||
// 设置长按监听器
|
||||
holder.imageView.setOnLongClickListener(v -> {
|
||||
saveImageToMediaStore(decodedBitmap, fileName);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadCleared(Drawable placeholder) {
|
||||
Log.d("PhotoAdapter", "Image load cleared at position: " + position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadFailed(Drawable errorDrawable) {
|
||||
super.onLoadFailed(errorDrawable);
|
||||
Log.e("PhotoAdapter", "Image load failed at position: " + position);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return imageUrls.size();
|
||||
}
|
||||
|
||||
public static class PhotoViewHolder extends RecyclerView.ViewHolder {
|
||||
ImageView imageView;
|
||||
|
||||
public PhotoViewHolder(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
imageView = itemView.findViewById(R.id.photo);
|
||||
}
|
||||
}
|
||||
|
||||
private Bitmap decodeImage(Bitmap imgSrc, int num) {
|
||||
if (num == 0) {
|
||||
return imgSrc;
|
||||
}
|
||||
|
||||
int w = imgSrc.getWidth();
|
||||
int h = imgSrc.getHeight();
|
||||
|
||||
// 创建新的解密图片
|
||||
Bitmap imgDecode = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
|
||||
Canvas canvas = new Canvas(imgDecode);
|
||||
|
||||
int over = h % num;
|
||||
for (int i = 0; i < num; i++) {
|
||||
int move = h / num;
|
||||
int ySrc = h - (move * (i + 1)) - over;
|
||||
int yDst = move * i;
|
||||
|
||||
if (i == 0) {
|
||||
move += over;
|
||||
} else {
|
||||
yDst += over;
|
||||
}
|
||||
|
||||
Rect srcRect = new Rect(0, ySrc, w, ySrc + move);
|
||||
Rect dstRect = new Rect(0, yDst, w, yDst + move);
|
||||
|
||||
canvas.drawBitmap(imgSrc, srcRect, dstRect, null);
|
||||
}
|
||||
|
||||
return imgDecode;
|
||||
}
|
||||
|
||||
private void saveBitmapToCache(Bitmap bitmap, File file) {
|
||||
OutputStream outputStream = null;
|
||||
try {
|
||||
outputStream = new FileOutputStream(file);
|
||||
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, outputStream);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
if (outputStream != null) {
|
||||
try {
|
||||
outputStream.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void saveImageToMediaStore(Bitmap bitmap, String fileName) {
|
||||
ContentValues values = new ContentValues();
|
||||
values.put(MediaStore.Images.Media.DISPLAY_NAME, fileName);
|
||||
values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
|
||||
values.put(MediaStore.Images.Media.RELATIVE_PATH, Environment.DIRECTORY_PICTURES + "/FindMaimaiUltra");
|
||||
|
||||
Uri uri = null;
|
||||
OutputStream outputStream = null;
|
||||
|
||||
try {
|
||||
uri = context.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
|
||||
if (uri != null) {
|
||||
outputStream = context.getContentResolver().openOutputStream(uri);
|
||||
if (outputStream != null) {
|
||||
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, outputStream);
|
||||
Toast.makeText(context, "图片已保存到相册", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
if (uri != null) {
|
||||
context.getContentResolver().delete(uri, null, null);
|
||||
}
|
||||
Toast.makeText(context, "保存图片失败", Toast.LENGTH_SHORT).show();
|
||||
} finally {
|
||||
if (outputStream != null) {
|
||||
try {
|
||||
outputStream.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 添加删除缓存方法
|
||||
public void clearCache() {
|
||||
File cacheDir = FileUtils.getCacheDir(context, "");
|
||||
if (cacheDir.exists() && cacheDir.isDirectory()) {
|
||||
File[] files = cacheDir.listFiles();
|
||||
if (files != null) {
|
||||
for (File file : files) {
|
||||
if (file.isFile()) {
|
||||
file.delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.astral.findmaimaiultra.adapter;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.util.Log;
|
||||
@@ -49,16 +50,22 @@ public class PixivAdapter extends RecyclerView.Adapter<PixivAdapter.ViewHolder>
|
||||
return new ViewHolder(view);
|
||||
}
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
|
||||
IllustData data = dataList.get(position);
|
||||
holder.title.setText(data.getTitle());
|
||||
// Load image using a library like Glide or Picasso
|
||||
if (data.getUrl().startsWith("JM:")) {
|
||||
holder.title.setText("[" + data.getId() + "] " +data.getTitle());
|
||||
}else if (data.getId().startsWith("Place:")) {
|
||||
holder.title.setText(data.getTitle() + " - " + data.getAlt());
|
||||
}else {
|
||||
String imageUrl = "http://43.153.174.191:45678/api/v1/pixiv/toTencent?id=" + data.getId();
|
||||
|
||||
if (imageUrl != null) {
|
||||
loadImage(holder.backgroundLayout, imageUrl);
|
||||
}
|
||||
}
|
||||
|
||||
holder.itemView.setOnClickListener(v -> {
|
||||
if (listener != null) {
|
||||
|
||||
@@ -0,0 +1,153 @@
|
||||
package org.astral.findmaimaiultra.been.pixiv.jm;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
public class Album {
|
||||
private String album_id;
|
||||
private String scramble_id;
|
||||
private String name;
|
||||
private int page_count;
|
||||
private String pub_date;
|
||||
private String update_date;
|
||||
private int likes;
|
||||
private int views;
|
||||
private int comment_count;
|
||||
private List<String> works;
|
||||
private List<String> actors;
|
||||
private List<String> authors;
|
||||
private List<String> tags;
|
||||
private List<String> image_urls;
|
||||
private List<RelatedItem> related_list;
|
||||
private List<Integer> nums;
|
||||
|
||||
public List<Integer> getNums() {
|
||||
return nums;
|
||||
}
|
||||
|
||||
public void setNums(List<Integer> nums) {
|
||||
this.nums = nums;
|
||||
}
|
||||
|
||||
// Getters and Setters
|
||||
public String getAlbum_id() {
|
||||
return album_id;
|
||||
}
|
||||
|
||||
public void setAlbum_id(String album_id) {
|
||||
this.album_id = album_id;
|
||||
}
|
||||
|
||||
public String getScramble_id() {
|
||||
return scramble_id;
|
||||
}
|
||||
|
||||
public void setScramble_id(String scramble_id) {
|
||||
this.scramble_id = scramble_id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public int getPage_count() {
|
||||
return page_count;
|
||||
}
|
||||
|
||||
public void setPage_count(int page_count) {
|
||||
this.page_count = page_count;
|
||||
}
|
||||
|
||||
public String getPub_date() {
|
||||
return pub_date;
|
||||
}
|
||||
|
||||
public void setPub_date(String pub_date) {
|
||||
this.pub_date = pub_date;
|
||||
}
|
||||
|
||||
public String getUpdate_date() {
|
||||
return update_date;
|
||||
}
|
||||
|
||||
public void setUpdate_date(String update_date) {
|
||||
this.update_date = update_date;
|
||||
}
|
||||
|
||||
public int getLikes() {
|
||||
return likes;
|
||||
}
|
||||
|
||||
public void setLikes(int likes) {
|
||||
this.likes = likes;
|
||||
}
|
||||
|
||||
public int getViews() {
|
||||
return views;
|
||||
}
|
||||
|
||||
public void setViews(int views) {
|
||||
this.views = views;
|
||||
}
|
||||
|
||||
public int getComment_count() {
|
||||
return comment_count;
|
||||
}
|
||||
|
||||
public void setComment_count(int comment_count) {
|
||||
this.comment_count = comment_count;
|
||||
}
|
||||
|
||||
public List<String> getWorks() {
|
||||
return works;
|
||||
}
|
||||
|
||||
public void setWorks(List<String> works) {
|
||||
this.works = works;
|
||||
}
|
||||
|
||||
public List<String> getActors() {
|
||||
return actors;
|
||||
}
|
||||
|
||||
public void setActors(List<String> actors) {
|
||||
this.actors = actors;
|
||||
}
|
||||
|
||||
public List<String> getAuthors() {
|
||||
return authors;
|
||||
}
|
||||
|
||||
public void setAuthors(List<String> authors) {
|
||||
this.authors = authors;
|
||||
}
|
||||
|
||||
public List<String> getTags() {
|
||||
return tags;
|
||||
}
|
||||
|
||||
public void setTags(List<String> tags) {
|
||||
this.tags = tags;
|
||||
}
|
||||
|
||||
public List<String> getImage_urls() {
|
||||
return image_urls;
|
||||
}
|
||||
|
||||
public void setImage_urls(List<String> image_urls) {
|
||||
this.image_urls = image_urls;
|
||||
}
|
||||
|
||||
public List<RelatedItem> getRelated_list() {
|
||||
return related_list;
|
||||
}
|
||||
|
||||
public void setRelated_list(List<RelatedItem> related_list) {
|
||||
this.related_list = related_list;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
package org.astral.findmaimaiultra.been.pixiv.jm;
|
||||
|
||||
public class AlbumItem {
|
||||
private String album_id;
|
||||
private String title;
|
||||
|
||||
// Getters and Setters
|
||||
public String getAlbum_id() {
|
||||
return album_id;
|
||||
}
|
||||
|
||||
public void setAlbum_id(String album_id) {
|
||||
this.album_id = album_id;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package org.astral.findmaimaiultra.been.pixiv.jm;
|
||||
|
||||
public class RelatedItem {
|
||||
private String id;
|
||||
private String author;
|
||||
private String name;
|
||||
private String image;
|
||||
|
||||
// Getters and Setters
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getAuthor() {
|
||||
return author;
|
||||
}
|
||||
|
||||
public void setAuthor(String author) {
|
||||
this.author = author;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getImage() {
|
||||
return image;
|
||||
}
|
||||
|
||||
public void setImage(String image) {
|
||||
this.image = image;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package org.astral.findmaimaiultra.been.pixiv.jm;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class SearchJM {
|
||||
private List<AlbumItem> albums;
|
||||
|
||||
// Getter and Setter
|
||||
public List<AlbumItem> getAlbums() {
|
||||
return albums;
|
||||
}
|
||||
|
||||
public void setAlbums(List<AlbumItem> albums) {
|
||||
this.albums = albums;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
package org.astral.findmaimaiultra.ui;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.view.animation.Animation;
|
||||
import android.view.animation.AnimationUtils;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.constraintlayout.widget.ConstraintLayout;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import com.google.android.material.bottomsheet.BottomSheetBehavior;
|
||||
import com.google.gson.Gson;
|
||||
import org.astral.findmaimaiultra.R;
|
||||
import org.astral.findmaimaiultra.adapter.PhotoAdapter;
|
||||
import org.astral.findmaimaiultra.been.pixiv.jm.Album;
|
||||
|
||||
|
||||
public class JMActivity extends AppCompatActivity {
|
||||
private FrameLayout overlay;
|
||||
private boolean isOverlayVisible = false;
|
||||
private BottomSheetBehavior<View> bottomSheetBehavior;
|
||||
private PhotoAdapter photoAdapter;
|
||||
@Override
|
||||
@SuppressLint("MissingInflatedId")
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.jm_dialog);
|
||||
|
||||
initRecyclerView();
|
||||
}
|
||||
|
||||
@SuppressLint({"ClickableViewAccessibility", "SetTextI18n"})
|
||||
private void initRecyclerView() {
|
||||
Intent intent = getIntent();
|
||||
String res = intent.getStringExtra("album");
|
||||
Album a = new Gson().fromJson(res, Album.class);
|
||||
RecyclerView recyclerView = findViewById(R.id.recyclerView);
|
||||
recyclerView.setLayoutManager(new LinearLayoutManager(this));
|
||||
photoAdapter = new PhotoAdapter(this, a.getImage_urls(), a.getNums(), a);
|
||||
photoAdapter.clearLoad();
|
||||
|
||||
recyclerView.setAdapter(photoAdapter);
|
||||
bottomSheetBehavior = BottomSheetBehavior.from(findViewById(R.id.bottom_sheet));
|
||||
bottomSheetBehavior.setPeekHeight(dpToPx(80));
|
||||
TextView menu = findViewById(R.id.menu);
|
||||
menu.setText(a.getName());
|
||||
TextView dec = findViewById(R.id.dec);
|
||||
dec.setText(a.getAuthors().toString().replaceAll( "\\[","").replaceAll( "]","")
|
||||
+ " / " + a.getActors().toString().replaceAll( "\"","") .replaceAll( "\\[","").replaceAll( "]","")
|
||||
+ " \n " + a.getTags().toString().replaceAll( "\"","") .replaceAll( "\\[","").replaceAll( "]","")
|
||||
+ " \n " + a.getAlbum_id().replaceAll( "\"","").replaceAll( "\\[","").replaceAll( "]",""));
|
||||
}
|
||||
public int dpToPx(int dp) {
|
||||
return (int) (dp * getResources().getDisplayMetrics().density);
|
||||
}
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
if (photoAdapter != null) {
|
||||
photoAdapter.clearCache();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,21 +1,14 @@
|
||||
package org.astral.findmaimaiultra.ui.pixiv;
|
||||
|
||||
import android.Manifest;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Activity;
|
||||
import android.content.*;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.location.Address;
|
||||
import android.location.*;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.Environment;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.util.Log;
|
||||
@@ -23,52 +16,48 @@ import android.view.*;
|
||||
import android.widget.*;
|
||||
import androidx.activity.OnBackPressedCallback;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.appcompat.widget.SearchView;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.core.app.ActivityCompat;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.bumptech.glide.request.RequestOptions;
|
||||
import com.bumptech.glide.request.target.CustomTarget;
|
||||
import com.bumptech.glide.request.target.Target;
|
||||
import com.bumptech.glide.request.transition.Transition;
|
||||
import com.google.android.material.button.MaterialButton;
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||
import com.google.android.material.snackbar.Snackbar;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import okhttp3.*;
|
||||
import org.astral.findmaimaiultra.R;
|
||||
import org.astral.findmaimaiultra.adapter.MusicRatingAdapter;
|
||||
import org.astral.findmaimaiultra.adapter.PixivAdapter;
|
||||
import org.astral.findmaimaiultra.adapter.PlaceAdapter;
|
||||
import org.astral.findmaimaiultra.been.*;
|
||||
import org.astral.findmaimaiultra.been.Place;
|
||||
import org.astral.findmaimaiultra.been.pixiv.jm.Album;
|
||||
import org.astral.findmaimaiultra.been.pixiv.jm.AlbumItem;
|
||||
import org.astral.findmaimaiultra.been.pixiv.jm.SearchJM;
|
||||
import org.astral.findmaimaiultra.been.pixiv.model.IllustData;
|
||||
import org.astral.findmaimaiultra.been.pixiv.model.PixivResponse;
|
||||
import org.astral.findmaimaiultra.been.pixiv.model.pages.PagePixivResponse;
|
||||
import org.astral.findmaimaiultra.been.pixiv.model.pages.photo.Photo;
|
||||
import org.astral.findmaimaiultra.been.pixiv.model.pages.photo.PhotoResponse;
|
||||
import org.astral.findmaimaiultra.been.pixiv.model.pages.photo.Urls;
|
||||
import org.astral.findmaimaiultra.databinding.FragmentHomeBinding;
|
||||
import org.astral.findmaimaiultra.databinding.FragmentPixivBinding;
|
||||
import org.astral.findmaimaiultra.ui.MainActivity;
|
||||
import org.astral.findmaimaiultra.ui.JMActivity;
|
||||
import org.astral.findmaimaiultra.ui.PageActivity;
|
||||
import org.astral.findmaimaiultra.ui.home.HomeViewModel;
|
||||
import org.astral.findmaimaiultra.utill.AddressParser;
|
||||
import org.astral.findmaimaiultra.utill.SharedViewModel;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.*;
|
||||
import java.lang.reflect.Type;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.net.URL;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
|
||||
public class PixivFragment extends Fragment {
|
||||
private RecyclerView recyclerView;
|
||||
private Handler handler = new Handler(Looper.getMainLooper());
|
||||
@@ -142,19 +131,29 @@ public class PixivFragment extends Fragment {
|
||||
recyclerView.setLayoutManager(new LinearLayoutManager(requireContext()));
|
||||
recyclerView.setAdapter(adapter);
|
||||
// 设置搜索框的查询监听器
|
||||
|
||||
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
|
||||
@Override
|
||||
public boolean onQueryTextSubmit(String query) {
|
||||
// 显示 Snackbar 提示“正在搜索”
|
||||
RadioGroup radioGroup = binding.radioGroup2;
|
||||
|
||||
|
||||
Snackbar snackbar = Snackbar.make(root, "正在搜索...", Snackbar.LENGTH_INDEFINITE);
|
||||
snackbar.setAnchorView(searchView); // 设置 Snackbar 锚定到搜索框
|
||||
snackbar.show();
|
||||
|
||||
//获取单选框
|
||||
int checkedRadioButtonId = radioGroup.getCheckedRadioButtonId();
|
||||
adapter.update(new ArrayList<>());
|
||||
adapter.notifyDataSetChanged();
|
||||
|
||||
// 当用户提交查询时调用 fetchData 方法
|
||||
if (checkedRadioButtonId == R.id.pb) {
|
||||
fetchData(query, 1, snackbar);
|
||||
} else if (checkedRadioButtonId == R.id.jmb) {
|
||||
fetchDataJM(query, 1, snackbar);
|
||||
}else if (checkedRadioButtonId == R.id.maimai) {
|
||||
fetchDataMai(query, 1, snackbar);
|
||||
}
|
||||
// 显示搜索结果布局,隐藏 RecyclerView
|
||||
path1.setVisibility(View.GONE);
|
||||
path2.setVisibility(View.VISIBLE);
|
||||
@@ -171,7 +170,106 @@ public class PixivFragment extends Fragment {
|
||||
return root;
|
||||
}
|
||||
|
||||
private void fetchDataMai(String query, int i, Snackbar snackbar) {
|
||||
OkHttpClient client = new OkHttpClient();
|
||||
Request request = new Request.Builder()
|
||||
.url("http://mai.godserver.cn:11451/api/mai/v1/searchAll?query=" + query )
|
||||
.build();
|
||||
snackbar.dismiss();
|
||||
client.newCall(request).enqueue(new Callback() {
|
||||
@Override
|
||||
public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
|
||||
String json = response.body().string();
|
||||
if (response.isSuccessful()) {
|
||||
List<Place> dataList = new Gson().fromJson(json, new TypeToken<List<Place>>() {
|
||||
}.getType());
|
||||
List<IllustData> dataList2 = new ArrayList<>();
|
||||
for (Place place : dataList) {
|
||||
IllustData illustData = new IllustData();
|
||||
illustData.setId("Place:"+place.getId());
|
||||
illustData.setTitle(place.getName());
|
||||
illustData.setAlt(place.getProvince());
|
||||
illustData.setUrl(place.getAddress());
|
||||
illustData.setDescription(new Gson().toJson(place,Place.class));
|
||||
dataList2.add(illustData);
|
||||
}
|
||||
handler.post(() -> {
|
||||
path2.setVisibility(View.VISIBLE);
|
||||
recyclerView.setVisibility(View.VISIBLE);
|
||||
adapter.update(dataList2);
|
||||
adapter.notifyDataSetChanged();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NotNull Call call, @NotNull IOException e) {
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void fetchDataJM(String query, int i, Snackbar snackbar) {
|
||||
OkHttpClient client = new OkHttpClient();
|
||||
int type =0;
|
||||
Request request = new Request.Builder()
|
||||
.url("http://jm.godserver.cn:35621/search?search_query=" + query + "&page=1")
|
||||
.build();
|
||||
if (query.matches("\\d+")) {
|
||||
request = new Request.Builder()
|
||||
.url("jm.godserver.cn:35621/album/" + query + "/")
|
||||
.build();
|
||||
type = 1;
|
||||
}
|
||||
snackbar = Snackbar.make(requireView(), "加载中", Snackbar.LENGTH_SHORT);
|
||||
snackbar.show();
|
||||
int finalType = type;
|
||||
Snackbar finalSnackbar = snackbar;
|
||||
client.newCall(request).enqueue(new Callback() {
|
||||
@Override
|
||||
public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
|
||||
String json = response.body().string();
|
||||
if (response.isSuccessful()) {
|
||||
if(finalType == 0) {
|
||||
System.out.println(json);
|
||||
Gson gson = new Gson();
|
||||
Type listType = new TypeToken<List<AlbumItem>>() {}.getType();
|
||||
List<AlbumItem> albumItems = gson.fromJson(json, listType);
|
||||
|
||||
List<IllustData> dataList = new ArrayList<>();
|
||||
for (AlbumItem item : albumItems) {
|
||||
IllustData illustData = new IllustData();
|
||||
illustData.setId(item.getAlbum_id());
|
||||
illustData.setTitle(item.getTitle());
|
||||
illustData.setUrl("JM:" + item.getAlbum_id());
|
||||
System.out.println(item.getAlbum_id());
|
||||
dataList.add(illustData);
|
||||
}
|
||||
|
||||
handler.post(() -> {
|
||||
path2.setVisibility(View.VISIBLE);
|
||||
recyclerView.setVisibility(View.VISIBLE);
|
||||
adapter.update(dataList);
|
||||
adapter.notifyDataSetChanged();
|
||||
// 隐藏 Snackbar
|
||||
finalSnackbar.dismiss();
|
||||
});
|
||||
}else if (finalType == 1) {
|
||||
Album albumItem = new Gson().fromJson(json, Album.class);
|
||||
openJMProject(albumItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NotNull Call call, @NotNull IOException e) {
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void fetchData(String word, int page, Snackbar snackbar) {
|
||||
|
||||
OkHttpClient client = new OkHttpClient();
|
||||
//设置超时时间60s
|
||||
client.newBuilder().connectTimeout(60, TimeUnit.SECONDS);
|
||||
@@ -257,6 +355,18 @@ public class PixivFragment extends Fragment {
|
||||
|
||||
@SuppressLint("MissingInflatedId")
|
||||
private void openIllustData(IllustData illustData) {
|
||||
if (illustData.getUrl().startsWith("JM:")) {
|
||||
Snackbar snackbar = Snackbar.make(binding.getRoot(), "正在获取数据", Snackbar.LENGTH_LONG);
|
||||
snackbar.show();
|
||||
openJM(illustData,snackbar);
|
||||
return;
|
||||
}
|
||||
if (illustData.getId().startsWith("Place:")) {
|
||||
Snackbar snackbar = Snackbar.make(binding.getRoot(), "正在获取数据", Snackbar.LENGTH_SHORT);
|
||||
snackbar.show();
|
||||
openPlace(illustData);
|
||||
return;
|
||||
}
|
||||
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(requireContext());
|
||||
builder.setTitle(illustData.getTitle());
|
||||
Log.d("PixivFragment", "openIllustData: " + illustData.getTitle());
|
||||
@@ -354,6 +464,159 @@ public class PixivFragment extends Fragment {
|
||||
// 显示对话框
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
private void openPlace(IllustData illustData) {
|
||||
Place place = new Gson().fromJson(illustData.getDescription(), Place.class);
|
||||
Intent intent = new Intent(context, PageActivity.class);
|
||||
intent.putExtra("id", place.getId());
|
||||
intent.putExtra("name", place.getName());
|
||||
intent.putExtra("address", place.getAddress());
|
||||
intent.putExtra("province", place.getProvince());
|
||||
intent.putExtra("city", place.getCity());
|
||||
intent.putExtra("area", place.getArea());
|
||||
intent.putExtra("x", place.getX());
|
||||
intent.putExtra("y", place.getY());
|
||||
intent.putExtra("count", place.getCount());
|
||||
intent.putExtra("bad", place.getBad());
|
||||
intent.putExtra("good", place.getGood());
|
||||
intent.putExtra("num", place.getNum());
|
||||
intent.putExtra("numJ", place.getNumJ());
|
||||
intent.putExtra("meituan", place.getMeituan_link());
|
||||
intent.putExtra("douyin", place.getDouyin_link());
|
||||
startActivity(intent);
|
||||
}
|
||||
|
||||
private void openJM(IllustData illustData,Snackbar snackbar) {
|
||||
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(requireContext());
|
||||
builder.setTitle(illustData.getTitle());
|
||||
//snackbar长显示
|
||||
snackbar = Snackbar.make(requireView(), "正在加载", Snackbar.LENGTH_INDEFINITE);
|
||||
snackbar.show();
|
||||
OkHttpClient httpClient = new OkHttpClient();
|
||||
//配置超时
|
||||
httpClient.newBuilder().connectTimeout(120, TimeUnit.SECONDS);
|
||||
httpClient.newBuilder().readTimeout(120, TimeUnit.SECONDS);
|
||||
httpClient.newBuilder().writeTimeout(120, TimeUnit.SECONDS);
|
||||
|
||||
Request request = new Request.Builder()
|
||||
.url("http://jm.godserver.cn:35621/album/" + illustData.getId() + "/")
|
||||
.build();
|
||||
Log.d("MainLaunch", "http://jm.godserver.cn:35621/album/" + illustData.getId() + "/");
|
||||
//配置超时
|
||||
|
||||
Snackbar finalSnackbar = snackbar;
|
||||
httpClient.newCall(request).enqueue(new Callback() {
|
||||
|
||||
@Override
|
||||
public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
|
||||
String res = response.body().string();
|
||||
if (response.isSuccessful()) {
|
||||
Log.d("PixivFragment", "onResponse: " + res);
|
||||
finalSnackbar.dismiss();
|
||||
Album a = new Gson().fromJson(res, Album.class);
|
||||
openJMProject(a);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NotNull Call call, @NotNull IOException e) {
|
||||
handler.post(()->{
|
||||
Toast.makeText(requireContext(), e.getMessage(), Toast.LENGTH_SHORT).show();
|
||||
finalSnackbar.dismiss();
|
||||
});
|
||||
Log.d("PixivFragment", "onFailure: " + e.getMessage());
|
||||
}
|
||||
});
|
||||
}
|
||||
private Bitmap decodeImage(Bitmap imgSrc, int num) {
|
||||
if (num == 0) {
|
||||
return imgSrc;
|
||||
}
|
||||
|
||||
int w = imgSrc.getWidth();
|
||||
int h = imgSrc.getHeight();
|
||||
|
||||
// 创建新的解密图片
|
||||
Bitmap imgDecode = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
|
||||
Canvas canvas = new Canvas(imgDecode);
|
||||
|
||||
int over = h % num;
|
||||
for (int i = 0; i < num; i++) {
|
||||
int move = h / num;
|
||||
int ySrc = h - (move * (i + 1)) - over;
|
||||
int yDst = move * i;
|
||||
|
||||
if (i == 0) {
|
||||
move += over;
|
||||
} else {
|
||||
yDst += over;
|
||||
}
|
||||
|
||||
Rect srcRect = new Rect(0, ySrc, w, ySrc + move);
|
||||
Rect dstRect = new Rect(0, yDst, w, yDst + move);
|
||||
|
||||
canvas.drawBitmap(imgSrc, srcRect, dstRect, null);
|
||||
}
|
||||
|
||||
return imgDecode;
|
||||
}
|
||||
|
||||
private void loadImageFromUrl(String url, int num, LinearLayout li) {
|
||||
// 使用 Glide 加载图片
|
||||
Glide.with(requireContext())
|
||||
.asBitmap()
|
||||
.load(url)
|
||||
.into(new CustomTarget<Bitmap>() {
|
||||
@Override
|
||||
public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition<? super Bitmap> transition) {
|
||||
Bitmap decodedBitmap = decodeImage(resource, num); // 假设 num 为 4,根据实际情况调整
|
||||
|
||||
// 更新 UI
|
||||
handler.post(() -> {
|
||||
ImageView photoView = new ImageView(getContext());
|
||||
photoView.setImageBitmap(decodedBitmap);
|
||||
photoView.setScaleType(ImageView.ScaleType.CENTER_CROP); // 设置图片缩放类型
|
||||
photoView.setAdjustViewBounds(true); // 调整视图边界
|
||||
|
||||
// 设置布局参数
|
||||
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
|
||||
LinearLayout.LayoutParams.MATCH_PARENT,
|
||||
LinearLayout.LayoutParams.WRAP_CONTENT
|
||||
);
|
||||
layoutParams.setMargins(0, 0, 0, 0); // 设置间距为0
|
||||
photoView.setLayoutParams(layoutParams);
|
||||
|
||||
li.addView(photoView);
|
||||
Log.d("t111111111", url);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadCleared(@Nullable Drawable placeholder) {
|
||||
// 处理加载清除的情况
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadFailed(@Nullable Drawable errorDrawable) {
|
||||
super.onLoadFailed(errorDrawable);
|
||||
handler.post(() -> {
|
||||
Toast.makeText(requireContext(), "图片加载失败", Toast.LENGTH_SHORT).show();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@SuppressLint("MissingInflatedId")
|
||||
private void openJMProject(Album a) {
|
||||
Intent intent = new Intent(requireContext(), JMActivity.class);
|
||||
intent.putExtra("album", new Gson().toJson(a));
|
||||
startActivity(intent);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private void download(String url) {
|
||||
//复制
|
||||
ClipboardManager clipboardManager = (ClipboardManager) requireContext().getSystemService(Context.CLIPBOARD_SERVICE);
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
package org.astral.findmaimaiultra.utill;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Environment;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class FileUtils {
|
||||
public static File getCacheDir(Context context, String fileName) {
|
||||
File cacheDir = new File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), "FindMaimaiUltra");
|
||||
if (!cacheDir.exists()) {
|
||||
cacheDir.mkdirs();
|
||||
}
|
||||
return new File(cacheDir, fileName);
|
||||
}
|
||||
}
|
||||
7
app/src/main/res/anim/slide_down.xml
Normal file
7
app/src/main/res/anim/slide_down.xml
Normal file
@@ -0,0 +1,7 @@
|
||||
|
||||
<set xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<translate
|
||||
android:fromYDelta="-100%p"
|
||||
android:toYDelta="0"
|
||||
android:duration="300"/>
|
||||
</set>
|
||||
7
app/src/main/res/anim/slide_up.xml
Normal file
7
app/src/main/res/anim/slide_up.xml
Normal file
@@ -0,0 +1,7 @@
|
||||
|
||||
<set xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<translate
|
||||
android:fromYDelta="0"
|
||||
android:toYDelta="-100%p"
|
||||
android:duration="300"/>
|
||||
</set>
|
||||
@@ -1,4 +1,3 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
@@ -28,11 +27,39 @@
|
||||
android:layout_margin="16dp"
|
||||
style="@style/CustomSearchView" />
|
||||
|
||||
<!-- 单选按钮组 -->
|
||||
<RadioGroup
|
||||
android:id="@+id/radioGroup2"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:layout_marginTop="8dp">
|
||||
|
||||
<RadioButton
|
||||
android:id="@+id/pb"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:checked="true"
|
||||
android:text="Pixiv" />
|
||||
|
||||
<RadioButton
|
||||
android:id="@+id/jmb"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="JM" />
|
||||
|
||||
<RadioButton
|
||||
android:id="@+id/maimai"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Maimai" />
|
||||
</RadioGroup>
|
||||
|
||||
<!-- TextView -->
|
||||
<com.google.android.material.textview.MaterialTextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="FindPixiv"
|
||||
android:text="FindMaimai Engine"
|
||||
android:textSize="18sp"
|
||||
android:layout_marginTop="8dp" />
|
||||
</LinearLayout>
|
||||
|
||||
51
app/src/main/res/layout/jm_dialog.xml
Normal file
51
app/src/main/res/layout/jm_dialog.xml
Normal file
@@ -0,0 +1,51 @@
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:id="@+id/back"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/recyclerView"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"/>
|
||||
|
||||
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent">
|
||||
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
|
||||
android:id="@+id/bottom_sheet"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:minHeight="100dp"
|
||||
android:background="@android:color/white"
|
||||
app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior">
|
||||
<LinearLayout
|
||||
android:id="@+id/bac"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:padding="16dp">
|
||||
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="32sp"
|
||||
android:textColor="@color/colorSecondaryVariant"
|
||||
android:id="@+id/menu"/>
|
||||
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="18sp"
|
||||
android:textColor="@color/colorSecondaryVariant"
|
||||
android:id="@+id/dec"/>
|
||||
</LinearLayout>
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
11
app/src/main/res/layout/overlay_layout.xml
Normal file
11
app/src/main/res/layout/overlay_layout.xml
Normal file
@@ -0,0 +1,11 @@
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/overlay"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="#80000000"
|
||||
android:visibility="gone"
|
||||
android:clickable="true"
|
||||
android:focusable="true">
|
||||
<TextView android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/title"/>
|
||||
<!-- 你可以在这里添加其他 UI 元素,例如按钮或文本 -->
|
||||
</FrameLayout>
|
||||
11
app/src/main/res/layout/photo_item.xml
Normal file
11
app/src/main/res/layout/photo_item.xml
Normal file
@@ -0,0 +1,11 @@
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/photo"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:adjustViewBounds="true"
|
||||
android:scaleType="centerCrop"/>
|
||||
</FrameLayout>
|
||||
@@ -39,7 +39,7 @@
|
||||
<string name="nav_header_title">FindMaimaiDX</string>
|
||||
<string name="nav_header_subtitle">Reisa</string>
|
||||
<string name="action_settings">设置</string>
|
||||
<string name="menu_pixiv">pixiv</string>
|
||||
<string name="menu_pixiv">Image</string>
|
||||
|
||||
|
||||
</resources>
|
||||
Reference in New Issue
Block a user