我有一个自定义ListView this是我正在使用的ListView,它在屏幕上显示一些数据,非常简单。现在,我需要为显示的数据视图设置主题。我这样做的方法是将key, value
保存到SQLite适配器,我不想使用SharedPrefs,这需要很长时间才能读取120多个键!并使UI滞后很多,所以我想让我们做一个异步setBackground
,所以这就是我整理的内容。
public static HashMap<String, String> lruCache = new HashMap<>();
我将所有键缓存在哈希集中
然后我制作了一种方法,用于检查密钥是否存在,如果不存在,则使用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);
}
}
这就是我的getColor
方法的工作原理。
public static int getColor(String str, String defaultValue) {
ThemeDatabaseManager lynxDatabaseHelper = new ThemeDatabaseManager(LynxBase.getApplicationContext()).open();
return ThemeUtils.parseColor(lynxDatabaseHelper.getString(str, defaultValue));
}
它从我的SQlite数据库获取字符串并将其解析为一个int。这是我的getString
方法
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;
}
我获取所有SQLite列并循环,直到找到正确的键,然后返回该值(如果该值不存在),我只是将默认值插入SQLite数据库中,因此我总是以一个键结束另外一次。
问题在这里发生。它不是适配器中所有选项卡的主题。
可以看到它仅以第3个适配器项目为主题,但是当我上下滚动时,位置会发生变化。所以它不会改变第3位,而是第5位,您明白了,有人知道我能解决这个问题吗?我已经调试了大约5天,尝试了各种方法似乎无法修复它。
一旦setBackgroundColor
完成,黑色就是所有物品的外观。白色是使用XML布局应用的默认颜色。
这就是我在适配器上调用它的方式。
public final View getView(int i, View view, ViewGroup viewGroup){\
...
view = inflate(R.layout.my_view, viewGroup, false);
setBackground(view);
...
}
我的班级正在扩展我制作的自定义类,如果有帮助,它会扩展BaseAdapter
!
这是我根据答案尝试过的。
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();
}
}
但是还是和以前一样。
这是Catlog转储:
答案 0 :(得分:1)
如果我只是从数据库设置颜色并跳过 异步位。但是当我使用异步时,它不起作用。
之所以会这样,是因为您的AsyncTask
在 UIThread 上不起作用,因此,当返回结果时,它就不会redraw
您的项目。为此,您需要使用myAdapter.notifyDataSetChanged();
从您共享的代码中,我想您可以从postExecute
进行调用:
public static class AsyncBackgroundColor extends AsyncTask<String, String, Integer> {
WeakReference<View> view;
WeakReference<Adapter> adapter;
AsyncBackgroundColor(Adapter ad, View view) {
this.view = new WeakReference<>(view);
this.adapter = new WeakReference<>(ad);
}
@Override
protected Integer doInBackground(String... strings) {
return 1;
}
@Override
protected void onPostExecute(Integer color) {
view.get().setBackgroundColor(color);
adapter.get().notifyDataSetChanged();
}
}
还可以在您的getString()
上更改此部分:
if (k.equals(key)) {
cursor.close();
if (database.isOpen()) database.close();
ThemeDatabaseCache.lruCache.put(key, value);
return value;
}
答案 1 :(得分:1)
作为补充。您应该更改查询以仅获取您感兴趣的条目,而不是获取整个数据库并匹配ThemeDatabaseHelper.COLUMN_NAME_TITLE
,这将加快您的操作并避免延迟。