Adding a new drawable it is changing the icons of the parsed xml

nideba :

I am facing with a problem which happens only when I add new drawable.
I have a parsed xml to Fragment the icon is set like int. If I add new drawable then it chooses random drawables to show the icons for the parsed xml.
I have an Adapter for the RecyclerListView.
A Pojo class and DB which extends SQLiteOpenHelper.
If I clear the cache and Storage then it back to normal, or if I delete the new added drawable it returns back to normally.
Can someone help me to know why it is affecting to change the icons.
I have tried to clean project and rebuild the same. Invalidate cache and restart but still the same.

Below you can find the code and below the code two pictures of the problem.

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);
    }
}

The 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;
}
}

This is the .XML file.

<?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>

Fragment of 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);
    }

This is the 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;
}
}

This is layout of 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> 

I have created a LogCat to show what it takes this is the result.

Right way

drawable/youtube
drawable/facebook
drawable/twitter

After add drawable or vector asset or image

drawable/wiki
drawable/facebook
drawable/trash

Right way of showing icons When add new drawable

tynn :

You're calling String.valueOf(bookmark.getIcon()) to store the icon in your database. As the icon is an int representing the resource, this stores the resource id as a string. The issue now is that resource ids are not stable and might change any time you create a new APK. Therefore it works while you don't update the app, but starts failing after.

Instead you should store the name of the res and keep these stable. You're already using the name with your XML data, so I'd assume that's your goal anyhow.

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));

Now you only need to implement the mapping from name to id.

String iconName(int icon) {
    return getResources().getResourceEntryName(icon);
}

int iconRes(String icon) {
    return getResources().getIdentifier(icon, "drawable", mContext.getPackageName())
}

Also you need to unset mContext on detach or don't store it and use getContext() or requireContext() instead. Of course you'd have to check for null if you use it in some background operation.

@Override
public void onDetach() {
    mContext = null;
    super.onDetach();
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=112104&siteId=1