Java 添加一个新的drawable,它正在更改已解析xml的图标
我遇到了一个问题,只有在添加新的drawable时才会出现。Java 添加一个新的drawable,它正在更改已解析xml的图标,java,android,xml,android-fragments,xml-parsing,Java,Android,Xml,Android Fragments,Xml Parsing,我遇到了一个问题,只有在添加新的drawable时才会出现。 我将xml解析为Fragment,图标设置为int。 如果我添加了新的drawable,那么它会选择random drawable来显示解析的xml 我有一个适配器用于回收列表视图 一个Pojo类和DB,它扩展了SQLiteOpenHelper 如果我清除缓存和存储,那么它将恢复正常, 或者,如果我删除新添加的drawable,它将返回正常状态。 有人能帮我知道为什么更改图标会有影响。 我试图清理项目,并重建相同的。 使缓存无效并重新
我将
xml
解析为Fragment
,图标设置为int
。
如果我添加了新的drawable,那么它会选择random drawable来显示解析的xml
我有一个适配器
用于回收列表视图
一个Pojo
类和DB
,它扩展了SQLiteOpenHelper
如果我清除缓存和存储,那么它将恢复正常,
或者,如果我删除新添加的drawable,它将返回正常状态。
有人能帮我知道为什么更改图标会有影响。
我试图清理项目,并重建相同的。
使缓存无效并重新启动,但仍然相同
下面是代码,下面是问题的两张图片
public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private static final int ITEM_TYPE_ONE = 0;
private static final int ITEM_TYPE_TWO = 1;
private final Handler handler = new Handler();
private final ArrayList<Bookmark> arrayList;
private final String BASE_URL = "https://besticon-demo.herokuapp.com/icon?url=";
private final Context context;
public MyAdapter(Context context, ArrayList<Bookmark> arrayList) {
this.context = context;
this.arrayList = arrayList;
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = null;
if (viewType == ITEM_TYPE_ONE) {
view = LayoutInflater.from(context).inflate(R.layout.grid_item, parent, false);
return new ViewHolder(view);
} else if (viewType == ITEM_TYPE_TWO) {
view = LayoutInflater.from(context).inflate(R.layout.add_bookmark, parent, false);
return new ButtonViewHolder(view);
} else {
return null;
}
}
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, final int position) {
final int itemType = getItemViewType(position);
final Bookmark bookmark = this.arrayList.get(position);
if (itemType == ITEM_TYPE_ONE) {
final ViewHolder viewHolder = (ViewHolder) holder;
RequestOptions requestOptions = new RequestOptions();
BookmarkDB bookmarkDB = new BookmarkDB(context);
String imageUrl = BASE_URL + arrayList.get(position).getSearchUrl() + "&size=32";
int resID = context.getResources().getIdentifier(String.valueOf(arrayList.get(position).getIcon()), "drawable", context.getPackageName());
if (resID == 0) {
Glide.with(context)
.load(imageUrl)
.apply(requestOptions
.placeholder(R.drawable.default_favicon)
.diskCacheStrategy(DiskCacheStrategy.AUTOMATIC)
.fitCenter())
.into(viewHolder.tvIcon);
} else {
viewHolder.tvIcon.setImageResource(resID);
String imageName = context.getResources().getResourceName(resID);
Log.d("getIcons", imageName); // This is the log.
} else if (itemType == ITEM_TYPE_TWO) {
ButtonViewHolder buttonViewHolder = (ButtonViewHolder) holder;
buttonViewHolder.imgButton.setImageResource(arrayList.get(position).getIcon());
}
}
class ViewHolder extends RecyclerView.ViewHolder {
final ImageView tvIcon;
ViewHolder(@NonNull final View itemView) {
super(itemView);
tvIcon = itemView.findViewById(R.id.image_view);
}
}
这是.XML
文件
<?xml version="1.0" encoding="utf-8"?>
<Bookmarks>
<Bookmark name="Bing"
hidden="true"
icon="bing"
id="0"
nativeUrl=""
searchUrl="https://www.bing.com" />
<Bookmark
name="Google"
hidden="true"
icon="google"
id="1"
nativeUrl=""
searchUrl="https://www.google.com" />
<Bookmark
name="Youtube"
hidden="false"
icon="youtube"
id="2"
nativeUrl="youtube://"
searchUrl="https://m.youtube.com" />
<Bookmark
name="Facebook"
hidden="false"
icon="facebook"
id="3"
nativeUrl="facebook://"
searchUrl="https://m.facebook.com" />
<Bookmark
name="Twitter"
hidden="false"
icon="twitter"
id="4"
nativeUrl=""
searchUrl="https://mobile.twitter.com/" />
</Bookmarks>
这是Pojo.class
public class Bookmark implements Parcelable, Comparable, Comparator<Bookmark> {
public static final Creator<Bookmark> CREATOR = new Creator<Bookmark>() {
@Override
public Bookmark createFromParcel(Parcel in) {
return new Bookmark(in);
}
@Override
public Bookmark[] newArray(int size) {
return new Bookmark[size];
}
};
private String name;
private String id;
private String nativeUrl;
private String searchUrl;
private String hidden;
private long db_id;
private int icon;
private int viewType;
private Bookmark(Parcel in) {
name = in.readString();
id = in.readString();
nativeUrl = in.readString();
searchUrl = in.readString();
db_id = in.readLong();
icon = in.readInt();
viewType = in.readInt();
hidden = in.readString();
}
public Bookmark() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getIcon() {
return icon;
}
public void setIcon(int icon) {
this.icon = icon;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
this.db_id = Integer.parseInt(id);
}
public String getNativeUrl() {
return nativeUrl;
}
public void setNativeUrl(String nativeUrl) {
this.nativeUrl = nativeUrl;
}
public String getSearchUrl() {
return searchUrl;
}
public void setSearchUrl(String searchUrl) {
this.searchUrl = searchUrl;
}
public int getViewType() {
return viewType;
}
public void setViewType(int viewType) {
this.viewType = viewType;
}
public String getHidden() {
return hidden;
}
public void setHidden(String hidden) {
this.hidden = hidden;
}
@Override
public String toString() {
return "Bookmark{" +
"name='" + name + '\'' +
", id='" + id + '\'' +
", nativeUrl='" + nativeUrl + '\'' +
", searchUrl='" + searchUrl + '\'' +
", hidden='" + hidden + '\'' +
", db_id=" + db_id +
", icon=" + icon +
", viewType=" + viewType +
'}';
}
@Override
public int compareTo(Object o) {
return 0;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
dest.writeString(id);
dest.writeString(nativeUrl);
dest.writeString(searchUrl);
dest.writeLong(db_id);
dest.writeInt(icon);
dest.writeInt(viewType);
dest.writeString(hidden);
}
@Override
public int compare(Bookmark o1, Bookmark o2) {
return 0;
}
}
我已经创建了一个LogCat来显示它需要什么,这就是结果
正确的方法
drawable/youtube
drawable/facebook
drawable/twitter
添加可绘图或矢量资源或图像后
drawable/wiki
drawable/facebook
drawable/trash
尝试执行myAdapter.notifyDataSetChanged()代码>在arrayList在FragmentBookmark中添加工作后:
Bookmark bookmark = new Bookmark();
bookmark.setViewType(1);
bookmark.setIcon(R.drawable.add_new_bookmark_icon);
arrayList.add(bookmark);
myAdapter.notifyDataSetChanged();
顺便说一句:xml解析工作和数据库操作通常应该异步处理
已更新:将书签中的类型图标
字段从int更改为String,并修改loadBookMarksFromXML
中的一些代码,从
int drawableResourceId =
getResources().getIdentifier(
xpp.getAttributeValue(null, "icon"), "drawable",mContext.getPackageName());
bookmark.setIcon(drawableResourceId);
到
在类MyAdapter
中的onBindViewHolder
中更改一些代码,从:
int resID = context.getResources().getIdentifier(String.valueOf(arrayList.get(position).getIcon()), "drawable", context.getPackageName());
到
您可以很容易地修复因更改图标
字段的类型而导致的其他错误,然后再次运行,让我知道结果。Thx.也许您应该将图标从res文件夹移动到assets,然后使用Glide加载它
if (getResources().getAssets().list("").contains("icon.png")) {
Glide.with(fragment)
.load(Uri.parse("file:///android_asset/icon.png"))
.into(imageView);
} else {
// load from web
}
要将图像存储到sqlite或任何其他本地数据库,必须存储变量的名称(我在使用本地数据库时这样做,也许有更好的方法)
所以,当您想要存储可拉伸
使用此代码
bookmark.setIcon("add_new_bookmark_icon");//don't forget to change icon to String in bookmark
而不是这个
bookmark.setIcon(R.drawable.add_new_bookmark_icon);//you use this in onViewCreate and buildBookmarkArrayListfromDB
现在,当您想从数据库中显示drawable时,请使用以下代码
int resourceId = getResources().getIdentifier("", "drawable", getPackageName());
Drawable yourImage = ContextCompat.getDrawable(this,resourceId);
imageView.setImageDrawable(yourImage);
注
必须将所有位置使用setIcon或getIcon以及所有使用图标的代码更改为int,如getAllBookmarks
->csr.getInt(csr.getColumnIndex(COL_图标)
和其他
我几年前就这样做了,但我不检查它是否仍然有效。请尝试并告诉我您正在调用的String.valueOf(bookmark.getIcon())发生了什么
将图标存储在数据库中。由于图标是表示资源的int
,因此将资源id存储为字符串。现在的问题是,资源id不稳定,在创建新APK时可能会更改。因此,它在不更新应用程序时工作,但在更新后开始失败
相反,您应该存储res的名称并保持其稳定。您已经在XML数据中使用了该名称,因此我认为这是您的目标
mDB.addBookmark(
Long.valueOf(bookmark.getId()),
bookmark.getName(),
bookmark.getViewType() > 0,
iconName(bookmark.getIcon()),
bookmark.getNativeUrl(),
bookmark.getSearchUrl()
);
String Icon = csr.getString(csr.getColumnIndex(COL_ICON));
b.setIcon(iconRes(Icon));
现在您只需要实现从name到id的映射
String iconName(int icon) {
return getResources().getResourceEntryName(icon);
}
int iconRes(String icon) {
return getResources().getIdentifier(icon, "drawable", mContext.getPackageName())
}
此外,您还需要在分离时取消设置mContext
,或者不存储它,而是使用getContext()
或requireContext()
。当然,如果在某些后台操作中使用它,您必须检查null
@Override
public void onDetach() {
mContext = null;
super.onDetach();
}
由于资源id在每次安装或生成apk时都会不断更改,因此明智的做法是存储图标资源的名称,并在显示期间获取它。为此,您可以存储图标名称的字符串值(您也可以使用与书签相同的名称,但确保相同名称的可绘制性)。
将数据库(Bookmark.db)&Pojo中的图标字段更改为字符串。
删除RecyclerView片段中的这一行
int drawableResourceId = getResources().getIdentifier(xpp.getAttributeValue(null, "icon"), "drawable", mContext.getPackageName());
换行
bookmark.setIcon(xpp.getAttributeValue(null, "name"));
在MyAdapter类的onBindViewHolder中,使用获取图标资源
int iresourceid = getResources().getIdentifier(arrayList.get(position).getIcon(),"drawable",getPackageName());
这也是同样的问题。您提供的代码看起来不完整。请提供完整的代码。我添加了更多的代码,包括Pojo.class
我忘了添加这些代码,并且为此添加了完整的DB
。“如果我添加了新的可绘制文件,那么它会选择随机可绘制文件来显示解析xml的图标。”我看到两个地方你在FragmentBookmark中添加了新的书签图标项,一个在buildBookmarkArrayListfromDB方法中,另一个在onCreateView中,你指的是哪一个?添加到FragmentBookmark中的书签图标是第二个视图,它只有加号按钮。如果我正确地遵循了你的描述,那是因为您正在将图标作为数字资源ID存储在数据库中。添加(或删除,或更改)时在您的资源中添加一个drawable,然后重新生成,drawable很可能不会具有与以前相同的数字ID。最简单的修复方法可能是只存储图标的名称,而不是它们的数字ID。@MikeM。是的,这些图标以int形式保存在数据库中。您能提供关于这个问题的答案吗您所说的是最简单的修复方法吗?您的意思是将所有内容从int改为String吗?@Spritzig是的,但我认为如果用我的代码替换bookmark.setIcon,您的问题可以解决,但不确定我在FragmentBookmark
bookmark.setIcon()
处确实有问题,返回此错误setIcon(java.lang.String)in Bookmark无法应用于(android.graphics.drawable.drawable)
不要将drawable发送到Bookmark!仅当您希望将其显示到imageView时,请使用drawable。为此,您必须将可绘制图像的名称发布到setIcon。我不知道您必须发布到书签的图标是什么使用此书签。setIcon(“添加新书签图标”);
String iconName(int icon) {
return getResources().getResourceEntryName(icon);
}
int iconRes(String icon) {
return getResources().getIdentifier(icon, "drawable", mContext.getPackageName())
}
@Override
public void onDetach() {
mContext = null;
super.onDetach();
}
int drawableResourceId = getResources().getIdentifier(xpp.getAttributeValue(null, "icon"), "drawable", mContext.getPackageName());
bookmark.setIcon(xpp.getAttributeValue(null, "name"));
int iresourceid = getResources().getIdentifier(arrayList.get(position).getIcon(),"drawable",getPackageName());