Completely unresponsive Android custom adapter
Unable to identify the problem with my adapter. I am trying to set up a progress bar to minimize the number of items and the complexity of the relative layout (by placing the pad on the bottom and the radio button to the right side textView
).
protected void onCreate(Bundle savedInstanceState)
{
...
connections = new ArrayList<WifiP2pClient>();//make an arraylist for the connections
listView = (ListView)findViewById(R.id.connectionsListView);//initialize the list view
adapter = new P2PClientArrayAdapter(this, android.R.layout.simple_List_item_single_choice, connections);//create an array adapter
listView.setAdapter(adapter);//attach the adapter to the listView
listView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
...
}
public class P2PClientArrayAdapter extends ArrayAdapter<WifiP2pClient>
{
private CheckedTextView checkedTextView;
private ProgressBar progressBar;
int lastRadioButtonPressed;
CheckedTextView lastPressedTextView;
public P2PClientArrayAdapter(Context context, int resource, List<WifiP2pClient> clients)
{
super(context, resource, clients);
lastRadioButtonPressed = -1;
lastPressedTextView = null;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent)
{
View row = convertView;
WifiP2pClient client = getItem(position);
if(row == null)
{
LayoutInflater inflater = (LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = inflater.inflate(R.layout.row_layout, parent, false);
checkedTextView = (CheckedTextView)row.findViewById(R.id.clientToString);
progressBar = (ProgressBar)row.findViewById(R.id.clientProgressBar);
row.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
if(position != lastRadioButtonPressed)
{
if(lastPressedTextView != null)
{
lastPressedTextView.setChecked(false);
}
lastRadioButtonPressed = position;
lastPressedTextView = checkedTextView;
checkedTextView.setChecked(true);
P2PClientArrayAdapter.this.notifyDataSetChanged();
}
}
});
}
checkedTextView.setText(client.toString());
progressBar.setProgress(client.getProgress());
return row;
}
}
Currently, the problem is that the adapter is not responding. I update WifiP2pClient
with an asynchronous task and call notifyDataSetChanged()
quite often, but the data shown in the UI is never updated. Also, when I click listView
, nothing happens (not even the usual black overwhelming animation).
If I use a regular object instead ArrayListAdapter<String>
, it arrayList
updates correctly, so I know the rest of the code is working correctly, there is something wrong with that arrayAdapter
.
EDIT: I put onClickListener()
in getView()
on the basis of this report:
How to use a custom adapter RadioGroup in ListView?
EDIT2: I got an adapter to react correctly to the changes I made. And push it, making sure the objects checkedViewText
and progressBar
have been properly updated when the view was not null using ViewHolder
object and view setTag()
and getTag()
. I will insert this code shortly. However, I still don't have an adapter returning the correct values for getCheckedItemPosition()
.
source to share
After doing enough experimentation and having a good break, here is my finished code (for future googlers and comparisons).
public class P2PClientArrayAdapter extends ArrayAdapter<WifiP2pClient>
{
//The viewholder object isn't neccessary but it allows us to Tag.set()
//with no indicies because we have it wrapped in one big object
private class ViewHolder
{
CheckedTextView checkedTextView;
ProgressBar progressBar;
}
int lastRadioButtonPressed;
CheckedTextView lastPressedTextView;
public P2PClientArrayAdapter(Context context, int resource, List<WifiP2pClient> clients)
{
super(context, resource, clients);
lastRadioButtonPressed = -1;
lastPressedTextView = null;
}
//I wasn't sure how to override ListView getCheckedItemPosition()
//So I made my own and then changed the calling code.
public int getCheckedItemPosition()
{
return lastRadioButtonPressed;
}
//If you delete an element in your list, you have
//to reset the pointer or you'll have logic errors.
public void resetCheckedItemPosition()
{
lastRadioButtonPressed = -1;
lastPressedTextView = null;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent)
{
View row = convertView;
WifiP2pClient client = getItem(position);
final ViewHolder viewHolder;
if(row == null)
{
LayoutInflater inflater = (LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = inflater.inflate(R.layout.row_layout, parent, false);
viewHolder = new ViewHolder();
viewHolder.checkedTextView = (CheckedTextView)row.findViewById(R.id.clientToString);
viewHolder.progressBar = (ProgressBar)row.findViewById(R.id.clientProgressBar);
row.setTag(viewHolder);
}
else
{
viewHolder = (ViewHolder)row.getTag();
}
row.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
if(position != lastRadioButtonPressed)
{
if(lastPressedTextView != null)
{
lastPressedTextView.setChecked(false);
}
lastRadioButtonPressed = position;
lastPressedTextView = viewHolder.checkedTextView;
viewHolder.checkedTextView.setChecked(true);
}
}
});
viewHolder.checkedTextView.setText(client.toString());
viewHolder.progressBar.setProgress(client.getProgress());
return row;
}
}
source to share