这是因为它仅在某些手机中发生,因为它们的分辨率是FHD。
当显示UI时,一切似乎都可以。当我点击项目并调用notifyDataSetChanged()时,项目不会刷新它的样子。我需要再次点击ListView,项目将刷新布局到正确的外观。
如果列表视图改变大小(例如:搜索功能将重新设计整个布局),一切都会变好。
这是ListView代码:
public final class MyListView extends ListView implements AdapterView.OnItemClickListener
{
ArrayList<SELECT_ITEM> selectList;
ArrayList<ID_ITEM> idList;
ShowItemAdapter showAdapter;
public MyListView(Context context)
{
selectList = new ArrayList<SELECT_ITEM>();
idList = new ArrayList<ID_ITEM>();
readIdList(mIdList);
showAdapter = new ShowItemAdapter(context, idList, selectList);
setAdapter(showAdapter);
...
}
@Override
protected void onFinishInflate() {
setOnItemClickListener(this);
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long ID) {
boolean itemIsSelected = true;
int size = selectList.size();
// remove if click item in selectList
for(int i=0 ; i<size ; i++) {
int selectID = selectList.get(i).id;
if (idList.get(position).id == selectID) {
itemIsSelected = false;
selectList.remove(i);
showAdapter.notifyDataSetChanged();
break;
}
}
if (itemIsSelected) {
SELECT_ITEM item = new SELECT_ITEM();
item.id = idList.get(position);
selectList.add(item);
// Here
showAdapter.notifyDataSetChanged();
}
...
}
....
}
这是适配器代码,
public final class ShowItemAdapter extends BaseAdapter{
public ArrayList<ID_ITEM> mIdList;
public ArrayList<SELECT_ITEM> mSelectList;
public ShowItemAdapter(Context context,
ArrayList<ID_ITEM> idList,
ArrayList<SELECT_ITEM> selectList)
{
mIdList = idList;
mSelectList = selectList;
}
@Override
public int getCount() {
int ret = mIdList.size();
return ret;
}
@Override
public Object getItem(int position) {
return position;
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
...
for(int i=0 ; i<size ; i++)
{
// is selected
if (mIdList.get(position).id ==
selectList.get(i).id)
{
mIsSelected = true;
break;
}
}
if (mIsSelected)
{
textView.setBackgroundColor(Color.red);
}
else
{
textView.setBackgroundColor(Color.white);
}
}
}
有人帮我一把吗?
我发现在getView()调试暂停时,这些手机正常工作会导致同样的问题。我认为..就像&#34;视图已经更新,因此它不会刷新视图。&#34;但是在调试期间更新视图会使ui实际上不刷新,然后它会以错误的方式工作。
我想这是关于令人耳目一新的观点。
答案 0 :(得分:2)
我发现适配器的getView()和onItemClick()之间可能存在代码冲突和时序问题。
请允许我解释一下。在getView()中,有代码
if (mIdList.get(position).id == selectList.get(i).id)
注意:这会检查selectList
的值,该值甚至不在此Adapter类中声明。我假设你的意思是mSelectList
。但是,让我们继续......
在onItemClick()中,有代码
if (idList.get(position).id == selectID) {
...
selectList.remove(i);
...
注意:此代码从selectList
中删除项目,而在getView
()中,它正在检查同一个对象。我们无法知道哪些代码会先运行。但我有个主意......
getView
()是一种虚拟回调方法,当 BaseAdapter需要显示行或项时, BaseAdapter可以触发方法。因此,当您从Listview中删除项目时,无论您在代码中执行什么操作,适配器都不会请求刷新。适配器ShowItemAdapter
负责所有行/视图刷新。
建议:在getView
()中放置相同的代码(用于删除/添加项目)以避免这些类型的代码冲突。
让我们知道这个奇怪的异常并祝你好运 Tommy Kwee
答案 1 :(得分:1)
您需要在super
类的constructor
和onFinishInflate
函数中调用MyListView
方法。这可能导致了这个问题。
public MyListView(Context context)
{
super(context);
selectList = new ArrayList<SELECT_ITEM>();
..
..
}
和
@Override
protected void onFinishInflate() {
super.onFinishInflate();
setOnItemClickListener(this);
}
答案 2 :(得分:1)
这是Android 4.0.3上的错误,notifyDataSetChanged
无法使用onItemClickListener
。
所以解决方案是这样的:
onItemClickListener
分别设置为适配器中的每个视图notifyDataSetChanged
答案 3 :(得分:1)
通常我会更新适配器上的数据,但我不会遇到这类问题,我相信它更加稳固。由于您正在更新Listview中的数据(selectList),我认为刷新/更新有点间接。我建议一开始尝试。
以下代码后的代码示例:
selectList.remove(i);
showAdapter.notifyDataSetChanged();
添加强>:
注意:我注意到你调用onInit()的解决方案,我不知道它是什么。似乎涉及到计时问题,这意味着您不必在新的/单独的线程上运行代码。
答案 4 :(得分:1)
以下可能有所帮助。我在4.4.2中遇到了类似的问题,这有助于:
//clear the adapter
showAdapter.clear();
//add all the data in your list to adapter again
showAdapter.addAll(selectList);
您无需调用notifyDataSetChanged,因为它将在addAll中执行此操作。 希望有所帮助。
答案 5 :(得分:1)
您应该同步更新ListView。
public final class ShowItemAdapter extends BaseAdapter{
public ArrayList<ID_ITEM> mIdList;
public ArrayList<SELECT_ITEM> mSelectList;
public ShowItemAdapter(Context context,
ArrayList<ID_ITEM> idList,
ArrayList<SELECT_ITEM> selectList)
{
mIdList = idList;
mSelectList = selectList;
}
public synchronized void refreshData(ArrayList<SELECT_ITEM> items) {
this.mSelectList = items;
notifyDataSetChanged();
}
每当您对列表进行更改时,请调用refreshData()方法
selectList.remove(i);
refreshData(selectList);
或
selectList.add(i);
refreshData(selectList);
这肯定会刷新用户列表视图以及更新的项目列表
答案 6 :(得分:0)
我找到了一个解决方案,虽然它仍然可以解决一些问题 我在Activity.onCreate()下面调用,只有onInit()MyListView才会被初始化:
postDelayed(new Runnable()
{
public void run()
{
onInit(icicle); // initial ui
}
}, 100);
它使视图显示较慢但工作正常 如果延迟大约100毫秒,可能会导致那些精细的手机变得糟糕。 延迟大约350毫秒使两部手机都运行良好。 有更好的答案吗?
答案 7 :(得分:0)
不是使用showAdapter.notifyDataSetChanged();
只更新数据源,而是指selectList并重新初始化您的适配器并将其附加到ListView。
替换此
selectList.remove(i);
showAdapter.notifyDataSetChanged();
和
selectList.add(item);
showAdapter.notifyDataSetChanged();
分别用
selectList.remove(i);
// or selectList.add(item);
showAdapter = new ShowItemAdapter(context, idList, selectList);
setAdapter(showAdapter);