This commit is contained in:
2025-04-08 23:05:25 +08:00
parent a71d53e8c4
commit 149e156e24
41 changed files with 2647 additions and 3 deletions

View File

@@ -74,4 +74,5 @@ dependencies {
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
implementation 'jp.wasabeef:glide-transformations:4.3.0' implementation 'jp.wasabeef:glide-transformations:4.3.0'
} }

View File

@@ -0,0 +1,119 @@
package org.astral.findmaimaiultra.adapter;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.request.RequestOptions;
import com.bumptech.glide.signature.ObjectKey;
import jp.wasabeef.glide.transformations.BlurTransformation;
import okhttp3.*;
import org.astral.findmaimaiultra.R;
import org.astral.findmaimaiultra.been.pixiv.model.IllustData;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
public class PixivAdapter extends RecyclerView.Adapter<PixivAdapter.ViewHolder> {
private List<IllustData> dataList;
private OnItemClickListener listener;
public PixivAdapter(List<IllustData> dataList) {
this.dataList = dataList;
}
public void update(List<IllustData> newDataList) {
this.dataList = newDataList;
notifyDataSetChanged();
}
public void setOnItemClickListener(OnItemClickListener listener) {
this.listener = listener;
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_pixiv, parent, false);
return new ViewHolder(view);
}
@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
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) {
listener.onItemClick(data);
}
});
}
@Override
public int getItemCount() {
return dataList.size();
}
public static class ViewHolder extends RecyclerView.ViewHolder {
public TextView title;
public ImageView backgroundLayout;
public ViewHolder(View itemView) {
super(itemView);
backgroundLayout = itemView.findViewById(R.id.backgroundLayout);
title = itemView.findViewById(R.id.title);
}
}
private void loadImage(ImageView imageView, String url) {
Request request = new Request.Builder()
.url(url)
.build();
OkHttpClient client = new OkHttpClient();
client.newBuilder().connectTimeout(180, TimeUnit.SECONDS);
client.newBuilder().readTimeout(180, TimeUnit.SECONDS);
client.newBuilder().writeTimeout(180, TimeUnit.SECONDS);
Log.d("Web", url);
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
Log.e("PixivAdapter", "Failed to load image: " + e.getMessage());
}
@Override
public void onResponse(Call call, Response response) throws IOException {
if (response.isSuccessful()) {
byte[] imageBytes = response.body().bytes();
Bitmap bitmap = BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.length);
if (bitmap != null) {
imageView.post(() -> imageView.setImageBitmap(bitmap));
}
} else {
Log.e("PixivAdapter", "Failed to load image: " + response.code());
}
}
});
}
public interface OnItemClickListener {
void onItemClick(IllustData illustData);
}
}

View File

@@ -0,0 +1,72 @@
package org.astral.findmaimaiultra.been.pixiv.model;
import com.google.gson.annotations.SerializedName;
import java.util.List;
public class Body {
@SerializedName("illustManga")
public IllustManga illustManga;
@SerializedName("popular")
public Popular popular;
@SerializedName("relatedTags")
public List<String> relatedTags;
@SerializedName("tagTranslation")
public TagTranslation tagTranslation;
@SerializedName("zoneConfig")
public ZoneConfig zoneConfig;
@SerializedName("extraData")
public ExtraData extraData;
public List<String> getRelatedTags() {
return relatedTags;
}
public void setRelatedTags(List<String> relatedTags) {
this.relatedTags = relatedTags;
}
public TagTranslation getTagTranslation() {
return tagTranslation;
}
public void setTagTranslation(TagTranslation tagTranslation) {
this.tagTranslation = tagTranslation;
}
public ZoneConfig getZoneConfig() {
return zoneConfig;
}
public void setZoneConfig(ZoneConfig zoneConfig) {
this.zoneConfig = zoneConfig;
}
public ExtraData getExtraData() {
return extraData;
}
public void setExtraData(ExtraData extraData) {
this.extraData = extraData;
}
public IllustManga getIllustManga() {
return illustManga;
}
public void setIllustManga(IllustManga illustManga) {
this.illustManga = illustManga;
}
public Popular getPopular() {
return popular;
}
public void setPopular(Popular popular) {
this.popular = popular;
}
}

View File

@@ -0,0 +1,27 @@
package org.astral.findmaimaiultra.been.pixiv.model;
import com.google.gson.annotations.SerializedName;
public class BookmarkRange {
@SerializedName("min")
public Integer min;
@SerializedName("max")
public Integer max;
public Integer getMin() {
return min;
}
public void setMin(Integer min) {
this.min = min;
}
public Integer getMax() {
return max;
}
public void setMax(Integer max) {
this.max = max;
}
}

View File

@@ -0,0 +1,5 @@
package org.astral.findmaimaiultra.been.pixiv.model;
public class ExtraData {
// 根据实际需要添加字段
}

View File

