Developing on Bada 2.0 – How to use ListContextItem in a ListView/GroupedListView

This post is part 4 of 6 in the series Developing in Bada 2.0

Hi all, in this post I’m going to show you how to use ListContextItem, a really cool feature that I discovered while writing the previous posts about ListView and GroupedListView. If you are new to ListView and GroupedListView, I suggest you to read my previous posts about the topic as this post assumes you already know how to setup a basic list.
As the name suggests, with a ListContextItem you can add contextual actions to an item in a ListView. The way this works graphically is that you can slide an item inside the ListView or GroupedListView in order to reveal one or more context buttons, see the picture on the left for an example.

Let’s say you are building an addressbook application and you have your contacts list populated, you now need a way to let your user call a contact or send him an SMS or an e-mail, and you want it to be easy, keeping your app user-friendly.
Solution is near: by using a ListContextItem you can let your user call/sms/e-mail a person very quickly just by sliding the corresponding item inside the list and touching the corresponding context button.

In this post I’m going to guide you step-by-step to create the sample app showed in the picture above.

Before we start

To go on you need a basic application with a ListView, see this post if you don’t have one.

Now, in the form class header declare an array that will hold your contacts’ names:

Osp::Base::Collection::ArrayList * pContacts;

And four Bitmap pointer to hold the three icons used for the three context buttons and the user placeholder used in every list item:

Osp::Graphics::Bitmap * pCallIcon;
Osp::Graphics::Bitmap * pSmsIcon;
Osp::Graphics::Bitmap * pEmailIcon;
Osp::Graphics::Bitmap * pUserPlaceholderIcon;

Below you’ll find the icons I used for this sample, as always, thanks to mysitemyway.com:




Import this icons into your project by right-clicking into the resource explorer window, then select “New Image…” and select “ScreenDensity-High” then browse to the icons.

Now we need to populate our contacts list, go to the form OnInitializing() and add the following code:

pContacts = new ArrayList();
pContacts->Construct();
pContacts->Add(*new String(L"Arthur Dent"));
pContacts->Add(*new String(L"Ford Prefect"));
pContacts->Add(*new String(L"Zaphod Beeblebrox"));
pContacts->Add(*new String(L"Vogon Headquarters"));
pContacts->Add(*new String(L"Marvin"));
pContacts->Add(*new String(L"Tricia McMillan"));

And also we have to load the icons:

AppResource * res = Application::GetInstance()->GetAppResource();
pCallIcon = res->GetBitmapN(L"ctx_phone_call.png");
pSmsIcon = res->GetBitmapN(L"ctx_send_sms.png");
pEmailIcon = res->GetBitmapN(L"ctx_send_email.png");
pUserPlaceholderIcon = res->GetBitmapN(L"user_placeholder.png");

Remember to delete these resources inside the form’s OnTerminating() method:

delete pCallIcon;
delete pSmsIcon;
delete pEmailIcon;
delete pUserPlaceholderIcon;
 
/* Remove all strings from pContacts array and deallocate them */
pContacts->RemoveAll(true);
/* Deallocate the pContacts array itself */
delete pContacts;

Now we are ready to start the cool part.

How to configure the ListContextItem

A ListContextItem is composed of one or more elements, each element being in practice a context button, we are going to need three elements: “Call”, “SMS”, “E-mail”. You can configure as many elements as you need, keep present however that if you create too many elements, they will start overlapping each other causing a really ugly effect. The configured ListContextItem is then added to a list item (SimpleItem or CustomItem) right after the item is built inside the CreateItem method, here’s a step-by-step example:

First: retrieve the contact name at this position:

