It is weirded because it happens only in some phones those resolution are FHD.
When UI is shown, everything seems ok. When I click items and call notifyDataSetChanged(), item won't refresh it's look. I need to click on the ListView anywhere again, the item will refresh layout to the correct look.
If the listview changes size (ex: search function will redesign whole layout), everything becomes OK.
Here is the ListView code:
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();
}
...
}
....
}
And here is Adapter code,
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);
}
}
}
Anybody give me a hand?
I found those phones work correctly will cause the same issue when debugging pause at getView(). I think .. it is like "Views has been updated so it won't refresh views." But views update during debugging make the ui not refresh actually, then it works in the wrong way.
I guess this is about refreshing views.
I see a possible code conflict and a timing issue between getView() of the adapter and the onItemClick().
Allow me to explain. In getView(), there is code
if (mIdList.get(position).id == selectList.get(i).id)
Note: This checks the value of selectList
, which is not even declared in this Adapter class. I assume you meant mSelectList
. But let's move on...
In onItemClick(), there is code
if (idList.get(position).id == selectID) {
...
selectList.remove(i);
...
Note: This code removes an item from selectList
, while in getView
(), it is checking for the same object. We cannot know which code will run first. But I have an idea...
getView
() is a virtual callback method where the BaseAdapter may trigger the method when it requires a row or item to display. So when you remove an item from a Listview, the Adapter may not request a refresh, no matter what you do in code. And the adapter ShowItemAdapter
is responsible for all row/views refresh.
Suggestion: Place the same code (for remove/add item) in getView
() to avoid these kind of code conflicts.
Let us know and good luck with this odd anomaly.
Tommy Kwee
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With