knirirr
knirirr

Reputation: 2827

Custom ArrayAdapter buttons, getting item at position

I have an app which shows a list of items with a custom ArrayAdapter. Listeners can be set up to allow users to tap a row to open another activity to process the item referred to by that row, or to long press to delete an item. Here's an example of one of these listeners, which is defined in the corresponding ListActivity:

// single tap selects an item for viewing
list.setOnItemClickListener(new AdapterView.OnItemClickListener()
{
  @Override
  public void onItemClick(AdapterView<?> arg0, View view, int position, long id)
  {
    Project p = projects.get(position);
    Intent intent = new Intent(ListProjectActivity.this, CountingActivity.class);
    intent.putExtra("project_id",p.id);
    startActivity(intent);
  }
});

However, I've found that long pressing is something that many users don't find intuitive, and so I'd prefer to put a button into the custom layout for each row and then attach a listener to the TextView in the row (to represent the single tap to load another activity) and to the button (for deleting). So, I put listeners like this into the ArrayAdapter itself:

public class ProjectListAdapter extends ArrayAdapter<Project>
{
     // set up constructor and project holder
     //....

     @Override
     public View getView(int position, View convertView, ViewGroup parent)
     {
        View row = convertView;
        ProjectHolder holder = null;

        if(row == null)
        {
            LayoutInflater inflater = ((Activity)context).getLayoutInflater();
            row = inflater.inflate(layoutResourceId, parent, false);

            holder = new ProjectHolder();
            holder.txtTitle = (TextView) row.findViewById(R.id.txtTitle);
            holder.deleteProject = (ImageButton) row.findViewById(R.id.deleteProject);

            holder.txtTitle.setOnClickListener(mOnTitleClickListener);
            holder.deleteProject.setOnClickListener(mOnDeleteClickListener);
            // the button and textview above could be tagged with position, but that
            // re-sets as the rows are re-used

            row.setTag(holder);
        }
        else
        {
            holder = (ProjectHolder)row.getTag();
        }

        holder.txtTitle.setText(project.name);

        return row;
      }

      private View.OnClickListener mOnTitleClickListener = new View.OnClickListener() {
      @Override
      public void onClick(View v)
      {
        Project p = null; // how can I get this here?
        Intent intent = new Intent(getContext(), CountingActivity.class);
        intent.putExtra("project_id",p.id);
        mContext.startActivity(intent);
      }
     };

     // the delete listener is similar

   }

The difficulty here is that I need to get the Project object associated with the ArrayAdapter at the position tapped, so I can either delete the object or open a new activity to process it. Can anyone suggest how I might get the object associated with the row tapped when using a listener of that sort, please?

Upvotes: 0

Views: 1403

Answers (2)

Blackbelt
Blackbelt

Reputation: 157467

You can have a class that implements OnClickListener, a pass the object to the constructor:

 private class MyOnClickListener implements OnClickListener {
     private Project mProject;
     public MyOnClickListener(Project p) {
           mProject = p;
     }

      @Override
      public void onClick(View v) { 
        Intent intent = new Intent(getContext(), CountingActivity.class);
        intent.putExtra("project_id",mProject.id);
        mContext.startActivity(intent);
      }
}


      getView(...) {

        // other logic

        holder.txtTitle.setOnClickListener(new MyOnClickListener((Project)getItem(position)));
        holder.txtTitle.setText(project.name);

        return row;
      }

Upvotes: 2

Suhail Mehta
Suhail Mehta

Reputation: 5542

public class ProjectListAdapter extends ArrayAdapter<Project>
{
     // set up constructor and project holder
     //....

     @Override
     public View getView(int position, View convertView, ViewGroup parent)
     {
        View row = convertView;
        ProjectHolder holder = null;

        if(row == null)
        {
            LayoutInflater inflater = ((Activity)context).getLayoutInflater();
            row = inflater.inflate(layoutResourceId, parent, false);

            holder = new ProjectHolder();
            holder.txtTitle = (TextView) row.findViewById(R.id.txtTitle);
            holder.deleteProject = (ImageButton) row.findViewById(R.id.deleteProject);

            row.setTag(holder);
        }
        else
        {
            holder = (ProjectHolder)row.getTag();
        }

        holder.txtTitle.setText(project.name);


 holder.txtTitle.setOnClickListener() {
      @Override
      public void onClick(View v)
      {
        // you can get the PROJECT refrence here
        Intent intent = new Intent(getContext(), CountingActivity.class);
        intent.putExtra("project_id",p.id);
        mContext.startActivity(intent);
      }
     };

     // the delete listener is similar

        return row;
      }



   }

Upvotes: 1

Related Questions