ListItemBase* Form1::CreateItem(int itemIndex, int itemWidth) {
    String * contact = static_cast<String *>(pContacts->GetAt(itemIndex));

Second: Create and configure a CustomItem with an icon element on the left, a text element for the person name and another text element for the explanation text “Slide for more actions”

 
    CustomItem * pItem = new CustomItem();
 
    int listItemHeight = 100;
    int nameHeight = listItemHeight *0.6;
    int commentHeight = listItemHeight *0.4;
 
    pItem->Construct(Dimension(itemWidth, 100), LIST_ANNEX_STYLE_NORMAL);
    pItem->AddElement(Rectangle(0, 
                                0, 
                                pUserPlaceholderIcon->GetWidth(), 
                                pUserPlaceholderIcon->GetHeight()), 
                      0, 
                      *pUserPlaceholderIcon, 
                      pUserPlaceholderIcon, 
                      pUserPlaceholderIcon);
 
    pItem->AddElement(Rectangle(pUserPlaceholderIcon->GetWidth(), 
                                0, 
                                itemWidth, 
                                nameHeight), 
                      1, 
                      *contact, 
                      nameHeight, 
                      Color::COLOR_WHITE, 
                      Color::COLOR_BLACK,
                      Color::COLOR_BLACK, 
                      false);
 
    pItem->AddElement(Rectangle(pUserPlaceholderIcon->GetWidth(), 
                                nameHeight, 
                                itemWidth, 
                                commentHeight), 
                      2, 
                      L"Slide for more actions", 
                      commentHeight, 
                      Color::COLOR_GREY, 
                      Color::COLOR_BLACK, 
                      Color::COLOR_BLACK, 
                      false);
 
    pItem->SetElementTextVerticalAlignment(1, ALIGNMENT_MIDDLE);
    pItem->SetElementTextVerticalAlignment(2, ALIGNMENT_MIDDLE);

Third: Create and configure a ListContextItem with three elements (buttons): “Call”, “SMS”, “E-mail”, note that each element has a specific id passed as first parameter to the AddElement() method that will be used later to catch its events, ids are declared in the .h file:

    static const int ID_CONTEXT_ITEM_CALL = 0;
    static const int ID_CONTEXT_ITEM_SMS = 1;
    static const int ID_CONTEXT_ITEM_EMAIL = 2;

The second parameter to the AddElement() method is the title text.
Third, fourth and fifth parameters are the icons for the element in its different states normal, pressed and highlighted, the sixth parameter enables the element, use false instead of true to disable user interaction on the element:

 
    ListContextItem* pItemContext = new ListContextItem();
    pItemContext->Construct();
    pItemContext->AddElement(ID_CONTEXT_ITEM_CALL, 
                             L"Call", 
                             *pCallIcon, 
                             *pCallIcon, 
                             pCallIcon, 
                             true);
 
    pItemContext->AddElement(ID_CONTEXT_ITEM_SMS, 
                             L"SMS", 
                             *pSmsIcon, 
                             *pSmsIcon, 
                             pSmsIcon, 
                             true);
 
    pItemContext->AddElement(ID_CONTEXT_ITEM_EMAIL, 
                             L"E-mail", 
                             *pEmailIcon, 
                             *pEmailIcon, 
                             pEmailIcon, 
                             true);

Fourth: Set the ListContextItem to the CustomItem .

    pItem->SetContextItem(pItemContext);
 
    return pItem;
}

That’s all, your list item has now the ability to show three context buttons when slided.

You may also configure the context elements with text only or icon only, three versions of the ListContextItem::AddElement() method are available:

/* Add a text-only element */
result ListContextItem::AddElement (int elementId, 
                                    const Osp::Base::String &text, 
                                    bool enable=true);
 
/* Add an icon-only element */
result ListContextItem::AddElement (int elementId, 
                                    const Osp::Graphics::Bitmap &normalBitmap, 
                                    const Osp::Graphics::Bitmap &pressedBitmap, 
                                    const Osp::Graphics::Bitmap *pHighlightedBitmap=null, 
                                    bool enable=true);
 
/* Add a text+icon element */
result ListContextItem::AddElement (int elementId, 
                                    const Osp::Base::String &text, 
                                    const Osp::Graphics::Bitmap &normalBitmap, 
                                    const Osp::Graphics::Bitmap &pressedBitmap, 
                                    const Osp::Graphics::Bitmap *pHighlightedBitmap=null, 
                                    bool enable=true);

How to handle events from ListContextItem

Whenever a context element is touched by the user, an event is thrown, that can be catched inside an appropriate method provided by the list event listener interface (IListViewItemEventListener or IGroupedListViewItemEventListener).

The method is OnListViewContextItemStateChanged() for a ListView and OnGroupedListViewContextItemStateChanged() for a GroupedListView.

We know which context element(button) has been touched thanks to the elementId parameter, and the list item on which it was pressed thanks to the itemIndex parameter.
This implementation only shows a MessageBox with an appropriate message to the user.

