laminatefish
laminatefish

Reputation: 5246

Override default expandablelistview expand behaviour

How does one go about manually expanding and collapsing an expandablelistview? I know of expandGroup(), but am not sure where to set the onClickListener(), as half of this code, is in a separate library project.

ExpandableDeliveryList

package com.goosesys.dta_pta_test;
[imports removed to save space]

public class ExpandableDeliveryList<T> extends ExpandableListActivity {

private ArrayList<GooseDeliveryItem> parentItems = new ArrayList<GooseDeliveryItem>();
private ArrayList<DeliverySiteExtras> childItems = new ArrayList<DeliverySiteExtras>();

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // CREATE THE EXPANDABLE LIST AND SET PROPERTIES //
    final ExpandableListView expandList = getExpandableListView();
    expandList.setDividerHeight(0);
    expandList.setGroupIndicator(null);
    expandList.setClickable(false); 

    // LIST OF PARENTS //
    setGroupParents();

    // CHILDREN //
    setChildData();

    // CREATE ADAPTER //
    GooseExpandableArrayAdapter<?> adapter = new GooseExpandableArrayAdapter<Object>(
            R.layout.goose_delivery_item,
            R.layout.goose_delivery_item_child,
            parentItems, 
            childItems);
    adapter.setInflater((LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE), this);       
    expandList.setAdapter(adapter);
    expandList.setOnChildClickListener(this);   
}

@Override
public boolean onOptionsItemSelected(MenuItem item)
{
    switch(item.getItemId())
    {
        case android.R.id.home:
        {
            Intent intent = new Intent(this, Main.class);
            intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
            startActivity(intent);
            return true;
        }

        default:
        {
            return super.onOptionsItemSelected(item);
        }
    }
}

public void setGroupParents()
{
    DatabaseHelper dbHelper = new DatabaseHelper(this);
    List<DeliverySite> sites = new ArrayList<DeliverySite>();       
    sites = dbHelper.getAllSites();

    GooseDeliveryItem[] deliveries = new GooseDeliveryItem[sites.size()];

    for(int i=0; i<sites.size(); i++)
    {
        Delivery del = new Delivery();

        try
        {
            del = dbHelper.getDeliveryByJobNo(sites.get(i).id);
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }

        final GooseDeliveryItem gdi;

        if((Double.isNaN(sites.get(i).lat)) || (Double.isNaN(sites.get(i).lng)))
        {
            gdi = new GooseDeliveryItem(sites.get(i).id, sites.get(i).company);
        }
        else
        {
            gdi = new GooseDeliveryItem(sites.get(i).id, sites.get(i).company, sites.get(i).lat, sites.get(i).lng);
        }

        if(del.getReportedFully() == 1)
        {
            gdi.isReportedFully = true;
        }

        deliveries[i] = gdi;
    }

    // FINALLY ADD THESE ITEMS TO THE PARENT ITEMS LIST ARRAY //
    for(GooseDeliveryItem g : deliveries)
        parentItems.add(g);
}

public void setChildData()
{       
    //DatabaseHelper dbHelper = new DatabaseHelper(this);
    ArrayList<DeliverySiteExtras> extras = new ArrayList<DeliverySiteExtras>();

    for(int i=0; i<parentItems.size(); i++)
    {
        DeliverySiteExtras dse = new DeliverySiteExtras();
        extras.add(dse);
    }

    childItems = extras;
}
}

ArrayAdapter

package com.goosesys.gooselib.Views;

[imports removed to save space]

public class GooseExpandableArrayAdapter<Object> extends BaseExpandableListAdapter 
{
private Activity activity;
private ArrayList<DeliverySiteExtras> childItems;
private LayoutInflater inflater;
ArrayList<GooseDeliveryItem> parentItems;
private DeliverySiteExtras child;
private int layoutId;
private int childLayoutId;

public GooseExpandableArrayAdapter(int layoutId, int childLayoutId, ArrayList<GooseDeliveryItem> parents, ArrayList<DeliverySiteExtras> children)
{
    this.layoutId = layoutId;
    this.childLayoutId = childLayoutId;
    this.parentItems = (ArrayList<GooseDeliveryItem>) parents;
    this.childItems = (ArrayList<DeliverySiteExtras>)children;
}

public GooseExpandableArrayAdapter(ArrayList<GooseDeliveryItem> parents, ArrayList<DeliverySiteExtras> children, int layoutId)
{
    this.parentItems = parents;
    this.childItems = children;
    this.layoutId = layoutId;
}

public void setInflater(LayoutInflater inflater, Activity activity)
{
    this.inflater = inflater;
    this.activity = activity;
}   

@Override
public Object getChild(int arg0, int arg1) 
{
    return null;
}

@Override
public long getChildId(int arg0, int arg1) 
{
    return 0;
}

/*
 * Child view get method
 * Utilise this to edit view properties at run time
 */
@Override
public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) 
{
    child = childItems.get(groupPosition);

    if(convertView == null)
    {
        convertView = inflater.inflate(this.childLayoutId, null);           
    }       

    // GET ALL THE OBJECT VIEWS AND SET THEM HERE //
    setGeoLocation(groupPosition, convertView);

    convertView.setOnClickListener(new View.OnClickListener() 
    {       
        @Override
        public void onClick(View arg0) 
        {
        }
    });

    return convertView;
}

@Override
public void onGroupCollapsed(int groupPosition)
{
    super.onGroupCollapsed(groupPosition);
}

@Override
public void onGroupExpanded(int groupPosition)
{
    super.onGroupExpanded(groupPosition);
}

