私は新しい描画可能を追加したときにのみ起こる問題に直面しています。
私が解析されているxml
にように設定されています。私は新しい描画可能を追加する場合、それは解析されたのアイコンを表示するようにランダムドローアブルを選択します。私が持っているために。クラスとその拡張。私は正常に戻って、それをキャッシュとストレージをクリアするか、私は新たな付加描画可能を削除した場合、それは通常に戻る場合。誰かの助けを借り、私はアイコンを変更することが影響している理由を知っていることができます。私はきれいなプロジェクトにしようとしたと同じように再構築してきました。無効化キャッシュと再起動が、それでも同じ。Fragment
icon
int
xml
Adapter
RecyclerListView
Pojo
DB
SQLiteOpenHelper
以下は、コードを見つけると、問題のコード二つの絵、以下のことができます。
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);
}
}
ザ・ Bookmark.db
public class BookmarkDB extends SQLiteOpenHelper {
private static final String DBNAME = "bookmarks.db"; // The name of the database file
private static final int DBVERSION = 1; // The Database version
public static final String TBL_BOOKMARK = "bookmark";
private static final String COL_ID = BaseColumns._ID; // equates to _id
private static final String COl_NAME = "name";
private static final String COl_HIDDEN = "hidden";
private static final String COL_ICON = "icon";
private static final String COL_NATIVEURL = "nativeurl";
private static final String COL_SEARCHURL = "searchurl";
private final SQLiteDatabase mDB;
Context mContext;
public BookmarkDB(Context context) {
super(context, DBNAME, null, DBVERSION);
mDB = this.getWritableDatabase();
}
@Override
public void onCreate(SQLiteDatabase db) {
// The SQL to be used to create the table
String crt_bookmark_tbl_sql = "CREATE TABLE IF NOT EXISTS " + TBL_BOOKMARK + "(" +
COL_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
COl_NAME + " TEXT, " +
COl_HIDDEN + " INTEGER, " +
COL_ICON + " TEXT, " +
COL_NATIVEURL + " TEXT," +
COL_SEARCHURL + " TEXT" +
")";
db.execSQL(crt_bookmark_tbl_sql); // CREATE THE TABLE
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP IF TABLE EXISTS " + DBNAME);
onCreate(db);
}
public void updateName(String newName, int id, String oldName) {
SQLiteDatabase db = this.getWritableDatabase();
String query = "UPDATE " + TBL_BOOKMARK + " SET " + COl_NAME +
" = '" + newName + "' WHERE " + COL_ID + " = '" + id + "'" +
" AND " + COl_NAME + " = '" + oldName + "'";
db.execSQL(query);
}
public void addBookmark(long id, String name, boolean hidden, String icon, String nativeurl, String searchurl) {
ContentValues cv = new ContentValues();
cv.put(COl_HIDDEN, hidden);
cv.put(COl_NAME, name);
cv.put(COL_ICON, icon);
cv.put(COL_NATIVEURL, nativeurl);
cv.put(COL_SEARCHURL, searchurl);
mDB.insert(TBL_BOOKMARK, null, cv);
// uses the convenience insert method that builds the SQL
}
public ArrayList<Bookmark> getAllBookmarks() {
ArrayList<Bookmark> rv = new ArrayList<>();
Cursor csr = mDB.query(TBL_BOOKMARK, null, null, null, null, null, null);
while (csr.moveToNext()) {
Bookmark b = new Bookmark();
b.setId(csr.getString(csr.getColumnIndex(COL_ID)));
int Icon = csr.getInt(csr.getColumnIndex(COL_ICON));
String name = csr.getString(csr.getColumnIndex(COl_NAME));
String searchUrl = csr.getString(csr.getColumnIndex(COL_SEARCHURL));
b.setIcon(Icon);
b.setName(name);
b.setSearchUrl(searchUrl);
b.setViewType(csr.getInt(csr.getColumnIndex(COl_NAME)));
b.setNativeUrl(csr.getString(csr.getColumnIndex(COL_NATIVEURL)));
rv.add(b);
}
return rv;
}
}
これは、ある.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>
のフラグメント RecyclerView
public class FragmentBookmark extends Fragment {
private final ArrayList<Bookmark> arrayList = new ArrayList<>();
private MyAdapter myAdapter;
private View paramView;
private RecyclerView myRecyclerView;
private BookmarkDB mDB;
private Context mContext;
@Override
public void onAttach(Context context) {
super.onAttach(context);
mContext = context;
mDB = new BookmarkDB(mContext);
mDB.getAllBookmarks();
buildBookmarkArrayListfromDB();
loadBookMarksFromXML();
}
@Nullable
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
paramView = inflater.inflate(R.layout.bookmark, container, false);
myRecyclerView = paramView.findViewById(R.id.myRecyclerView);
// myRecyclerView.setLayoutManager(new LinearLayoutManager(mContext));
myRecyclerView.setLayoutManager(new GridLayoutManager(mContext, 4));
myRecyclerView.setHasFixedSize(true);
myAdapter = new MyAdapter(mContext, arrayList);
myRecyclerView.setAdapter(myAdapter);
myAdapter.notifyDataSetChanged();
Bookmark bookmark = new Bookmark();
bookmark.setViewType(1);
bookmark.setIcon(R.drawable.add_new_bookmark_icon);
arrayList.add(bookmark);
((MainActivity) getActivity()).setFragmentBookmarkListener(new MainActivity.FragmentBookmarkListener() {
@Override
public void onRefresh() {
assert getFragmentManager() != null;
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.detach(FragmentBookmark.this).attach(FragmentBookmark.this).commit();
}
});
return paramView;
}
private void loadBookMarksFromXML() {
// MAY WISH TO ONLY DO THIS ONCE as bookmarks would be loaded OTHERWISE DELETE LINE BELOW
if (DatabaseUtils.queryNumEntries(mDB.getWritableDatabase(), BookmarkDB.TBL_BOOKMARK) > 0)
return;
try {
XmlResourceParser xpp = getResources().getXml(R.xml.bookmarks);
while (xpp.getEventType() != XmlPullParser.END_DOCUMENT) {
if (xpp.getEventType() == XmlPullParser.START_TAG) {
if (xpp.getName().equals("Bookmark")) {
Bookmark bookmark = new Bookmark();
bookmark.setName(xpp.getAttributeValue(null, "name"));
bookmark.setSearchUrl(xpp.getAttributeValue(null, "searchUrl"));
bookmark.setNativeUrl(xpp.getAttributeValue(null, "nativeUrl"));
bookmark.setId(xpp.getAttributeValue(null, "id"));
int drawableResourceId = getResources().getIdentifier(xpp.getAttributeValue(null, "icon"), "drawable", mContext.getPackageName());
bookmark.setIcon(drawableResourceId);
bookmark.setViewType(0);
if (bookmark.getId() == null) {
bookmark.setId("1");
}
mDB.addBookmark(
Long.valueOf(bookmark.getId()),
bookmark.getName(),
bookmark.getViewType() > 0,
String.valueOf(bookmark.getIcon()),
bookmark.getNativeUrl(),
bookmark.getSearchUrl()
);
}
}
xpp.next();
}
} catch (XmlPullParserException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private void buildBookmarkArrayListfromDB() {
arrayList.clear();
arrayList.addAll(mDB.getAllBookmarks());
Bookmark bookmark = new Bookmark();
bookmark.setViewType(1);
bookmark.setIcon(R.drawable.add_new_bookmark_icon);
arrayList.add(bookmark);
}
これは 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;
}
}
これはレイアウトですFragment
。
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:overScrollMode="never">
<android.support.v7.widget.RecyclerView
android:id="@+id/myRecyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="false"
android:orientation="horizontal"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent">
</android.support.v7.widget.RecyclerView>
</android.support.v4.widget.NestedScrollView>
私はそれは、これが結果です必要なものを表示するようにLogCatを作成しました。
正しい方法
drawable/youtube
drawable/facebook
drawable/twitter
追加描画可能またはベクトル資産や画像の後
drawable/wiki
drawable/facebook
drawable/trash
あなたは呼んでいるString.valueOf(bookmark.getIcon())
、データベース内のアイコンを格納します。アイコンのようにint
リソースを表し、これは文字列としてリソースIDを格納します。問題は、今のリソースIDが安定していない、あなたは新しいAPKを作成し、いつでも変更される可能性があるということです。したがって、それはあなたがアプリを更新していないながら動作しますが、後に失敗を開始します。
代わりに、解像度の名前を格納し、これらの安定を維持する必要があります。私はあなたの目標はとにかくだと仮定と思いますので、あなたはすでに、あなたの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));
今、あなただけの名前から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();
}