Home | History | Annotate | Download | only in view
      1 /*
      2  * Copyright (C) 2007 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.example.android.apis.view;
     18 
     19 import android.app.ExpandableListActivity;
     20 import android.content.AsyncQueryHandler;
     21 import android.content.ContentUris;
     22 import android.content.Context;
     23 import android.database.Cursor;
     24 import android.net.Uri;
     25 import android.os.Bundle;
     26 import android.provider.ContactsContract.CommonDataKinds.Phone;
     27 import android.provider.ContactsContract.Contacts;
     28 import android.widget.CursorTreeAdapter;
     29 import android.widget.SimpleCursorTreeAdapter;
     30 
     31 /**
     32  * Demonstrates expandable lists backed by Cursors
     33  */
     34 public class ExpandableList2 extends ExpandableListActivity {
     35 
     36     private static final String[] CONTACTS_PROJECTION = new String[] {
     37         Contacts._ID,
     38         Contacts.DISPLAY_NAME
     39     };
     40     private static final int GROUP_ID_COLUMN_INDEX = 0;
     41 
     42     private static final String[] PHONE_NUMBER_PROJECTION = new String[] {
     43             Phone._ID,
     44             Phone.NUMBER
     45     };
     46 
     47     private static final int TOKEN_GROUP = 0;
     48     private static final int TOKEN_CHILD = 1;
     49 
     50     private static final class QueryHandler extends AsyncQueryHandler {
     51         private CursorTreeAdapter mAdapter;
     52 
     53         public QueryHandler(Context context, CursorTreeAdapter adapter) {
     54             super(context.getContentResolver());
     55             this.mAdapter = adapter;
     56         }
     57 
     58         @Override
     59         protected void onQueryComplete(int token, Object cookie, Cursor cursor) {
     60             switch (token) {
     61             case TOKEN_GROUP:
     62                 mAdapter.setGroupCursor(cursor);
     63                 break;
     64 
     65             case TOKEN_CHILD:
     66                 int groupPosition = (Integer) cookie;
     67                 mAdapter.setChildrenCursor(groupPosition, cursor);
     68                 break;
     69             }
     70         }
     71     }
     72 
     73     public class MyExpandableListAdapter extends SimpleCursorTreeAdapter {
     74 
     75         // Note that the constructor does not take a Cursor. This is done to avoid querying the
     76         // database on the main thread.
     77         public MyExpandableListAdapter(Context context, int groupLayout,
     78                 int childLayout, String[] groupFrom, int[] groupTo, String[] childrenFrom,
     79                 int[] childrenTo) {
     80 
     81             super(context, null, groupLayout, groupFrom, groupTo, childLayout, childrenFrom,
     82                     childrenTo);
     83         }
     84 
     85         @Override
     86         protected Cursor getChildrenCursor(Cursor groupCursor) {
     87             // Given the group, we return a cursor for all the children within that group
     88 
     89             // Return a cursor that points to this contact's phone numbers
     90             Uri.Builder builder = Contacts.CONTENT_URI.buildUpon();
     91             ContentUris.appendId(builder, groupCursor.getLong(GROUP_ID_COLUMN_INDEX));
     92             builder.appendEncodedPath(Contacts.Data.CONTENT_DIRECTORY);
     93             Uri phoneNumbersUri = builder.build();
     94 
     95             mQueryHandler.startQuery(TOKEN_CHILD, groupCursor.getPosition(), phoneNumbersUri,
     96                     PHONE_NUMBER_PROJECTION, Phone.MIMETYPE + "=?",
     97                     new String[] { Phone.CONTENT_ITEM_TYPE }, null);
     98 
     99             return null;
    100         }
    101     }
    102 
    103     private QueryHandler mQueryHandler;
    104     private CursorTreeAdapter mAdapter;
    105 
    106     @Override
    107     public void onCreate(Bundle savedInstanceState) {
    108         super.onCreate(savedInstanceState);
    109 
    110         // Set up our adapter
    111         mAdapter = new MyExpandableListAdapter(
    112                 this,
    113                 android.R.layout.simple_expandable_list_item_1,
    114                 android.R.layout.simple_expandable_list_item_1,
    115                 new String[] { Contacts.DISPLAY_NAME }, // Name for group layouts
    116                 new int[] { android.R.id.text1 },
    117                 new String[] { Phone.NUMBER }, // Number for child layouts
    118                 new int[] { android.R.id.text1 });
    119 
    120         setListAdapter(mAdapter);
    121 
    122         mQueryHandler = new QueryHandler(this, mAdapter);
    123 
    124         // Query for people
    125         mQueryHandler.startQuery(TOKEN_GROUP, null, Contacts.CONTENT_URI, CONTACTS_PROJECTION,
    126                 Contacts.HAS_PHONE_NUMBER + "=1", null, null);
    127     }
    128 
    129     @Override
    130     protected void onDestroy() {
    131         super.onDestroy();
    132 
    133         // Null out the group cursor. This will cause the group cursor and all of the child cursors
    134         // to be closed.
    135         mAdapter.changeCursor(null);
    136         mAdapter = null;
    137     }
    138 }
    139