@@ -0,0 +1,282 @@
package org.astral.findmaimaiultra.been.pixiv.model;
import com.google.gson.annotations.SerializedName;
import java.util.List;
public class IllustData {
@SerializedName("id")
public String id;
@SerializedName("title")
public String title;
@SerializedName("illustType")
public int illustType;
@SerializedName("xRestrict")
public int xRestrict;
@SerializedName("restrict")
public int restrict;
@SerializedName("sl")
public int sl;
@SerializedName("url")
public String url;
@SerializedName("description")
public String description;
@SerializedName("tags")
public List<String> tags;
@SerializedName("userId")
public String userId;
@SerializedName("userName")
public String userName;
@SerializedName("width")
public int width;
@SerializedName("height")
public int height;
@SerializedName("pageCount")
public int pageCount;
@SerializedName("isBookmarkable")
public boolean isBookmarkable;
@SerializedName("bookmarkData")
public Object bookmarkData;
@SerializedName("alt")
public String alt;
@SerializedName("titleCaptionTranslation")
public TitleCaptionTranslation titleCaptionTranslation;
@SerializedName("createDate")
public String createDate;
@SerializedName("updateDate")
public String updateDate;
@SerializedName("isUnlisted")
public boolean isUnlisted;
@SerializedName("isMasked")
public boolean isMasked;
@SerializedName("aiType")
public int aiType;
@SerializedName("visibilityScope")
public int visibilityScope;
@SerializedName("profileImageUrl")
public String profileImageUrl;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public int getIllustType() {
return illustType;
}
public void setIllustType(int illustType) {
this.illustType = illustType;
}
public int getxRestrict() {
return xRestrict;
}
public void setxRestrict(int xRestrict) {
this.xRestrict = xRestrict;
}
public int getRestrict() {
return restrict;
}
public void setRestrict(int restrict) {
this.restrict = restrict;
}
public int getSl() {
return sl;
}
public void setSl(int sl) {
this.sl = sl;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public List<String> getTags() {
return tags;
}
public void setTags(List<String> tags) {
this.tags = tags;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public int getWidth() {
return width;
}
public void setWidth(int width) {
this.width = width;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
public int getPageCount() {
return pageCount;
}
public void setPageCount(int pageCount) {
this.pageCount = pageCount;
}
public boolean isBookmarkable() {
return isBookmarkable;
}
public void setBookmarkable(boolean bookmarkable) {
isBookmarkable = bookmarkable;
}
public Object getBookmarkData() {
return bookmarkData;
}
public void setBookmarkData(Object bookmarkData) {
this.bookmarkData = bookmarkData;
}
public String getAlt() {
return alt;
}
public void setAlt(String alt) {
this.alt = alt;
}
public TitleCaptionTranslation getTitleCaptionTranslation() {
return titleCaptionTranslation;
}
public void setTitleCaptionTranslation(TitleCaptionTranslation titleCaptionTranslation) {
this.titleCaptionTranslation = titleCaptionTranslation;
}
public String getCreateDate() {
return createDate;
}
public void setCreateDate(String createDate) {
this.createDate = createDate;
}
public String getUpdateDate() {
return updateDate;
}
public void setUpdateDate(String updateDate) {
this.updateDate = updateDate;
}
public boolean isUnlisted() {
return isUnlisted;
}
public void setUnlisted(boolean unlisted) {
isUnlisted = unlisted;
}
public boolean isMasked() {
return isMasked;
}
public void setMasked(boolean masked) {
isMasked = masked;
}
public int getAiType() {
return aiType;
}
public void setAiType(int aiType) {
this.aiType = aiType;
}
public int getVisibilityScope() {
return visibilityScope;
}
public void setVisibilityScope(int visibilityScope) {
this.visibilityScope = visibilityScope;
}
public String getProfileImageUrl() {
return profileImageUrl;
}
public void setProfileImageUrl(String profileImageUrl) {
this.profileImageUrl = profileImageUrl;
}
}

View File

@@ -0,0 +1,51 @@
package org.astral.findmaimaiultra.been.pixiv.model;
import com.google.gson.annotations.SerializedName;
import java.util.List;
public class IllustManga {
@SerializedName("data")
public List<IllustData> data;
@SerializedName("total")
public int total;
@SerializedName("lastPage")
public int lastPage;
@SerializedName("bookmarkRanges")
public List<BookmarkRange> bookmarkRanges;
public List<IllustData> getData() {
return data;
}
public void setData(List<IllustData> data) {
this.data = data;
}
public int getTotal() {
return total;
}
public void setTotal(int total) {
this.total = total;
}
public int getLastPage() {
return lastPage;
}
public void setLastPage(int lastPage) {
this.lastPage = lastPage;
}
public List<BookmarkRange> getBookmarkRanges() {
return bookmarkRanges;
}
public void setBookmarkRanges(List<BookmarkRange> bookmarkRanges) {
this.bookmarkRanges = bookmarkRanges;
}
}

View File

@@ -0,0 +1,24 @@
package org.astral.findmaimaiultra.been.pixiv.model;
public class PixivResponse {
public boolean error;
public Body body;
public boolean isError() {
return error;
}
public void setError(boolean error) {
this.error = error;
}
public Body getBody() {
return body;
}
public void setBody(Body body) {
this.body = body;
}
}

View File

@@ -0,0 +1,29 @@
package org.astral.findmaimaiultra.been.pixiv.model;
import com.google.gson.annotations.SerializedName;
import java.util.List;
public class Popular {
@SerializedName("recent")
public List<Object> recent;
@SerializedName("permanent")
public List<Object> permanent;
public List<Object> getRecent() {
return recent;
}
public void setRecent(List<Object> recent) {
this.recent = recent;
}
public List<Object> getPermanent() {
return permanent;
}
public void setPermanent(List<Object> permanent) {
this.permanent = permanent;
}
}

View File

@@ -0,0 +1,15 @@
package org.astral.findmaimaiultra.been.pixiv.model;
import com.google.gson.annotations.SerializedName;
import java.util.Map;
public class TagTranslation {
@SerializedName("tagTranslation")
public Map<String, Translation> tagTranslation;
public static class Translation {
@SerializedName("zh")
public String zh;
}
}

View File

@@ -0,0 +1,27 @@
package org.astral.findmaimaiultra.been.pixiv.model;
import com.google.gson.annotations.SerializedName;
public class TitleCaptionTranslation {
@SerializedName("workTitle")
public String workTitle;
@SerializedName("workCaption")
public String workCaption;
public String getWorkTitle() {
return workTitle;
}
public void setWorkTitle(String workTitle) {
this.workTitle = workTitle;
}
public String getWorkCaption() {
return workCaption;
}
public void setWorkCaption(String workCaption) {
this.workCaption = workCaption;
}
}

View File

@@ -0,0 +1,81 @@
package org.astral.findmaimaiultra.been.pixiv.model;
public class Video {
private String videoId;
private String title;
private String duration;
private String uploader;
private String views;
private String rating;
private String href; // 新增字段
// Getters and Setters
public String getVideoId() {
return videoId;
}
public void setVideoId(String videoId) {
this.videoId = videoId;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDuration() {
return duration;
}
public void setDuration(String duration) {
this.duration = duration;
}
public String getUploader() {
return uploader;
}
public void setUploader(String uploader) {
this.uploader = uploader;
}
public String getViews() {
return views;
}
public void setViews(String views) {
this.views = views;
}
public String getRating() {
return rating;
}
public void setRating(String rating) {
this.rating = rating;
}
public String getHref() {
return href;
}
public void setHref(String href) {
this.href = href;
}
@Override
public String toString() {
return "Video{" +
"videoId='" + videoId + '\'' +
", title='" + title + '\'' +
", duration='" + duration + '\'' +
", uploader='" + uploader + '\'' +
", views='" + views + '\'' +
", rating='" + rating + '\'' +
", href='" + href + '\'' + // 包含href字段
'}';
}
}

View File

@@ -0,0 +1,5 @@
package org.astral.findmaimaiultra.been.pixiv.model;
public class ZoneConfig {
// 根据实际需要添加字段
}

View File

@@ -0,0 +1,14 @@
package org.astral.findmaimaiultra.been.pixiv.model.pages;
public class ExtraData {
private Meta meta;
// Getters and Setters
public Meta getMeta() {
return meta;
}
public void setMeta(Meta meta) {
this.meta = meta;
}
}

View File

@@ -0,0 +1,70 @@
package org.astral.findmaimaiultra.been.pixiv.model.pages;
import java.util.Map;
public class Meta {
private String title;
private String description;
private String canonical;
private Map<String, String> alternateLanguages;
private String descriptionHeader;
private Ogp ogp;
private Twitter twitter;
// Getters and Setters
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getCanonical() {
return canonical;
}
public void setCanonical(String canonical) {
this.canonical = canonical;
}
public Map<String, String> getAlternateLanguages() {
return alternateLanguages;
}
public void setAlternateLanguages(Map<String, String> alternateLanguages) {
this.alternateLanguages = alternateLanguages;
}
public String getDescriptionHeader() {
return descriptionHeader;
}
public void setDescriptionHeader(String descriptionHeader) {
this.descriptionHeader = descriptionHeader;
}
public Ogp getOgp() {
return ogp;
}
public void setOgp(Ogp ogp) {
this.ogp = ogp;
}
public Twitter getTwitter() {
return twitter;
}
public void setTwitter(Twitter twitter) {
this.twitter = twitter;
}
}

View File

@@ -0,0 +1,41 @@
package org.astral.findmaimaiultra.been.pixiv.model.pages;
public class Ogp {
private String description;
private String image;
private String title;
private String type;
// Getters and Setters
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getImage() {
return image;
}
public void setImage(String image) {
this.image = image;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}

View File

@@ -0,0 +1,498 @@
package org.astral.findmaimaiultra.been.pixiv.model.pages;
import java.util.Date;
import java.util.List;
import java.util.Map;
public class PageBody {
private String illustId;
private String illustTitle;
private String illustComment;
private String id;
private String title;
private String description;
private int illustType;
private Date createDate;
private Date uploadDate;
private int restrict;
private int xRestrict;
private int sl;
private Urls urls;
private Tags tags;
private String alt;
private String userId;
private String userName;
private String userAccount;
private Map<String, UserIllust> userIllusts;
private boolean likeData;
private int width;
private int height;
private int pageCount;
private int bookmarkCount;
private int likeCount;
private int commentCount;
private int responseCount;
private int viewCount;
private String bookStyle;
private boolean isHowto;
private boolean isOriginal;
private List<?> imageResponseOutData;
private List<?> imageResponseData;
private int imageResponseCount;
private Object pollData;
private Object seriesNavData;
private Object descriptionBoothId;
private Object descriptionYoutubeId;
private Object comicPromotion;
private Object fanboxPromotion;
private List<?> contestBanners;
private boolean isBookmarkable;
private Object bookmarkData;
private Object contestData;
private ZoneConfig zoneConfig;
private TitleCaptionTranslation titleCaptionTranslation;
private boolean isUnlisted;
private Object request;
private int commentOff;
private int aiType;
private Object reuploadDate;
private boolean locationMask;
private boolean commissionLinkHidden;
private boolean isLoginOnly;
// Getters and Setters
// (Add getters and setters for all fields)
public String getIllustId() {
return illustId;
}
public void setIllustId(String illustId) {
this.illustId = illustId;
}
public String getIllustTitle() {
return illustTitle;
}
public void setIllustTitle(String illustTitle) {
this.illustTitle = illustTitle;
}
public String getIllustComment() {
return illustComment;
}
public void setIllustComment(String illustComment) {
this.illustComment = illustComment;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public int getIllustType() {
return illustType;
}
public void setIllustType(int illustType) {
this.illustType = illustType;
}
public Date getCreateDate() {
return createDate;
}
public void setCreateDate(Date createDate) {
this.createDate = createDate;
}
public Date getUploadDate() {
return uploadDate;
}
public void setUploadDate(Date uploadDate) {
this.uploadDate = uploadDate;
}
public int getRestrict() {
return restrict;
}
public void setRestrict(int restrict) {
this.restrict = restrict;
}
public int getxRestrict() {
return xRestrict;
}
public void setxRestrict(int xRestrict) {
this.xRestrict = xRestrict;
}
public int getSl() {
return sl;
}
public void setSl(int sl) {
this.sl = sl;
}
public Urls getUrls() {
return urls;
}
public void setUrls(Urls urls) {
this.urls = urls;
}
public Tags getTags() {
return tags;
}
public void setTags(Tags tags) {
this.tags = tags;
}
public String getAlt() {
return alt;
}
public void setAlt(String alt) {
this.alt = alt;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getUserAccount() {
return userAccount;
}
public void setUserAccount(String userAccount) {
this.userAccount = userAccount;
}
public Map<String, UserIllust> getUserIllusts() {
return userIllusts;
}
public void setUserIllusts(Map<String, UserIllust> userIllusts) {
this.userIllusts = userIllusts;
}
public boolean isLikeData() {
return likeData;
}
public void setLikeData(boolean likeData) {
this.likeData = likeData;
}
public int getWidth() {
return width;
}
public void setWidth(int width) {
this.width = width;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
public int getPageCount() {
return pageCount;
}
public void setPageCount(int pageCount) {
this.pageCount = pageCount;
}
public int getBookmarkCount() {
return bookmarkCount;
}
public void setBookmarkCount(int bookmarkCount) {
this.bookmarkCount = bookmarkCount;
}
public int getLikeCount() {
return likeCount;
}
public void setLikeCount(int likeCount) {
this.likeCount = likeCount;
}
public int getCommentCount() {
return commentCount;
}
public void setCommentCount(int commentCount) {
this.commentCount = commentCount;
}
public int getResponseCount() {
return responseCount;
}
public void setResponseCount(int responseCount) {
this.responseCount = responseCount;
}
public int getViewCount() {
return viewCount;
}
public void setViewCount(int viewCount) {
this.viewCount = viewCount;
}
public String getBookStyle() {
return bookStyle;
}
public void setBookStyle(String bookStyle) {
this.bookStyle = bookStyle;
}
public boolean isHowto() {
return isHowto;
}
public void setHowto(boolean howto) {
isHowto = howto;
}
public boolean isOriginal() {
return isOriginal;
}
public void setOriginal(boolean original) {
isOriginal = original;
}
public List<?> getImageResponseOutData() {
return imageResponseOutData;
}
public void setImageResponseOutData(List<?> imageResponseOutData) {
this.imageResponseOutData = imageResponseOutData;
}
public List<?> getImageResponseData() {
return imageResponseData;
}
public void setImageResponseData(List<?> imageResponseData) {
this.imageResponseData = imageResponseData;
}
public int getImageResponseCount() {
return imageResponseCount;
}
public void setImageResponseCount(int imageResponseCount) {
this.imageResponseCount = imageResponseCount;
}
public Object getPollData() {
return pollData;
}
public void setPollData(Object pollData) {
this.pollData = pollData;
}
public Object getSeriesNavData() {
return seriesNavData;
}
public void setSeriesNavData(Object seriesNavData) {
this.seriesNavData = seriesNavData;
}
public Object getDescriptionBoothId() {
return descriptionBoothId;
}
public void setDescriptionBoothId(Object descriptionBoothId) {
this.descriptionBoothId = descriptionBoothId;
}
public Object getDescriptionYoutubeId() {
return descriptionYoutubeId;
}
public void setDescriptionYoutubeId(Object descriptionYoutubeId) {
this.descriptionYoutubeId = descriptionYoutubeId;
}
public Object getComicPromotion() {
return comicPromotion;
}
public void setComicPromotion(Object comicPromotion) {
this.comicPromotion = comicPromotion;
}
public Object getFanboxPromotion() {
return fanboxPromotion;
}
public void setFanboxPromotion(Object fanboxPromotion) {
this.fanboxPromotion = fanboxPromotion;
}
public List<?> getContestBanners() {
return contestBanners;
}
public void setContestBanners(List<?> contestBanners) {
this.contestBanners = contestBanners;
}
public boolean isBookmarkable() {
return isBookmarkable;
}
public void setBookmarkable(boolean bookmarkable) {
isBookmarkable = bookmarkable;
}
public Object getBookmarkData() {
return bookmarkData;
}
public void setBookmarkData(Object bookmarkData) {
this.bookmarkData = bookmarkData;
}
public Object getContestData() {
return contestData;
}
public void setContestData(Object contestData) {
this.contestData = contestData;
}
public ZoneConfig getZoneConfig() {
return zoneConfig;
}
public void setZoneConfig(ZoneConfig zoneConfig) {
this.zoneConfig = zoneConfig;
}
public TitleCaptionTranslation getTitleCaptionTranslation() {
return titleCaptionTranslation;
}
public void setTitleCaptionTranslation(TitleCaptionTranslation titleCaptionTranslation) {
this.titleCaptionTranslation = titleCaptionTranslation;
}
public boolean isUnlisted() {
return isUnlisted;
}
public void setUnlisted(boolean unlisted) {
isUnlisted = unlisted;
}
public Object getRequest() {
return request;
}
public void setRequest(Object request) {
this.request = request;
}
public int getCommentOff() {
return commentOff;
}
public void setCommentOff(int commentOff) {
this.commentOff = commentOff;
}
public int getAiType() {
return aiType;
}
public void setAiType(int aiType) {
this.aiType = aiType;
}
public Object getReuploadDate() {
return reuploadDate;
}
public void setReuploadDate(Object reuploadDate) {
this.reuploadDate = reuploadDate;
}
public boolean isLocationMask() {
return locationMask;
}
public void setLocationMask(boolean locationMask) {
this.locationMask = locationMask;
}
public boolean isCommissionLinkHidden() {
return commissionLinkHidden;
}
public void setCommissionLinkHidden(boolean commissionLinkHidden) {
this.commissionLinkHidden = commissionLinkHidden;
}
public boolean isLoginOnly() {
return isLoginOnly;
}
public void setLoginOnly(boolean loginOnly) {
isLoginOnly = loginOnly;
}
}

View File

@@ -0,0 +1,31 @@
package org.astral.findmaimaiultra.been.pixiv.model.pages;
public class PagePixivResponse {
private boolean error;
private String message;
private PageBody body;
public boolean isError() {
return error;
}
public void setError(boolean error) {
this.error = error;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public PageBody getBody() {
return body;
}
public void setBody(PageBody body) {
this.body = body;
}
}

View File

@@ -0,0 +1,50 @@
package org.astral.findmaimaiultra.been.pixiv.model.pages;
public class Tag {
private String tag;
private boolean locked;
private boolean deletable;
private String userId;
private String userName;
// Getters and Setters
public String getTag() {
return tag;
}
public void setTag(String tag) {
this.tag = tag;
}
public boolean isLocked() {
return locked;
}
public void setLocked(boolean locked) {
this.locked = locked;
}
public boolean isDeletable() {
return deletable;
}
public void setDeletable(boolean deletable) {
this.deletable = deletable;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
}

View File

@@ -0,0 +1,43 @@
package org.astral.findmaimaiultra.been.pixiv.model.pages;
import java.util.List;
public class Tags {
private String authorId;
private boolean isLocked;
private List<Tag> tags;
private boolean writable;
// Getters and Setters
public String getAuthorId() {
return authorId;
}
public void setAuthorId(String authorId) {
this.authorId = authorId;
}
public boolean isLocked() {
return isLocked;
}
public void setLocked(boolean locked) {
isLocked = locked;
}
public List<Tag> getTags() {
return tags;
}
public void setTags(List<Tag> tags) {
this.tags = tags;
}
public boolean isWritable() {
return writable;
}
public void setWritable(boolean writable) {
this.writable = writable;
}
}

View File

@@ -0,0 +1,23 @@
package org.astral.findmaimaiultra.been.pixiv.model.pages;
public class TitleCaptionTranslation {
private Object workTitle;
private Object workCaption;
// Getters and Setters
public Object getWorkTitle() {
return workTitle;
}
public void setWorkTitle(Object workTitle) {
this.workTitle = workTitle;
}
public Object getWorkCaption() {
return workCaption;
}
public void setWorkCaption(Object workCaption) {
this.workCaption = workCaption;
}
}

View File

@@ -0,0 +1,41 @@
package org.astral.findmaimaiultra.been.pixiv.model.pages;
public class Twitter {
private String description;
private String image;
private String title;
private String card;
// Getters and Setters
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getImage() {
return image;
}
public void setImage(String image) {
this.image = image;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getCard() {
return card;
}
public void setCard(String card) {
this.card = card;
}
}

View File

@@ -0,0 +1,50 @@
package org.astral.findmaimaiultra.been.pixiv.model.pages;
public class Urls {
private String mini;
private String thumb;
private String small;
private String regular;
private String original;
// Getters and Setters
public String getMini() {
return mini;
}
public void setMini(String mini) {
this.mini = mini;
}
public String getThumb() {
return thumb;
}
public void setThumb(String thumb) {
this.thumb = thumb;
}
public String getSmall() {
return small;
}
public void setSmall(String small) {
this.small = small;
}
public String getRegular() {
return regular;
}
public void setRegular(String regular) {
this.regular = regular;
}
public String getOriginal() {
return original;
}
public void setOriginal(String original) {
this.original = original;
}
}

View File

@@ -0,0 +1,227 @@
package org.astral.findmaimaiultra.been.pixiv.model.pages;
import java.util.Date;
import java.util.List;
public class UserIllust {
private String id;
private String title;
private int illustType;
private int xRestrict;
private int restrict;
private int sl;
private String url;
private String description;
private List<String> tags;
private String userId;
private String userName;
private int width;
private int height;
private int pageCount;
private boolean isBookmarkable;
private Object bookmarkData;
private String alt;
private TitleCaptionTranslation titleCaptionTranslation;
private Date createDate;
private Date updateDate;
private boolean isUnlisted;
private boolean isMasked;
private int aiType;
private String profileImageUrl;
// Getters and Setters
// (Add getters and setters for all fields)
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public int getIllustType() {
return illustType;
}
public void setIllustType(int illustType) {
this.illustType = illustType;
}
public int getxRestrict() {
return xRestrict;
}
public void setxRestrict(int xRestrict) {
this.xRestrict = xRestrict;
}
public int getRestrict() {
return restrict;
}
public void setRestrict(int restrict) {
this.restrict = restrict;
}
public int getSl() {
return sl;
}
public void setSl(int sl) {
this.sl = sl;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public List<String> getTags() {
return tags;
}
public void setTags(List<String> tags) {
this.tags = tags;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public int getWidth() {
return width;
}
public void setWidth(int width) {
this.width = width;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
public int getPageCount() {
return pageCount;
}
public void setPageCount(int pageCount) {
this.pageCount = pageCount;
}
public boolean isBookmarkable() {
return isBookmarkable;
}
public void setBookmarkable(boolean bookmarkable) {
isBookmarkable = bookmarkable;
}
public Object getBookmarkData() {
return bookmarkData;
}
public void setBookmarkData(Object bookmarkData) {
this.bookmarkData = bookmarkData;
}
public String getAlt() {
return alt;
}
public void setAlt(String alt) {
this.alt = alt;
}
public TitleCaptionTranslation getTitleCaptionTranslation() {
return titleCaptionTranslation;
}
public void setTitleCaptionTranslation(TitleCaptionTranslation titleCaptionTranslation) {
this.titleCaptionTranslation = titleCaptionTranslation;
}
public Date getCreateDate() {
return createDate;
}
public void setCreateDate(Date createDate) {
this.createDate = createDate;
}
public Date getUpdateDate() {
return updateDate;
}
public void setUpdateDate(Date updateDate) {
this.updateDate = updateDate;
}
public boolean isUnlisted() {
return isUnlisted;
}
public void setUnlisted(boolean unlisted) {
isUnlisted = unlisted;
}
public boolean isMasked() {
return isMasked;
}
public void setMasked(boolean masked) {
isMasked = masked;
}
public int getAiType() {
return aiType;
}
public void setAiType(int aiType) {
this.aiType = aiType;
}
public String getProfileImageUrl() {
return profileImageUrl;
}
public void setProfileImageUrl(String profileImageUrl) {
this.profileImageUrl = profileImageUrl;
}
}

View File

@@ -0,0 +1,14 @@
package org.astral.findmaimaiultra.been.pixiv.model.pages;
public class Zone {
private String url;
// Getters and Setters
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
}

View File

@@ -0,0 +1,86 @@
package org.astral.findmaimaiultra.been.pixiv.model.pages;
public class ZoneConfig {
private Zone responsive;
private Zone rectangle;
private Zone _500x500;
private Zone header;
private Zone footer;
private Zone expandedFooter;
private Zone logo;
private Zone adLogo;
private Zone relatedworks;
// Getters and Setters
public Zone getResponsive() {
return responsive;
}
public void setResponsive(Zone responsive) {
this.responsive = responsive;
}
public Zone getRectangle() {
return rectangle;
}
public void setRectangle(Zone rectangle) {
this.rectangle = rectangle;
}
public Zone get_500x500() {
return _500x500;
}
public void set_500x500(Zone _500x500) {
this._500x500 = _500x500;
}
public Zone getHeader() {
return header;
}
public void setHeader(Zone header) {
this.header = header;
}
public Zone getFooter() {
return footer;
}
public void setFooter(Zone footer) {
this.footer = footer;
}
public Zone getExpandedFooter() {
return expandedFooter;
}
public void setExpandedFooter(Zone expandedFooter) {
this.expandedFooter = expandedFooter;
}
public Zone getLogo() {
return logo;
}
public void setLogo(Zone logo) {
this.logo = logo;
}
public Zone getAdLogo() {
return adLogo;
}
public void setAdLogo(Zone adLogo) {
this.adLogo = adLogo;
}
public Zone getRelatedworks() {
return relatedworks;
}
public void setRelatedworks(Zone relatedworks) {
this.relatedworks = relatedworks;
}
}

View File

@@ -0,0 +1,32 @@
package org.astral.findmaimaiultra.been.pixiv.model.pages.photo;
public class Photo {
private Urls urls;
private int width;
private int height;
// Getters and Setters
public Urls getUrls() {
return urls;
}
public void setUrls(Urls urls) {
this.urls = urls;
}
public int getWidth() {
return width;
}
public void setWidth(int width) {
this.width = width;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
}

View File

@@ -0,0 +1,34 @@
package org.astral.findmaimaiultra.been.pixiv.model.pages.photo;
import java.util.List;
public class PhotoResponse {
private boolean error;
private String message;
private List<Photo> body;
// Getters and Setters
public boolean isError() {
return error;
}
public void setError(boolean error) {
this.error = error;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public List<Photo> getBody() {
return body;
}
public void setBody(List<Photo> body) {
this.body = body;
}
}

View File

@@ -0,0 +1,41 @@
package org.astral.findmaimaiultra.been.pixiv.model.pages.photo;
public class Urls {
private String thumb_mini;
private String small;
private String regular;
private String original;
// Getters and Setters
public String getThumb_mini() {
return thumb_mini;
}
public void setThumb_mini(String thumb_mini) {
this.thumb_mini = thumb_mini;
}
public String getSmall() {
return small;
}
public void setSmall(String small) {
this.small = small;
}
public String getRegular() {
return regular;
}
public void setRegular(String regular) {
this.regular = regular;
}
public String getOriginal() {
return original;
}
public void setOriginal(String original) {
this.original = original;
}
}

View File

@@ -59,7 +59,7 @@ public class MainActivity extends AppCompatActivity implements ImagePickerListen
// Passing each menu ID as a set of Ids because each // Passing each menu ID as a set of Ids because each
// menu should be considered as top level destinations. // menu should be considered as top level destinations.
mAppBarConfiguration = new AppBarConfiguration.Builder( mAppBarConfiguration = new AppBarConfiguration.Builder(
R.id.nav_home, R.id.nav_gallery, R.id.nav_music, R.id.nav_slideshow) R.id.nav_home, R.id.nav_gallery, R.id.nav_music,R.id.nav_pixiv, R.id.nav_slideshow)
.setOpenableLayout(drawer) .setOpenableLayout(drawer)
.build(); .build();
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment_content_main); NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment_content_main);

View File

@@ -0,0 +1,399 @@
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.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.view.*;
import android.widget.*;
import androidx.activity.OnBackPressedCallback;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.widget.SearchView;
import androidx.appcompat.widget.Toolbar;
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.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.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.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.BufferedReader;
import java.io.EOFException;
import java.io.IOException;
import java.lang.reflect.Type;
import java.util.*;
import java.util.concurrent.TimeUnit;
public class PixivFragment extends Fragment {
private RecyclerView recyclerView;
private Handler handler = new Handler(Looper.getMainLooper());
private Context context;
private boolean flag = true;
private double tagXY[] = new double[2];
private String tagplace;
private boolean isFlag = true;
private SharedPreferences shoucang;
private SharedPreferences settingProperties;
private SharedPreferences settingProperties2;
private LinearLayout path1;
private LinearLayout path2;
private SearchView searchView;
private FragmentPixivBinding binding;
private SharedViewModel sharedViewModel;
private PixivAdapter adapter;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 获取 SharedPreferences 实例
// 在 Application 类中启用 Glide 调试日志
context = getContext();
if (context != null) {
shoucang = context.getSharedPreferences("shoucang_prefs", Context.MODE_PRIVATE);
settingProperties = context.getSharedPreferences("setting_prefs", Context.MODE_PRIVATE);
settingProperties2 = context.getSharedPreferences("setting", Context.MODE_PRIVATE);
}
sharedViewModel = new ViewModelProvider(requireActivity()).get(SharedViewModel.class);
}
@Override
public View onCreateView(@NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
HomeViewModel homeViewModel =
new ViewModelProvider(this).get(HomeViewModel.class);
binding = FragmentPixivBinding.inflate(inflater, container, false);
View root = binding.getRoot();
recyclerView = binding.recyclerView;
path1 = binding.path1;
path2 = binding.path2;
searchView = binding.searchView;
requireActivity().getOnBackPressedDispatcher().addCallback(getViewLifecycleOwner(), new OnBackPressedCallback(true) {
@Override
public void handleOnBackPressed() {
if (path2.getVisibility() == View.VISIBLE) {
// 如果 path2 可见,隐藏 path2 并显示 path1
path2.setVisibility(View.GONE);
path1.setVisibility(View.VISIBLE);
} else {
// 否则,允许默认的返回行为
remove(); // 移除回调,允许默认的返回行为
requireActivity().onBackPressed();
}
}
});
// 示例:读取 SharedPreferences 中的数据
if (shoucang != null) {
String savedData = shoucang.getString("key_name", "default_value");
// 使用 savedData
}
adapter = new PixivAdapter(new ArrayList<>());
adapter.setOnItemClickListener(illustData -> openIllustData(illustData));
recyclerView.setLayoutManager(new LinearLayoutManager(requireContext()));
recyclerView.setAdapter(adapter);
// 设置搜索框的查询监听器
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
// 显示 Snackbar 提示“正在搜索”
Snackbar snackbar = Snackbar.make(root, "正在搜索...", Snackbar.LENGTH_INDEFINITE);
snackbar.setAnchorView(searchView); // 设置 Snackbar 锚定到搜索框
snackbar.show();
adapter.update(new ArrayList<>());
adapter.notifyDataSetChanged();
// 当用户提交查询时调用 fetchData 方法
fetchData(query, 1, snackbar);
// 显示搜索结果布局,隐藏 RecyclerView
path1.setVisibility(View.GONE);
path2.setVisibility(View.VISIBLE);
return true;
}
@Override
public boolean onQueryTextChange(String newText) {
// 当用户输入查询文本时可以进行其他操作
return false;
}
});
return root;
}
private void fetchData(String word, int page, Snackbar snackbar) {
OkHttpClient client = new OkHttpClient();
//设置超时时间60s
client.newBuilder().connectTimeout(60, TimeUnit.SECONDS);
client.newBuilder().readTimeout(60, TimeUnit.SECONDS);
client.newBuilder().writeTimeout(60, TimeUnit.SECONDS);
Request request = new Request.Builder()
.url("http://43.153.174.191:45678/api/v1/pixiv/photo?word=" + word + "&page=" + page)
.addHeader("Auth", "1234567890qwertyuiop")
.build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
handler.post(() -> {
Toast.makeText(requireContext(), "请求失败: " + e.getMessage(), Toast.LENGTH_SHORT).show();
Log.e("PixivFragment", "Request failed: ", e);
// 隐藏 Snackbar
snackbar.dismiss();
});
}
@Override
public void onResponse(Call call, Response response) throws IOException {
if (response.isSuccessful()) {
ResponseBody body = response.body();
if (body == null) {
throw new IOException("Response body is null");
}
try (BufferedReader reader = new BufferedReader(body.charStream())) {
StringBuilder result = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
result.append(line);
}
String responseData = result.toString();
if (responseData != null && !responseData.isEmpty()) {
Gson gson = new Gson();
PixivResponse pixivResponse = gson.fromJson(responseData, PixivResponse.class);
if (!pixivResponse.isError() && pixivResponse.getBody() != null && pixivResponse.getBody().getIllustManga() != null) {
List<IllustData> dataList = pixivResponse.getBody().getIllustManga().getData();
handler.post(() -> {
adapter.update(dataList);
adapter.notifyDataSetChanged();
// 隐藏 Snackbar
snackbar.dismiss();
});
} else {
handler.post(() -> {
Toast.makeText(requireContext(), "数据解析失败", Toast.LENGTH_SHORT).show();
// 隐藏 Snackbar
snackbar.dismiss();
});
}
} else {
handler.post(() -> {
Toast.makeText(requireContext(), "响应体为空", Toast.LENGTH_SHORT).show();
// 隐藏 Snackbar
snackbar.dismiss();
});
}
} catch (EOFException e) {
// 捕获 EOFException 并记录日志
e.printStackTrace();
handler.post(() -> {
Toast.makeText(requireContext(), "数据读取错误", Toast.LENGTH_SHORT).show();
// 隐藏 Snackbar
snackbar.dismiss();
});
}
} else {
handler.post(() -> {
Toast.makeText(requireContext(), "请求失败: " + response.code(), Toast.LENGTH_SHORT).show();
// 隐藏 Snackbar
snackbar.dismiss();
});
}
}
});
}
@SuppressLint("MissingInflatedId")
private void openIllustData(IllustData illustData) {
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(requireContext());
builder.setTitle(illustData.getTitle());
Log.d("PixivFragment", "openIllustData: " + illustData.getTitle());
// 创建对话框
AlertDialog dialog = builder.create();
// 使用 pixiv_dialog
View view = LayoutInflater.from(requireContext()).inflate(R.layout.pixiv_dialog, null);
dialog.setView(view);
int id = Integer.parseInt(illustData.getId());
LinearLayout li = view.findViewById(R.id.li);
// 设置对话框的尺寸
Window window = dialog.getWindow();
if (window != null) {
WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams();
layoutParams.copyFrom(window.getAttributes());
layoutParams.width = WindowManager.LayoutParams.MATCH_PARENT;
layoutParams.height = WindowManager.LayoutParams.MATCH_PARENT;
layoutParams.width = (int) (getResources().getDisplayMetrics().widthPixels * 0.9);
layoutParams.height = (int) (getResources().getDisplayMetrics().heightPixels * 0.9);
window.setAttributes(layoutParams);
}
MaterialButton share = view.findViewById(R.id.share);
share.setOnClickListener(v -> {
// 获取要打开的链接
String url = "http://tokyo.1.godserver.cn:45678/api/v1/pixiv/photos?id=" + id; // 假设 getShareUrl() 返回要打开的链接
openBrowser(getContext(), url);
});
// 设置动画效果
if (window != null) {
window.setWindowAnimations(R.style.DialogAnimation);
}
OkHttpClient client = new OkHttpClient();
client.newBuilder().connectTimeout(60, TimeUnit.SECONDS);
client.newBuilder().readTimeout(60, TimeUnit.SECONDS);
client.newBuilder().writeTimeout(60, TimeUnit.SECONDS);
Request request = new Request.Builder()
.url("http://tokyo.1.godserver.cn:45678/api/v1/pixiv/pageId?id=" + id)
.addHeader("Auth", "1234567890qwertyuiop")
.build();
Request request2 = new Request.Builder()
.url("http://tokyo.1.godserver.cn:45678/api/v1/pixiv/photoId?id=" + id)
.addHeader("Auth", "1234567890qwertyuiop")
.build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
String res = response.body().string();
Log.d("PixivFragment111111111", "onResponse: " + res);
if (response.isSuccessful()) {
PagePixivResponse photoResponse = new Gson().fromJson(res, PagePixivResponse.class);
TextView user = view.findViewById(R.id.user);
user.setText(photoResponse.getBody().getUserName());
TextView des = view.findViewById(R.id.des);
des.setText(photoResponse.getBody().getDescription());
}
}
@Override
public void onFailure(@NotNull Call call, @NotNull IOException e) {
e.printStackTrace();
handler.post(() -> {
Toast.makeText(requireContext(), "图片加载失败: " + e.getMessage(), Toast.LENGTH_SHORT).show();
});
}
});
client.newCall(request2).enqueue(new Callback() {
@Override
public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
String res = response.body().string();
if (response.isSuccessful()) {
PhotoResponse photoResponse = new Gson().fromJson(res, PhotoResponse.class);
for (Photo photo : photoResponse.getBody()) {
ImageView photoView = new ImageView(getContext());
String url = "http://43.153.174.191:45678/api/v1/pixiv/photoUrl?href=" + photo.getUrls().getSmall();
loadImage(photoView, url,li);
}
}
}
@Override
public void onFailure(@NotNull Call call, @NotNull IOException e) {
e.printStackTrace();
}
});
// 设置对话框的视图
builder.setView(view);
// 显示对话框
dialog.show();
}
public void openBrowser(Context context, String url) {
Uri uri = Uri.parse(url);
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);
}
private void loadImage(ImageView imageView, String url,LinearLayout li) {
Request request = new Request.Builder()
.url(url)
.build();
Log.d("Web", url);
OkHttpClient client = new OkHttpClient();
client.newBuilder().connectTimeout(180, TimeUnit.SECONDS);
client.newBuilder().readTimeout(180, TimeUnit.SECONDS);
client.newBuilder().writeTimeout(180, TimeUnit.SECONDS);
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
Log.e("PixivAdapter", "Failed to load image: " + e.getMessage());
}
@Override
public void onResponse(Call call, Response response) throws IOException {
if (response.isSuccessful()) {
byte[] imageBytes = response.body().bytes();
Bitmap bitmap = BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.length);
if (bitmap != null) {
imageView.post(() -> imageView.setImageBitmap(bitmap));
}
requireActivity().runOnUiThread(() -> {
li.addView(imageView);
});
} else {
Log.e("PixivAdapter", "Failed to load image: " + response.code());
}
}
});
}
@Override
public void onDestroyView() {
super.onDestroyView();
binding = null;
}
}