void Form1::OnListViewContextItemStateChanged(Osp::Ui::Controls::ListView &listView,
                                              int itemIndex,
                                              int elementId,
                                              Osp::Ui::Controls::ListContextItemStatus state) {
    String message;
 
    switch (elementId) {
    case ID_CONTEXT_ITEM_CALL:
    	message.Append(L"Calling ");
    	break;
    case ID_CONTEXT_ITEM_SMS:
    	message.Append(L"Sending an SMS to ");
    	break;
    case ID_CONTEXT_ITEM_EMAIL:
    	message.Append(L"Sending an e-mail to ");
    	break;
    }
 
    String * contact = static_cast<String *>(pContacts->GetAt(itemIndex));
    message.Append(*contact);
    message.Append(L"...");
 
    MessageBox messageBox;
    messageBox.Construct(L"Context action", message, MSGBOX_STYLE_OK);
 
    // Calls ShowAndWait - draw, show itself and process events
    int modalResult = 0;
    messageBox.ShowAndWait(modalResult);
 
}

And this is the final result, launch the application and slide with your finger above an item in the list to reveal context buttons:

Hope this post can be useful, this feature is not very well pointed out in the SDK, and I think is really cool after all.

More posts about Bada 2.0 are coming… stay tuned!

Related Posts Plugin for WordPress, Blogger...
Previous Part: Developing on Bada 2.0 – How to manage a GroupedListView
Next Part: Bada 2.0 – How to create an image gallery with the Gallery control
If you enjoyed this post, make sure you subscribe to my RSS feed!
  1. I have the following problem “cannot convert ‘int*’ to ‘Osp::Base::Collection::ArrayList*’ in assignment” regarding this line “pContacts = new ArrayList();” Any idea?
    By the way, awesome tutorial!! Have you thought writing a book about programming bada?

  2. mmmmh… please check this two things:
    1 – did you add “using namespace Osp::Base::Collection” inside the cpp file?
    2 – do you declared pArray in the class header file?
    maybe one if these two could cause your problem…

  3. Drstrangcode! Can i ask u a question? I have array list with about 1000 string items different. how i can add them to list view ? Can u show me code for this problem. Thanks!

    • Hi, you can see that in my previous post about listview, and also in this one.
      Here I used an arraylist with 6 items only, but you can have as many strings as you need, the ListView will not build all 1000 elements at once, it will instead build, say, the first 20, then when you scroll down the list, top items will be destroyed and items from 21 and more will be loaded, so to only keep in memory 10-20 items, don’t know the exact number, but you get the idea…
      Hope this is helpful, thanks for visiting!

    • THANKS for U support! Can I create List View after 1 event; example when i change text on edit field(with INPUT_STYLE_OVERLAY), after i click button “DONE” on virtual keyboard my List View just load? In normal, when i create item as u do, My list view will have 10-20 items null – which appear immediately on my screen then when click done my array will load into list view at item 11 or 21 :cry:
      How to resolve it?

      • No, it does not work like that, I think you misunderstood what I’m saying.
        Let’s say you have your datasource which is an ArrayList, initially it is empty, zero elements inside. Your list draws and since you have zero elements, the list won’t load any row (because your GetItemCount() returns zero).
        From that point on, you can add items inside your datasource (ArrayList) and reload the listview with:

        yourList->UpdateList();
        youtList->RequestRedraw();

        If you add 1000 elements to your arraylist, it is not a problem since the listview only loads items that are currently visible, plus some other elements on the top or on the bottom as a padding.
        When you scroll the list, the items loaded by the list are always only the currently visible items (plus the padding items), if you scrolled to element 10, with element 10 being the first visible item in the listview your list will have loaded (as an example) elements from 8 to 15.

        So, to answer to your question: yes, it is possible to do that, just fill your datasource with data you need to display and reload the list.

        Hope it is more clear now.

  4. MAN!! THANKS!!

    I suffered much when wanted to right align numbers in the listitems, I used EnrichedText, but it’s much more work to add.
    And what did I just see in your article:

    SetElementText________Alignment

    YESSS!
    See, even if you think you are a Bada expert, you can always learn
    :wink:

Leave a Comment


*


NOTE - You can use these HTML tags and attributes:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>