Expandable views

An ExpandableView is a control that's used to display a portion of its contents in a fixed height, and the control can be expanded to display its full contents.


Screen showing the More and Collapse buttons of an ExpandableView.

When the contents of an ExpandableView exceed the maximum height specified for the control, a More button is displayed. Users can tap the More button to display the full height and contents of the expandable view.

The contents of an ExpandableView can include other controls. Usually, your content is a Container that you then fill with content. A common use for expandable views is to hide information that, while nice to know, is not critical for the user.

When you add a control to an ExpandableView, the control is added as the first child in the ExpandableView. If an ExpandableView is removed from the scene, all of its children are removed as well.

Sizing

Controlling the view

An ExpandableView supports a variety of modes that you can use to control the expand and collapse behavior of the control. Expand and collapse modes can be set independently, allowing full control over an expandable view.

Expand modes

An ExpandableView has the following expand modes:

  • The Default mode sets the expand mode automatically based on the content of the ExpandableView.

  • The AutoExpand mode expands the control when the user interacts with any visible part of the content in the ExpandableView.

  • The UserExpand mode expands the control when the user taps the More button.

Collapse modes

An ExpandableView has the following collapse modes:

  • The Default mode automatically sets the collapse mode based on the content of the ExpandableView.

  • The None mode prevents the user from collapsing the control.

  • The UserCollapse mode collapses the control when the user taps the Collapse button.

Expandable view example

The following example uses a pair of SegmentedControl controls to demonstrate the different expand and collapse modes available for an ExpandableView.

The first SegmentedControl has three options: Default, Auto expand, and User expand. These options are used to control the expand modes.

The second SegmentedControl also has three options: Default, None, and User collapse. These options are used to control the collapse modes.

When the app starts, both the expand and collapse modes are set to Default.

Animation showing the expand and collapse modes of an ExpandableView control.

main.qml

import bb.cascades 1.3

Page {
    Container {
        layout: StackLayout {
            orientation: LayoutOrientation.TopToBottom
        }
        SegmentedControl {
            id: expand
            Option {
                text: "Default"
                value: 0
            }
            Option {
                text: "Auto expand"
                value: 1
            }
            Option {
                text: "User expand"
                value: 2
            }
            onSelectedOptionChanged: {
                myExpandable.expandMode = selectedOption.value
            }
        }
        ExpandableView {
            id: myExpandable
            maxCollapsedHeight: 175
            horizontalAlignment: HorizontalAlignment.Center
            Container {
                layout: StackLayout {
                    orientation: LayoutOrientation.TopToBottom
                }
                minHeight: 350
                minWidth: 700
                horizontalAlignment: HorizontalAlignment.Fill
                Container {
                    minHeight: 175
                    horizontalAlignment: HorizontalAlignment.Fill
                    background: Color.Red
                }
                Container {
                    minHeight: 175
                    horizontalAlignment: HorizontalAlignment.Fill
                    background: Color.Green
                }
            }

        }
        SegmentedControl {
            id: collapse
            Option {
                text: "Default"
                value: 0
            }
            Option {
                text: "None"
                value: 1
            }
            Option {
                text: "User collapse"
                value: 2
            }
            onSelectedOptionChanged: {
                myExpandable.collapseMode = selectedOption.value
            }
        }
    }
}

ExpandableViewRecipe.h

#ifndef EXPANDABLEVIEWRECIPE_H_
#define EXPANDABLEVIEWRECIPE_H_

#include <bb/cascades/Page>
#include <bb/cascades/Container>
#include <QObject>
#include <bb/cascades/SegmentedControl>
#include <bb/cascades/ExpandableView>
#include <bb/cascades/Application>

using namespace bb::cascades;

class ExpandableViewRecipe : public QObject
{
    Q_OBJECT

public:
    ExpandableViewRecipe(bb::cascades::Application *app);
    virtual ~ExpandableViewRecipe() {}

    public slots:

    void expandOptionChanged(bb::cascades::Option *selectedOption);
    void collapseOptionChanged(bb::cascades::Option *selectedOption);

    private:

        Container *mRoot;
        Container *mParent;
        Container *mRedContainer;
        Container *mGreenContainer;

        SegmentedControl *mExpandControl;
        SegmentedControl *mCollapseControl;
        ExpandableView *mExpandableView;


};

#endif /* EXPANDABLEVIEWRECIPE_H_ */

ExpandableViewRecipe.cpp

#include "ExpandableViewRecipe.h"

#include <bb/cascades/Application>
#include <bb/cascades/Container>
#include <bb/cascades/StackLayout>
#include <bb/cascades/Page>
#include <bb/cascades/TitleBar>
#include <bb/cascades/SegmentedControl>
#include <bb/cascades/ExpandableView>
#include <bb/cascades/ExpandMode>
#include <bb/cascades/CollapseMode>
#include <bb/cascades/Color>
#include <bb/cascades/Control>
#include <bb/cascades/HorizontalAlignment>


using namespace bb::cascades;