View File

@@ -0,0 +1,15 @@
<!-- res/anim/dialog_enter.xml -->
<set xmlns:android="http://schemas.android.com/apk/res/android">
<alpha
android:fromAlpha="0.0"
android:toAlpha="1.0"
android:duration="300" />
<scale
android:fromXScale="0.9"
android:toXScale="1.0"
android:fromYScale="0.9"
android:toYScale="1.0"
android:pivotX="50%"
android:pivotY="50%"
android:duration="300" />
</set>

View File

@@ -0,0 +1,15 @@
<!-- res/anim/dialog_exit.xml -->
<set xmlns:android="http://schemas.android.com/apk/res/android">
<alpha
android:fromAlpha="1.0"
android:toAlpha="0.0"
android:duration="300" />
<scale
android:fromXScale="1.0"
android:toXScale="0.9"
android:fromYScale="1.0"
android:toYScale="0.9"
android:pivotX="50%"
android:pivotY="50%"
android:duration="300" />
</set>

View File

@@ -0,0 +1,17 @@
<!-- res/drawable/custom_searchview_background.xml -->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape>
<solid android:color="@android:color/transparent" />
<stroke
android:width="1dp"
android:color="?attr/colorPrimary" />
<corners android:radius="8dp" />
<padding
android:left="8dp"
android:top="8dp"
android:right="8dp"
android:bottom="8dp" />
</shape>
</item>
</selector>

View File

@@ -0,0 +1,58 @@
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.pixiv.PixivFragment">
<!-- Path 1 -->
<LinearLayout
android:id="@+id/path1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="center"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent">
<!-- 搜索框 -->
<androidx.appcompat.widget.SearchView
android:id="@+id/searchView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:queryHint="搜索..."
android:layout_margin="16dp"
style="@style/CustomSearchView" />
<!-- TextView -->
<com.google.android.material.textview.MaterialTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="FindPixiv"
android:textSize="18sp"
android:layout_marginTop="8dp" />
</LinearLayout>
<!-- Path 2 -->
<LinearLayout
android:id="@+id/path2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/colorOnPrimary"
android:scrollbars="vertical" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,40 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardCornerRadius="8dp"
app:cardElevation="4dp"
android:clickable="true"
android:focusable="true"
android:layout_margin="8dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/backgroundLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:alpha="0.5" /> <!-- 设置透明度为50% -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18sp"
android:textStyle="bold"
android:maxLines="1"
android:ellipsize="end" />
</LinearLayout>
</RelativeLayout>
</androidx.cardview.widget.CardView>

View File

@@ -0,0 +1,53 @@
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp">
<TextView
android:id="@+id/user"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="loading"
android:textSize="18sp"
android:paddingBottom="8dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
<TextView
android:id="@+id/des"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="loading"
android:textSize="16sp"
android:paddingBottom="16dp"
app:layout_constraintTop_toBottomOf="@id/user"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
<com.google.android.material.button.MaterialButton
android:id="@+id/share"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="下载图集(打包)"
app:layout_constraintTop_toBottomOf="@id/des"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintVertical_bias="0.5" />
<ScrollView
android:id="@+id/scrollView"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintTop_toBottomOf="@id/share"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent">
<LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/li"
android:orientation="vertical"/>
</ScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -13,6 +13,9 @@
<item <item
android:id="@+id/nav_music" android:id="@+id/nav_music"
android:title="@string/menu_music"/> android:title="@string/menu_music"/>
<item
android:id="@+id/nav_pixiv"
android:title="@string/menu_pixiv"/>
<item <item
android:id="@+id/nav_slideshow" android:id="@+id/nav_slideshow"
android:title="@string/menu_slideshow"/> android:title="@string/menu_slideshow"/>

