Welcome!

Welcome to the official BlackBerry Support Community Forums.

This is your resource to discuss support topics with your peers, and learn from each other.

inside custom component

Native Development

Reply
Developer
Posts: 121
Registered: ‎02-08-2013
My Device: 9900
My Carrier: verizon
Accepted Solution

Refreshing ListView

Hi,

 

I am working with ListView to show a list of contacts, some online and some offline. I want the contacts who are online to appear at the top of my list and they might come online later so they will need to be put to the top of the list if they do come online later.

 

I have a working solution but it is not satisfactory as it requires a full refresh of my listview and there can be times when a lot of contacts appear online at once so it looks a bit untidy when there is muliple refreshes happeing one after the other.

 

Is it possible to move an item from one place in the list to the top of list when required without having to do a full refresh?

 

Currently what I have done to acheive a workable solution is just remove the contact from a QList variable - entireList and then append or insert it again (depending on if the contact is online or not) .

 

I then clear my datamodel and append my entireList data back again into the datamodel and emit itemsChanged(bb::cascades:Smiley Very HappyataModelChangeType::AddRemove) from my datamodel.

 

This does the job but I am hoping there is a tidier way to do this.

 

Anybody please with a bit of advice?

Developer
Posts: 6,152
Registered: ‎07-05-2012
My Device: Playbook, Dev Alpha C, Z10 LE, Z30
My Carrier: Orange

Re: Refreshing ListView

You will have to implement your own DataModel with IndexMapper to sort, add, delete asynchronously...

 

http://developer.blackberry.com/native/reference/cascades/bb__cascades__datamodel.html

 

http://developer.blackberry.com/native/reference/cascades/bb__cascades__datamodel__indexmapper.html

 

 

 


If you've been helped click on Like Button, if you've been saved buy the app. Smiley Happy

Developer of stokLocker, Sympatico and Super Sentences.
Developer
Posts: 6,152
Registered: ‎07-05-2012
My Device: Playbook, Dev Alpha C, Z10 LE, Z30
My Carrier: Orange

Re: Refreshing ListView

Take a look at the AsynchronousDataLoading example for how to implement, sadly it's way to simple to be plug and play and so will need a little work on the IndexMapper side with pointers to fit it to your project...

 

http://developer.blackberry.com/native/documentation/cascades/ui/lists/asynch_data.html

 

If you are fairly confident with pointers and binary searchs it should be fairly easy for you.


If you've been helped click on Like Button, if you've been saved buy the app. Smiley Happy

Developer of stokLocker, Sympatico and Super Sentences.
Developer
Posts: 285
Registered: ‎08-06-2010
My Device: Z10

Re: Refreshing ListView

I would use an ArrayDataModel, then use swap, replace, insert and remove as necessary. 



Follow me on twitter @RileyGB - https://twitter.com/RileyGB
View my BB10 OpenSource projects - https://github.com/RileyGB/BlackBerry10-Samples
Developer
Posts: 6,152
Registered: ‎07-05-2012
My Device: Playbook, Dev Alpha C, Z10 LE, Z30
My Carrier: Orange

Re: Refreshing ListView

@RileyGB, I don't think the problem is one of which data structure to use this could be the one he is already using and would still result in the ListView items being called for an update AFAIK.

 

Using an IndexMapper no matter what the underlying data storage method is allows a ListView to manipulate the way the indexPath is represented and therefore allows the list to call itemUpdated only affecting the minimum of ListItems.


If you've been helped click on Like Button, if you've been saved buy the app. Smiley Happy

Developer of stokLocker, Sympatico and Super Sentences.
Developer
Posts: 121
Registered: ‎02-08-2013
My Device: 9900
My Carrier: verizon

Re: Refreshing ListView

Thank you both for replying,

 

I am struggling to get my head around IndexMapper and there isn't much else I can refer to other than 1 page in the docs to learn more. My confusion with it lies in when I manually emit itemsChanged with my custom IndexMapper, basically I don't know what else to do. I have it compiling with the following code which I'm hoping if I post will make it easier for you to help me.

 

foreach(ChatUser* u, outerChatModel->m_listData[0].second)
	{
		if(u->jid == message.from())
		{
			if(message.type() == 2)
			{

		u->setOnline(false);
		entireList.removeOne(u);
		entireList.append(u);

		break;
			}
			else
			{
				u->setOnline(true);
				entireList.removeOne(u);
				entireList.insert(0, u);
				break;
			}
			i++;
		}
	}

outerChatModel->m_listData.clear();
outerChatModel->m_listData.append(qMakePair(QString(" "), entireList));
outerChatModel->refreshNew();



/////


//Here is my new refresh function 

void OuterDataModel::refreshNew()
{
	QSharedPointer<MyIndexMapper> obj = QSharedPointer<MyIndexMapper>(new MyIndexMapper);
	emit itemsChanged(bb::cascades::DataModelChangeType::AddRemove, obj);
	
}

//MYIndexMapper class

 MyIndexMapper::MyIndexMapper()
 {

 }
bool MyIndexMapper::newIndexPath(QVariantList *pNewIndexPath,
        int *pReplacementIndex, const QVariantList &oldIndexPath) const {
qDebug() << "indexmapper newindexpath";
    // Unaffected indices
    if (oldIndexPath[0].toInt() < mIndex) {
        (*pNewIndexPath).append(oldIndexPath);
        return true;

    // Deleted indices
    } else if (mDeleted && oldIndexPath[0].toInt() <= mIndex + mCount) {
        *pReplacementIndex = mIndex;
        return false;

    // Indices after a deletion or addition
    } else {
        if (mDeleted)
            (*pNewIndexPath).append(oldIndexPath[0].toInt() - mCount);
        else
            (*pNewIndexPath).append(oldIndexPath[0].toInt() + mCount);
        return true;
    }
}

 

 

How do I link it all together properly?

Developer
Posts: 6,152
Registered: ‎07-05-2012
My Device: Playbook, Dev Alpha C, Z10 LE, Z30
My Carrier: Orange

Re: Refreshing ListView

As I said the code is woefully lacking as a useful piece of code for adding data the example code just appends to the end and updates the pointer accordingly. You will need to rewrite the pointer code to handle sorting and insertion within the datamodel.


If you've been helped click on Like Button, if you've been saved buy the app. Smiley Happy

Developer of stokLocker, Sympatico and Super Sentences.
Developer
Posts: 121
Registered: ‎02-08-2013
My Device: 9900
My Carrier: verizon

Re: Refreshing ListView

I'm struggling to understand - the indexmappers newIndexPath function is called automatically with variables which include old and new indexpath, this function is called when i emit itemschanged with the indexmapper object, how do i tell it all which is the old and new index path?

 

Thank you.

Developer
Posts: 121
Registered: ‎02-08-2013
My Device: 9900
My Carrier: verizon

Re: Refreshing ListView

Sorry, I was reading the html page for asynchronousdataloading project rather than downloading the full project, I should be ok from here now I have seen the actual code.

 

Thank you again.