I have a Custom ListView this is the ListView I am using that shows some data on the screen, Pretty simple. Now I need to theme the shown data view. the way I do this is by saving a key, value
to SQLite adapter, I don't want to use SharedPrefs, This takes a long process to read over 120+ keys! and lags the UI a lot so I thought lets make an async setBackground
so here is what I put together.
public static HashMap<String, String> lruCache = new HashMap<>();
I cache all the keys in a hashset
and then I made a method that checks if the key exists if not it gets the key using AsyncTask
public static void setBackgroundColor(View view, String key, String defaultValue) {
String val = lruCache.get(key);
if (val != null) {
view.setBackgroundColor(ThemeUtils.parseColor(val));
return;
}
new AsyncBackgroundColor(view).execute(key, defaultValue);
}
public static class AsyncBackgroundColor extends AsyncTask<String, String, Integer> {
WeakReference<View> view;
AsyncBackgroundColor(View view) {
this.view = new WeakReference<>(view);
}
@Override
protected Integer doInBackground(String... strings) {
return ThemeUtils.getColor(strings[0], strings[1]);
}
@Override
protected void onPostExecute(Integer color) {
view.get().setBackgroundColor(color);
}
}
and this is how my getColor
method works.
public static int getColor(String str, String defaultValue) {
ThemeDatabaseManager lynxDatabaseHelper = new ThemeDatabaseManager(LynxBase.getApplicationContext()).open();
return ThemeUtils.parseColor(lynxDatabaseHelper.getString(str, defaultValue));
}
It gets the string from my SQlite database and parses it to an int. This is my getString
method
public String getString(String key, String defaultValue) {
String cachedValue = ThemeDatabaseCache.lruCache.get(key);
if (cachedValue != null) {
return cachedValue;
}
if (!database.isOpen()) open();
String[] columns = new String[]{ThemeDatabaseHelper.COLUMN_NAME_TITLE, ThemeDatabaseHelper.COLUMN_NAME_SUBTITLE};
Cursor cursor = database.query(TABLE_NAME, columns, null, null, null, null, null);
if(cursor != null) {
cursor.moveToFirst();
if(cursor.getCount() != 0) {
do {
if (!(cursor.getColumnCount() <= 1)) {
String k = cursor.getString(cursor.getColumnIndex(ThemeDatabaseHelper.COLUMN_NAME_TITLE));
String value = cursor.getString(cursor.getColumnIndex(ThemeDatabaseHelper.COLUMN_NAME_SUBTITLE));
if (k.equals(key)) {
cursor.close();
if (database.isOpen()) database.close();
ThemeDatabaseCache.lruCache.put(key, defaultValue);
return value;
}
}
} while (cursor.moveToNext());
}
cursor.close();
}
insertOrUpdate(key, defaultValue);
if (database.isOpen()) database.close();
return defaultValue;
}
I fetch all the SQLite colums and loop until I find the correct key and then return that how ever if the value doesn't exist I just insert the default value into the SQLite database, that way I always end up with a key the other time.
The problem happens here. It doesn't theme all the tabs in the adapter.
as you can see It only themed the 3rd adapter item, But when I scroll up and down, the position changes. So It wont change 3rd its gonna be 5th and you get the point, Does anyone know how I can resolve this? I am been debugging this for about 5 days now, Tried all sorts of stuff can't seem to fix it.
The black is what all of the item is suppose to look like once the setBackgroundColor
is done. The white is the default color applied using XML Layout.
This is how I call it on my adapter.
public final View getView(int i, View view, ViewGroup viewGroup){\
...
view = inflate(R.layout.my_view, viewGroup, false);
setBackground(view);
...
}
and my class is extending a custom class that I made that extends BaseAdapter
if that helps!
This is what I have tried according to the answer.
public static void setBackgroundColor(BaseAdapter baseAdapter, View view, String key, String defaultValue) {
String val = lruCache.get(key);
if (val != null) {
Log.wtf("Lynx", "background set using cached Color.");
view.setBackgroundColor(ThemeUtils.parseColor(val));
baseAdapter.notifyDataSetChanged();
return;
}
new AsyncBackgroundColor(baseAdapter, view).execute(key, defaultValue);
}
..
public static class AsyncBackgroundColor extends AsyncTask<String, String, Integer> {
WeakReference<View> view;
BaseAdapter baseAdapter;
AsyncBackgroundColor(BaseAdapter baseAdapter, View view) {
this.view = new WeakReference<>(view);
this.baseAdapter = baseAdapter;
}
@Override
protected Integer doInBackground(String... strings) {
return ThemeUtils.getColor(strings[0], strings[1]);
}
@Override
protected void onPostExecute(Integer color) {
Log.wtf("Lynx", "background set using async task.");
view.get().setBackgroundColor(color);
if(baseAdapter != null)
baseAdapter.notifyDataSetChanged();
}
}
But It's still the same as before.
Here is the Catlog dump: