JM更新
This commit is contained in:
@@ -45,7 +45,6 @@
|
|||||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||||
<uses-permission android:name="android.permission.WRITE_SETTINGS" tools:ignore="ProtectedPermissions"/>
|
<uses-permission android:name="android.permission.WRITE_SETTINGS" tools:ignore="ProtectedPermissions"/>
|
||||||
|
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:allowBackup="true"
|
android:allowBackup="true"
|
||||||
android:fullBackupContent="@xml/backup_rules"
|
android:fullBackupContent="@xml/backup_rules"
|
||||||
@@ -123,6 +122,7 @@
|
|||||||
android:screenOrientation="fullSensor"
|
android:screenOrientation="fullSensor"
|
||||||
android:theme="@style/Theme.AppCompat.Light.NoActionBar"
|
android:theme="@style/Theme.AppCompat.Light.NoActionBar"
|
||||||
tools:ignore="MissingClass" />
|
tools:ignore="MissingClass" />
|
||||||
|
<activity android:name=".ui.JMActivity" android:theme="@style/Theme.FindMaimaiUltra.NoActionBar" android:label="FindMaimai Engine"/>
|
||||||
<service
|
<service
|
||||||
android:hardwareAccelerated="true"
|
android:hardwareAccelerated="true"
|
||||||
android:name="org.astral.findmaimaiultra.utill.updater.vpn.core.LocalVpnService"
|
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;
|
package org.astral.findmaimaiultra.adapter;
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.graphics.BitmapFactory;
|
import android.graphics.BitmapFactory;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
@@ -49,15 +50,21 @@ public class PixivAdapter extends RecyclerView.Adapter<PixivAdapter.ViewHolder>
|
|||||||
return new ViewHolder(view);
|
return new ViewHolder(view);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressLint("SetTextI18n")
|
||||||
@Override
|
@Override
|
||||||
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
|
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
|
||||||
IllustData data = dataList.get(position);
|
IllustData data = dataList.get(position);
|
||||||
holder.title.setText(data.getTitle());
|
holder.title.setText(data.getTitle());
|
||||||
// Load image using a library like Glide or Picasso
|
// Load image using a library like Glide or Picasso
|
||||||
String imageUrl = "http://43.153.174.191:45678/api/v1/pixiv/toTencent?id=" + data.getId();
|
if (data.getUrl().startsWith("JM:")) {
|
||||||
|
holder.title.setText("[" + data.getId() + "] " +data.getTitle());
|
||||||
if (imageUrl != null) {
|
}else if (data.getId().startsWith("Place:")) {
|
||||||
loadImage(holder.backgroundLayout, imageUrl);
|
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 -> {
|
holder.itemView.setOnClickListener(v -> {
|
||||||
|
|||||||
@@ -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;
|
package org.astral.findmaimaiultra.ui.pixiv;
|
||||||
|
|
||||||
import android.Manifest;
|
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
import android.app.Activity;
|
|
||||||
import android.content.*;
|
import android.content.*;
|
||||||
import android.content.pm.PackageInfo;
|
|
||||||
import android.content.pm.PackageManager;
|
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.graphics.BitmapFactory;
|
import android.graphics.BitmapFactory;
|
||||||
import android.graphics.Canvas;
|
import android.graphics.Canvas;
|
||||||
import android.graphics.Paint;
|
import android.graphics.Rect;
|
||||||
import android.graphics.drawable.BitmapDrawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.location.Address;
|
|
||||||
import android.location.*;
|
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Environment;
|
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
@@ -23,52 +16,48 @@ import android.view.*;
|
|||||||
import android.widget.*;
|
import android.widget.*;
|
||||||
import androidx.activity.OnBackPressedCallback;
|
import androidx.activity.OnBackPressedCallback;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
import androidx.appcompat.app.AlertDialog;
|
import androidx.appcompat.app.AlertDialog;
|
||||||
import androidx.appcompat.widget.SearchView;
|
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.fragment.app.Fragment;
|
||||||
import androidx.lifecycle.ViewModelProvider;
|
import androidx.lifecycle.ViewModelProvider;
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
import com.bumptech.glide.Glide;
|
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.button.MaterialButton;
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||||
import com.google.android.material.snackbar.Snackbar;
|
import com.google.android.material.snackbar.Snackbar;
|
||||||
import com.google.gson.Gson;
|
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 com.google.gson.reflect.TypeToken;
|
||||||
import okhttp3.*;
|
import okhttp3.*;
|
||||||
import org.astral.findmaimaiultra.R;
|
import org.astral.findmaimaiultra.R;
|
||||||
import org.astral.findmaimaiultra.adapter.MusicRatingAdapter;
|
|
||||||
import org.astral.findmaimaiultra.adapter.PixivAdapter;
|
import org.astral.findmaimaiultra.adapter.PixivAdapter;
|
||||||
import org.astral.findmaimaiultra.adapter.PlaceAdapter;
|
import org.astral.findmaimaiultra.been.Place;
|
||||||
import org.astral.findmaimaiultra.been.*;
|
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.IllustData;
|
||||||
import org.astral.findmaimaiultra.been.pixiv.model.PixivResponse;
|
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.PagePixivResponse;
|
||||||
import org.astral.findmaimaiultra.been.pixiv.model.pages.photo.Photo;
|
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.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.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.PageActivity;
|
||||||
import org.astral.findmaimaiultra.ui.home.HomeViewModel;
|
import org.astral.findmaimaiultra.ui.home.HomeViewModel;
|
||||||
import org.astral.findmaimaiultra.utill.AddressParser;
|
|
||||||
import org.astral.findmaimaiultra.utill.SharedViewModel;
|
import org.astral.findmaimaiultra.utill.SharedViewModel;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
import java.text.SimpleDateFormat;
|
import java.net.URL;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
|
||||||
public class PixivFragment extends Fragment {
|
public class PixivFragment extends Fragment {
|
||||||
private RecyclerView recyclerView;
|
private RecyclerView recyclerView;
|
||||||
private Handler handler = new Handler(Looper.getMainLooper());
|
private Handler handler = new Handler(Looper.getMainLooper());
|
||||||
@@ -142,19 +131,29 @@ public class PixivFragment extends Fragment {
|
|||||||
recyclerView.setLayoutManager(new LinearLayoutManager(requireContext()));
|
recyclerView.setLayoutManager(new LinearLayoutManager(requireContext()));
|
||||||
recyclerView.setAdapter(adapter);
|
recyclerView.setAdapter(adapter);
|
||||||
// 设置搜索框的查询监听器
|
// 设置搜索框的查询监听器
|
||||||
|
|
||||||
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
|
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
|
||||||
@Override
|
@Override
|
||||||
public boolean onQueryTextSubmit(String query) {
|
public boolean onQueryTextSubmit(String query) {
|
||||||
// 显示 Snackbar 提示“正在搜索”
|
// 显示 Snackbar 提示“正在搜索”
|
||||||
|
RadioGroup radioGroup = binding.radioGroup2;
|
||||||
|
|
||||||
|
|
||||||
Snackbar snackbar = Snackbar.make(root, "正在搜索...", Snackbar.LENGTH_INDEFINITE);
|
Snackbar snackbar = Snackbar.make(root, "正在搜索...", Snackbar.LENGTH_INDEFINITE);
|
||||||
snackbar.setAnchorView(searchView); // 设置 Snackbar 锚定到搜索框
|
snackbar.setAnchorView(searchView); // 设置 Snackbar 锚定到搜索框
|
||||||
snackbar.show();
|
snackbar.show();
|
||||||
|
//获取单选框
|
||||||
|
int checkedRadioButtonId = radioGroup.getCheckedRadioButtonId();
|
||||||
adapter.update(new ArrayList<>());
|
adapter.update(new ArrayList<>());
|
||||||
adapter.notifyDataSetChanged();
|
adapter.notifyDataSetChanged();
|
||||||
|
|
||||||
// 当用户提交查询时调用 fetchData 方法
|
// 当用户提交查询时调用 fetchData 方法
|
||||||
fetchData(query, 1, snackbar);
|
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
|
// 显示搜索结果布局,隐藏 RecyclerView
|
||||||
path1.setVisibility(View.GONE);
|
path1.setVisibility(View.GONE);
|
||||||
path2.setVisibility(View.VISIBLE);
|
path2.setVisibility(View.VISIBLE);
|
||||||
@@ -171,7 +170,106 @@ public class PixivFragment extends Fragment {
|
|||||||
return root;
|
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) {
|
private void fetchData(String word, int page, Snackbar snackbar) {
|
||||||
|
|
||||||
OkHttpClient client = new OkHttpClient();
|
OkHttpClient client = new OkHttpClient();
|
||||||
//设置超时时间60s
|
//设置超时时间60s
|
||||||
client.newBuilder().connectTimeout(60, TimeUnit.SECONDS);
|
client.newBuilder().connectTimeout(60, TimeUnit.SECONDS);
|
||||||
@@ -257,6 +355,18 @@ public class PixivFragment extends Fragment {
|
|||||||
|
|
||||||
@SuppressLint("MissingInflatedId")
|
@SuppressLint("MissingInflatedId")
|
||||||
private void openIllustData(IllustData illustData) {
|
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());
|
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(requireContext());
|
||||||
builder.setTitle(illustData.getTitle());
|
builder.setTitle(illustData.getTitle());
|
||||||
Log.d("PixivFragment", "openIllustData: " + illustData.getTitle());
|
Log.d("PixivFragment", "openIllustData: " + illustData.getTitle());
|
||||||
@@ -354,6 +464,159 @@ public class PixivFragment extends Fragment {
|
|||||||
// 显示对话框
|
// 显示对话框
|
||||||
dialog.show();
|
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) {
|
private void download(String url) {
|
||||||
//复制
|
//复制
|
||||||
ClipboardManager clipboardManager = (ClipboardManager) requireContext().getSystemService(Context.CLIPBOARD_SERVICE);
|
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
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
@@ -28,11 +27,39 @@
|
|||||||
android:layout_margin="16dp"
|
android:layout_margin="16dp"
|
||||||
style="@style/CustomSearchView" />
|
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 -->
|
<!-- TextView -->
|
||||||
<com.google.android.material.textview.MaterialTextView
|
<com.google.android.material.textview.MaterialTextView
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="FindPixiv"
|
android:text="FindMaimai Engine"
|
||||||
android:textSize="18sp"
|
android:textSize="18sp"
|
||||||
android:layout_marginTop="8dp" />
|
android:layout_marginTop="8dp" />
|
||||||
</LinearLayout>
|
</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_title">FindMaimaiDX</string>
|
||||||
<string name="nav_header_subtitle">Reisa</string>
|
<string name="nav_header_subtitle">Reisa</string>
|
||||||
<string name="action_settings">设置</string>
|
<string name="action_settings">设置</string>
|
||||||
<string name="menu_pixiv">pixiv</string>
|
<string name="menu_pixiv">Image</string>
|
||||||
|
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
Reference in New Issue
Block a user