View File

@@ -20,7 +20,12 @@
android:id="@+id/nav_music" android:id="@+id/nav_music"
android:name="org.astral.findmaimaiultra.ui.music.MusicFragment" android:name="org.astral.findmaimaiultra.ui.music.MusicFragment"
android:label="@string/menu_music" android:label="@string/menu_music"
tools:layout="@layout/fragment_gallery"/> tools:layout="@layout/fragment_music"/>
<fragment
android:id="@+id/nav_pixiv"
android:name="org.astral.findmaimaiultra.ui.pixiv.PixivFragment"
android:label="@string/menu_pixiv"
tools:layout="@layout/fragment_pixiv"/>
<fragment <fragment
android:id="@+id/nav_slideshow" android:id="@+id/nav_slideshow"
android:name="org.astral.findmaimaiultra.ui.slideshow.SlideshowFragment" android:name="org.astral.findmaimaiultra.ui.slideshow.SlideshowFragment"

View File

@@ -39,6 +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>
</resources> </resources>

View File

@@ -12,5 +12,10 @@
<item name="cornerFamily">rounded</item> <item name="cornerFamily">rounded</item>
<item name="cornerSize">16dp</item> <item name="cornerSize">16dp</item>
</style> </style>
<style name="CustomSearchView" parent="Widget.AppCompat.SearchView">
<item name="queryBackground">@drawable/custom_searchview_background</item>
</style>
<style name="DialogAnimation"> <item name="android:windowEnterAnimation">@anim/dialog_enter</item>
<item name="android:windowExitAnimation">@anim/dialog_exit</item>
</style>
</resources> </resources>