gpt4 book ai didi

java - ListView 适配器异步操作

转载 作者:搜寻专家 更新时间:2023-11-01 09:21:37 24 4
gpt4 key购买 nike

我有一个自定义 ListView this是我正在使用的 ListView,它在屏幕上显示一些数据,非常简单。现在我需要为显示的数据 View 设置主题。我这样做的方法是保存 key, value对于 SQLite 适配器,我不想使用 SharedPrefs,这需要很长时间才能读取超过 120 个键!并且滞后于 UI 很多所以我想让我们做一个异步 setBackground所以这是我放在一起的。

public static HashMap<String, String> lruCache = new HashMap<>();

我将所有键缓存在一个哈希集中

然后我创建了一个方法来检查 key 是否存在,如果不存在则使用 AsyncTask 获取 key

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 数据库,这样我总是以一个键结束另一次。

问题就出在这里。它不会为适配器中的所有选项卡设置主题。

enter image description here

如您所见,它仅以第 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);
...
}

我的类(class)正在扩展我制作的自定义类(class),该类(class)扩展了 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();
}
}

但还是和以前一样。

这是目录转储:

enter image description here

最佳答案

This works if I just set the color from the database and skip the async bit. But when I use async it doesn't work.

发生这种情况是因为您的 AsyncTask 无法在 UIThread 上工作,因此当结果返回时它不会重绘您的项目.为此,您需要使用 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;
}

关于java - ListView 适配器异步操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54715709/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com