ExpandableViewRecipe::ExpandableViewRecipe(bb::cascades::Application *app)
: QObject(app)
{
    // Create a Container and set the layout
    Page *page = new Page();

    mRoot = Container::create()
                .layout(new StackLayout())
                .top(20.0f);

    TitleBar *tbar = TitleBar::create().title("ExpandableView");
    page->setTitleBar(tbar);

    // Create a SegmentedControl with
    // three options corresponding to the different
    // expand modes available
    mExpandControl = SegmentedControl::create()
            .add(bb::cascades::Option::create()
                .text("Default")
                .value(0)
                .selected(true))
            .add(bb::cascades::Option::create()
                .text("Auto expand")
                .value(1))
            .add(bb::cascades::Option::create()
                .text("User expand")
                .value(2));

    // Create a SegmentedControl with
    // three options corresponding to the different
    // collapse modes available
    mCollapseControl = SegmentedControl::create()
            .add(bb::cascades::Option::create()
                .text("Default")
                .value(0)
                .selected(true))
            .add(bb::cascades::Option::create()
                .text("None")
                .value(1))
            .add(bb::cascades::Option::create()
                .text("User collapse")
                .value(2));

    // If any Q_ASSERT statement(s) indicate that the slot failed to connect to
    // the signal, make sure you know exactly why this has happened. This is not
    // normal, and will cause your app to stop working
    bool connectResult;

    // Since the variable is not used in the app, this is added to avoid a
    // compiler warning
    Q_UNUSED(connectResult);

    // Connect the selectedOptionChanged() signal to
    // the expandOptionChanged() slot
    connectResult = connect(mExpandControl,
                      SIGNAL(selectedOptionChanged(bb::cascades::Option*)),
                      this,
                      SLOT(expandOptionChanged(bb::cascades::Option*)));

    // Connect the selectedOptionChanged() signal to
    // the collapseOptionChanged() slot
    connectResult = connect(mCollapseControl,
                      SIGNAL(selectedOptionChanged(bb::cascades::Option*)),
                      this,
                      SLOT(collapseOptionChanged(bb::cascades::Option*)));

    // This is only available in Debug builds
    Q_ASSERT(connectResult);

    // Create the expandable view and set the maximum
    // collapsed height
    mExpandableView = ExpandableView::create()
            .maxCollapsedHeight(175)
            .horizontal(HorizontalAlignment::Center);

    // Create the content for your expandable view;
    // in this case, a series of containers
    mParent = Container::create()
            .layout(new StackLayout())
            .horizontal(HorizontalAlignment::Fill);

    mParent->setMinHeight(350);
    mParent->setMinWidth(800);

    mRedContainer = Container::create()
        .horizontal(HorizontalAlignment::Fill)
        .background(Color::Red);

    mRedContainer->setMinHeight(175);

    mGreenContainer = Container::create()
        .horizontal(HorizontalAlignment::Fill)
        .background(Color::Green);

    mGreenContainer->setMinHeight(175);

    // Add your components to the scene
    mRoot->add(mExpandControl);
    mRoot->add(mExpandableView);
    mRoot->add(mCollapseControl);
    mExpandableView->setContent(mParent);
    mParent->add(mRedContainer);
    mParent->add(mGreenContainer);
    page->setContent(mRoot);
    app->setScene(page);

}

// Create the expandOptionChanged() slot
// to capture the selectedOptionChanged() signal emitted
// by the SegmentedControl
void ExpandableViewRecipe::expandOptionChanged
    (bb::cascades::Option *selectedOption)
{
    // Use a switch case to change the expand mode based
    // on the selected option.
    switch (selectedOption->value().toInt()) {
    case 0:
        mExpandableView->setExpandMode(ExpandMode::Default);
        break;
    case 1:
        mExpandableView->setExpandMode(ExpandMode::AutoExpand);
        break;
    case 2:
        mExpandableView->setExpandMode(ExpandMode::UserExpand);
        break;
    }
}

// Create the collapseOptionChanged() slot
// to capture the selectedOptionChanged() signal emitted
// by the SegmentedControl
void ExpandableViewRecipe::collapseOptionChanged
    (bb::cascades::Option *selectedOption)
{
    // Use a switch case to change the expand mode based
    // on the selected option.
    switch (selectedOption->value().toInt()) {
    case 0:
        mExpandableView->setCollapseMode(CollapseMode::Default);
        break;
    case 1:
        mExpandableView->setCollapseMode(CollapseMode::None);
        break;
    case 2:
        mExpandableView->setCollapseMode(CollapseMode::UserCollapse);
        break;
    }
}

main.cpp

#include "ExpandableViewRecipe.h"

#include <bb/cascades/Application>
#include <Qt/qdeclarativedebug.h>

using namespace bb::cascades;

Q_DECL_EXPORT int main(int argc, char **argv)
{
    Application app(argc, argv);

    new ExpandableViewRecipe(&app);

    return Application::exec();
}

Last modified: 2014-05-14



Got questions about leaving a comment? Get answers from our Disqus FAQ.

comments powered by Disqus