Question

I need to implement collapsible list with dynamic data in BB 10. For this i am using FilteredDataModel example provided in Github. Currently all data is hard coded in example but it is required to fill data dynamically in ListView.

Searched a lot but didn't get anything.

Was it helpful?

Solution

I took a look at that example, and the data that's hardcoded is in the VegetablesDataModel::data function. That's the data you want to replace with your dynamic data.

First you need to think of how you are going to store your data. The list has headers and each header has a sublist. One way to represent a header and the sublist of items is with a

QPair<QString, QList<QString> >

QPair::first will be your header, and QPair::second will be the list of subitems.

To make it easier to type you can use a typedef

typedef QPair<QString, QList<QString> > SubList;

Then to represent all the data in your ListView you need a list of the SubList struct above

QList<SubList>

Next, we want to replace how the data is returned by VegetablesDataModel. Add a new member variable to VegetablesDataModel for the above items list

QList<SubList> m_listData.

You now just need to replace the contents of the VegetablesDataModel::data and VegetablesDataModel::childCount functions.

QVariant VegetablesDataModel::data(const QVariantList& indexPath)
{
    QString value;

    if (indexPath.size() == 1) { // Header requested
        int header = indexPath[0].toInt();
        return m_listData[header].first; // Return the header name
    }

    if (indexPath.size() == 2) { // 2nd-level item requested
        const int header = indexPath[0].toInt();
        const int childItem = indexPath[1].toInt();
        return m_listData[header].second[childItem]; // Return the matching sublist item.

    }

    qDebug() << "Data for " << indexPath << " is " << value;

    return QVariant(value);
}

This takes care of the data, but we still need to tell the listView how many elements we have.

int VegetablesDataModel::childCount(const QVariantList& indexPath)
{

    const int level = indexPath.size();

    if (level == 0) { // The number of top-level items is requested
        return m_listData.length();
    }

    if (level == 1) { // The number of child items for a header is requested
        const int header = indexPath[0].toInt();
        return m_listData[header].second.length();
    }

    // The number of child items for 2nd level items is requested -> always 0
    return 0;
}

You should be good with everything else remaining the same. All that remains is for you to fill in m_listData with the data you want. Please mind any spelling mistakes since I don't have a chance to test my code but the logic should be there.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top