Search code examples
androidlistviewandroid-adapterview

Android ListView row interaction disabled after onItemClick?


I have listView with several rows of data that are populated from a Custom Array Adapter. In that row I have a few textviews hidden that are visible when that row is clicked. After they are visible, I would like to then click the row again to re-hide the labels. I got the first piece to work but then the onItemClick doesn't seem to fire after that. One of those textViews also has clickable URLs and those seem to be "disabled" also. They show as highlighted URLs but I can't click them.

Should I be using listview for this? is there a way to reset the row so it can be interacted with again?

Edit

Here's some of my code:

Activity:

public class SeasonsActivity extends AppCompatActivity {
private String locationShortName = "";
private ArrayList<Object> seasons;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_seasons);
    ActionBar ab = getSupportActionBar();

    ab.setDisplayHomeAsUpEnabled(true);

    AdView mAdView = (AdView) findViewById(R.id.adView);
    AdRequest adRequest = new AdRequest.Builder().addTestDevice(AdRequest.DEVICE_ID_EMULATOR).build();
    mAdView.loadAd(adRequest);

    seasons = LocationsActivity.seasons;
    locationShortName = getIntent().getStringExtra("locationShortName");

    if(locationShortName.length() > 0)
        ab.setTitle(locationShortName);

    final SeasonAdapter adapter = new SeasonAdapter(getBaseContext(),seasons);

    final ListView listView = (ListView)findViewById(R.id.list_season);
    listView.setAdapter(adapter);
    adapter.notifyDataSetChanged();

    listView.setOnItemClickListener(new android.widget.AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            Object item = adapter.getItem(position);
            if (item instanceof Season) {
                Season s = (Season)item;
                adapter.selectRow(s.getId());
                adapter.notifyDataSetChanged();
            }
        }
    });

}

}

and my adapter class:

class SeasonAdapter extends BaseAdapter {

private ArrayList<String> selectedRowGuids = new ArrayList<String>();

private static final int TYPE_ITEM = 0;
private static final int TYPE_SEPARATOR = 1;

private ArrayList<Object> mData = new ArrayList<Object>();

private LayoutInflater mInflater;

public SeasonAdapter(Context context, ArrayList<Object> seasonsArray) {
    this.mData = seasonsArray;
    this.mInflater = (LayoutInflater) context
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}

public void addItem(final Object item) {
    mData.add(item);
    notifyDataSetChanged();
}

public void selectRow(String guid)
{
    if(selectedRowGuids.contains(guid))
    {
        selectedRowGuids.remove(guid);
    }
    else {
        selectedRowGuids.add(guid);
    }
}

@Override
public int getItemViewType(int position) {
    if (getItem(position) instanceof Season) {
        return TYPE_ITEM;
    }

    return TYPE_SEPARATOR;
}

@Override
public int getViewTypeCount() {
    return 2;
}

@Override
public int getCount() {
    return mData.size();
}

@Override
public Object getItem(int position) {
    return mData.get(position);
}

@Override
public long getItemId(int position) {
    return position;
}

public View getView(int position, View convertView, ViewGroup parent) {
    int rowType = getItemViewType(position);

    if (convertView == null) {
        switch (rowType) {
            case TYPE_ITEM:
                convertView = mInflater.inflate(R.layout.activity_season_list_row, null);
                break;
            case TYPE_SEPARATOR:
                convertView = mInflater.inflate(R.layout.season_header_row, null);
                break;
        }
    }

    switch (rowType)
    {
        case TYPE_ITEM:
            Season season = (Season)getItem(position);
            convertView = getSeasonView(convertView, season, position);
            break;
        case TYPE_SEPARATOR:
            String header = (String)getItem(position);
            convertView = getSeasonHeaderView(convertView,header);
            break;
    }

    return convertView;
}


public View getSeasonView(View rowView, Season currentSeason,Integer position) {
    if (currentSeason != null) {
        SeasonView view = new SeasonView();

        view.txtTitle = (TextView) rowView.findViewById(R.id.season_title);
        view.txtDetails = (TextView) rowView.findViewById(R.id.season_details);
        view.txtStartDate = (TextView) rowView.findViewById(R.id.season_startdate);
        view.txtEndDate = (TextView) rowView.findViewById(R.id.season_enddate);

        view.txtTitle.setText(currentSeason.getTitle());
        view.txtDetails.setText(currentSeason.getDetails());

        SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");

        view.txtStartDate.setText(sdf.format(currentSeason.getStartDate()));
        view.txtEndDate.setText(sdf.format(currentSeason.getEndDate()));

        if(selectedRowGuids.contains(currentSeason.getId()))
        {
            view.txtDetails.setVisibility(View.VISIBLE);
            rowView.findViewById(R.id.lblDetail).setVisibility(View.VISIBLE);
            rowView.setSelected(true);
        }
        else
        {
            view.txtDetails.setVisibility(View.GONE);
            rowView.findViewById(R.id.lblDetail).setVisibility(View.GONE);
        }

        rowView.setTag(view);
    }

    return rowView;
}

public View getSeasonHeaderView(View rowView,String title) {
    SeasonHeaderView view = new SeasonHeaderView();
    view.txtTitle = (TextView) rowView.findViewById(R.id.header_title);

    rowView.setTag(view);

    if (title != null) {
        view.txtTitle.setText(title);
    }
    return rowView;
}

public class SeasonHeaderView {
    public TextView txtTitle;
}

public class SeasonView {
    public TextView txtTitle;
    public TextView txtDetails;
    public TextView txtStartDate;
    public TextView txtEndDate;
}

}


Solution

  • If you want to hide/show the items, then add clicklistener in adapter to the control on which you want to handle the visibility. Then in listener you can check the current status and do the opposite.

    btn.setOnClickListener(new OnClickListener() { //btn by which you want to handle event
    
    	@Override
    	public void onClick(View v) {
    		// TODO Auto-generated method stub
    		if(tv.getVisibility()==View.VISIBLE){ //tv you want to hide/show
              tv.setVisibility(View.GONE);
            }else{
              tv.setVisibility(View.VISIBLE);
            }
    	}
    });

    You can use any control of that layout instead of button, you can use whole layout also.