3

Can't seem to determine the problem with my adapter. I am trying to put a progress bar underneath a checkedTextView in order to minimize the number of elements and the hassle of a relative layout (putting the loading bar underneath and the radio button to the right side of the 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 issue is that the adapter is non-responsive. I update the WifiP2pClient with an asynchronous task and call notifyDataSetChanged() quite often, but the data displayed in the UI never updates. In addition, when I press the listView, nothing happens (not even the normal black depress animation).

If I instead use a regular ArrayListAdapter<String> object, the arrayList updates properly, so I know that the rest of the code works properly, it's something wrong with this arrayAdapter.

EDIT: I'm putting the onClickListener() in the getView() based on this post: How to use RadioGroup in ListView custom adapter?

EDIT2: I got the adapter to properly respond to the changes made to it AND the press by the user by ensuring that the checkedViewText and progressBar objects were properly updated when the view was not null by using a ViewHolder object and the view's setTag() and getTag() functionality. I will be pasting this code in shortly. I still don't have the adapter returning proper values for getCheckedItemPosition(), however.

Community
  • 1
  • 1
user1519665
  • 511
  • 5
  • 16

1 Answers1

0

After doing enough experimenting and getting a lucky break, here is my finished code (for future googlers and comparison's sake).

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's 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;
    }
}
user1519665
  • 511
  • 5
  • 16