@Override
public int getChildrenCount(int groupPosition) 
{
    return 1; //childItems.get(groupPosition);
}

@Override
public Object getGroup(int groupPosition) 
{
    return null;
}

@Override
public int getGroupCount() 
{
    return parentItems.size();
}

@Override
public long getGroupId(int arg0) 
{
    return 0;
}

/*
 * Parent View Object get method
 * Utilise this to edit view properties at run time.
 */
@Override
public View getGroupView(final int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) 
{   
    if(convertView == null)
    {
        convertView = inflater.inflate(this.layoutId, null);
    }

    // GET ALL OBJECT VIEWS AND SET THEM HERE -- PARENT VIEW //     
    TextView name = (TextView)convertView.findViewById(R.id.customerName);
    name.setText(parentItems.get(groupPosition).customerText);  

    ImageView go = (ImageView)convertView.findViewById(R.id.moreDetails);
    go.setOnClickListener(new View.OnClickListener() 
    {
        @Override
        public void onClick(View v) 
        {           
            Intent i = new Intent(activity, DeliveryJobActivity.class);
            i.putExtra("obj", parentItems.get(groupPosition));
            activity.startActivity(i);
        }
    });

    return convertView;
}

@Override
public boolean hasStableIds() 
{
    return false;
}

@Override
public boolean isChildSelectable(int arg0, int arg1) 
{
    return false;
}

private void setGeoLocation(final int groupPosition, View parent)
{
    GeoLocation geoLocation = new GeoLocation(activity);
    final double lat = geoLocation.getLatitude();
    final double lng = geoLocation.getLongitude();

    // GET OUR START LOCATION //
    Location startLocation = new Location("Start");
    startLocation.setLatitude(lat);
    startLocation.setLongitude(lng);

    // GET OUR DESTINATION //
    Location destination = new Location("End");
    destination.setLatitude(((GooseDeliveryItem)parentItems.get(groupPosition)).latitude);
    destination.setLongitude(((GooseDeliveryItem)parentItems.get(groupPosition)).longitude);        

    double distanceValue = startLocation.distanceTo(destination);

    TextView tv = (TextView)parent.findViewById(R.id.extraHeader);
    tv.setText(parentItems.get(groupPosition).customerText + " information:");

    TextView ds = (TextView)parent.findViewById(R.id.deliveryDistance);
    ds.setText("Distance (from location): " + String.valueOf(Math.ceil(distanceValue * GooseConsts.METERS_TO_A_MILE)) + " Mi (approx)");

    ImageView img = (ImageView)parent.findViewById(R.id.directionsImage);
    img.setOnClickListener(new View.OnClickListener() {         
        @Override
        public void onClick(View arg0) {
            // invoke google maps with lat / lng position
            Intent navigation = new Intent(Intent.ACTION_VIEW, Uri.parse(
                    "http://maps.google.com/maps?saddr="
                    + (lat) + "," + (lng)
                    + "&daddr="
                    + ((GooseDeliveryItem)parentItems.get(groupPosition)).latitude + ","
                    + ((GooseDeliveryItem)parentItems.get(groupPosition)).longitude                             
                    ));
            activity.startActivity(navigation);                 
        }
    });
}
}

Ideally, my bosses would like to have a "+" button, that when clicked expands the listview manually. Rather than clicking anywhere on the view and it doing it automatically. Is this possible? Also, setting setClickable(false) seems to have no effect. Because it'll still expand when any list item is clicked. Am I missing something there also?

Cheers.

Upvotes: 2

Views: 4216

Answers (1)

user3053075
user3053075

Reputation: 146

You can add an ExpandableListView Group Click Listener ("ExpandableListView::setOnGroupClickListener") to monitor and suppress click event for the ListView Groups. Using your code example, this would be done in your "ExpandableDeliveryList" module after you create the ExpandableListView.

Then in your "+" (and "-") Button click handlers, you can add logic to expand/collapse some or all of the ListView Groups using the "ExpandableListView::expandGroup()" and "ExpandableListView::collapseGroup()" methods.

You do not need to return "false" from the overridden "isChildSelectable()" method as this has no effect on what you are trying to accomplish (and will prevent anyone from clicking/selecting child items in the ListView).

Code examples are shown below:

// CREATE THE EXPANDABLE LIST AND SET PROPERTIES //
final ExpandableListView expandList = getExpandableListView();      
//...

expandList.setOnGroupClickListener(new android.widget.ExpandableListView.OnGroupClickListener() {

    @Override
    public boolean onGroupClick(    ExpandableListView  parent,
                                    View                view,
                                    int                 groupPosition,
                                    long                id) {

        //  some code...

        //  return "true" to consume the event (and prevent the Group from expanding/collapsing) / "false" to allow the Group to expand/collapse normally
        return true;
    }
});

To manually expand and collapse the ListView Groups:

//  enumerate thru the ExpandableListView Groups
//  [in this code example, a single index is used...]
int groupPosition = 0;

//  expand the ListView Group/s
if (m_expandableListView.isGroupExpanded(groupPosition) == false) {

    //  API Level 14+ allows you to animate the Group expansion...
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
        m_expandableListView.expandGroup(groupPosition, true);
    }

    //  else just expand the Group without animation
    else {
        m_expandableListView.expandGroup(groupPosition);
    }               
}

//  collapse the ListView Group/s
else {
    m_expandableListView.collapseGroup(groupPosition);          
}

Hope this Helps.

Upvotes: 8

Related Questions