Namespaces

Variants
Actions

Please note that as of October 24, 2014, the Nokia Developer Wiki will no longer be accepting user contributions, including new entries, edits and comments, as we begin transitioning to our new home, in the Windows Phone Development Wiki. We plan to move over the majority of the existing entries over the next few weeks. Thanks for all your past and future contributions.

Пример работы с Adaptive Search - S60 Touch UI

From Wiki
Jump to: navigation, search
Article Metadata

Пример кода
Исходный файл: AdaptiveSearch.zip

Совместимость
Платформа(ы):
S60 5th Edition

Статья
Автор: A.A.M. (A.A.M.)
Последнее редактирование: hamishwillee (08 Dec 2011)

Статья базируется на материалах англоязычной части Wiki, все они перечислены в разделе ссылки.

Contents

Обзор

Адаптивный поиск - это совмещение возможностей сенсорного управления с существовавшим в предыдущих изданиях S60 интерфейсом CAknSearchField API. В данной статье мы рассмотрим пример работы с этим API.

Что такое адаптивный поиск

  • При использовании адаптивного поиска, искомые символы изначально выводятся в виде сетки. С выбором каждого следующего символа, число оставшихся уменьшается в зависимости от количества совпадений, список фильтруется, сужая тем самым число возможных вариантов для следующего выбора и, соответственно, уменьшая общее время поиска.
  • Адаптивный поиск интегрируется с CAknSearchField API.
  • Обычно адаптивный поиск используется совместно с компонентом списка (List box).
  • Системное приложение Контакты - это лучший пример наглядного использования функций адаптивного поиска в устройствах на S60 5-го издания.

MainFiltered

Создание списка

  • Прежде всего мы должны создать ресурсы для списка (listbox), который будет совмещен с CAknSearchField API и будет использован для демонстрации возможностей адаптивного поиска.
RESOURCE LISTBOX r_list_box
{
flags = EAknListBoxSelectionList;
array_id= r_list_box_item_array;
}
 
RESOURCE ARRAY r_list_box_item_array
{
items =
{
LBUF { txt = "\tAlbert Eienstein\t";},
LBUF { txt = "\tAlbert Makinstosh\t";},
LBUF { txt = "\tVikram Sarabhai\t";},
LBUF { txt = "\tSarabhai Anand\t";}
};
}


Реализация функционала адаптивного поиска

AdaptiveSearchAppView.h

  • Унаследуем класс от MAdaptiveSearchTextObserver и реализуем его виртуальную функцию AdaptiveSearchTextChanged() для получения символов, выбранных пользователем в сетке адаптивного поиска.
  • Объявляем объект CAknSingleStyleListBox членом класса и используем его для отображения массива строк, хранящегося в ресурсах
  • Объявляем объект CAknSearchField членом класса и интегрируем его со списком для реализации адаптивного поиска.
...
...
#include <aknlists.h> // For List Box
#include <barsread.h> //For Resource Reader
#include <aknsfld.h> // For SearchField
...
 
// CLASS DECLARATION
class CAdaptiveSearchAppView : public CCoeControl, public MAdaptiveSearchTextObserver
{
....
....
//For listbox
void CreateListBoxL();
TInt CountComponentControls() const;
CCoeControl* ComponentControl(TInt aIndex) const;
TKeyResponse OfferKeyEventL(const TKeyEvent &aKeyEvent, TEventCode aType);
 
//From MAdaptiveSearchTextObserver
virtual void AdaptiveSearchTextChanged (CAknSearchField *aSearchField);
 
private:
CAknSingleStyleListBox* iListBox;
CAknSearchField* iSearchField;
.....
};

AdaptiveSearchAppView.cpp

// -----------------------------------------------------------------------------
// CAdaptiveSearchAppView::ConstructL()
// Symbian 2nd phase constructor can leave.
// -----------------------------------------------------------------------------
//
void CAdaptiveSearchAppView::ConstructL(const TRect& aRect)
{
// Создаем окно
CreateWindowL();
 
// Создаем списк (listbox) и заполняем его строками из ресурсов
CreateListBoxL();
 
// Устанавливаем размеры окна
SetRect(aRect);
 
// Активизируем окно
ActivateL();
}
  • Создаем список и заполняем его
  • Указываем данный класс ("this") в качестве наблюдателя за событиями адаптивного поиска
void CAdaptiveSearchAppView::CreateListBoxL()
{
iListBox= new (ELeave) CAknSingleStyleListBox();
iListBox->SetContainerWindowL(*this);
 
TResourceReader rr;
iCoeEnv->CreateResourceReaderLC(rr, R_LIST_BOX);
iListBox->ConstructFromResourceL(rr);
iListBox->CreateScrollBarFrameL(ETrue);
iListBox->ScrollBarFrame()->SetScrollBarVisibilityL( CEikScrollBarFrame::EOn, CEikScrollBarFrame::EAuto );
 
CleanupStack::PopAndDestroy();//rr
 
// Создаем поле для поиска (SearchField) и включаем поддержку адаптивного поиска
iSearchField = CAknSearchField::NewL(*this, CAknSearchField::EAdaptive, NULL, 20);
 
STATIC_CAST(CAknFilteredTextListBoxModel*, iListBox->Model())->CreateFilterL(iListBox,iSearchField);
STATIC_CAST(CAknFilteredTextListBoxModel*, iListBox->Model())->Filter()->HandleOfferkeyEventL();
 
// Добавляем данный класс ("this") в качестве наблюдателя за событиями адаптивного поиска
iSearchField->AddAdaptiveSearchTextObserverL(this);
}
  • Реализуем функцию AdaptiveSearchTextChanged для того, чтобы получить текст, введенный в поле адаптивного поиска.
void CAdaptiveSearchAppView::AdaptiveSearchTextChanged(CAknSearchField* aSearchFiled)
{
TBuf<50> buffer;
aSearchFiled->GetSearchText(buffer);
 
// добавлено для предотвращения исчезновения поля поиска после закрытия сетки адаптивного поиска
SizeChanged();
DrawNow();
}
  • Корректно обрабатываем случаи изменения размеров отображения
// -----------------------------------------------------------------------------
// CAdaptiveSearchAppView::SizeChanged()
// Вызывается системой в случае изменения размеров отображения.
// -----------------------------------------------------------------------------
//
void CAdaptiveSearchAppView::SizeChanged()
{
if (iListBox)
{
if (iSearchField)
{
CAknColumnListBox* aknListBox = STATIC_CAST(CAknColumnListBox*, iListBox);
AknFind::HandleFixedFindSizeChanged(this, aknListBox, iSearchField);
 
}
else
{
iListBox->SetRect(Rect()); // Устанавливаем прямоугольную область, занимаемую объектом iListBox.
}
}
}
  • Возвращаем число компонентов, содержащихся в контейнере, у нас их два - Listbox и SearchField
TInt CAdaptiveSearchAppView::CountComponentControls() const
{
return 2; // возвращаем число компонентов в контейнере
}
 
CCoeControl* CAdaptiveSearchAppView::ComponentControl(TInt aIndex) const
{
switch ( aIndex )
{
case 0:
return iListBox;
break;
case 1:
return iSearchField;
break;
default:
return NULL;
}
}
  • Пример обработки событий от указателя в <tt>HandlePointerEventL:
// -----------------------------------------------------------------------------
// CAdaptiveSearchAppView::HandlePointerEventL()
// Вызывается фреймворком при получении событий от указателя (стилуса)
// -----------------------------------------------------------------------------
//
void CAdaptiveSearchAppView::HandlePointerEventL(
const TPointerEvent& aPointerEvent)
{
// Передаем событие от указателя в обработчик объекта iSearchField
iSearchField->HandlePointerEventL(aPointerEvent);
 
// Передаем событие базовому классу
CCoeControl::HandlePointerEventL(aPointerEvent);
}
  • Обработка событий от клавиатуры происходит в функции OfferKeyEventL()
TKeyResponse CAdaptiveSearchAppView::OfferKeyEventL(const TKeyEvent &aKeyEvent, TEventCode aType)
{
TKeyResponse ret = EKeyWasNotConsumed;
switch (aKeyEvent.iCode)
{
case EKeyDevice3:
break;
default:
if(iListBox)
{
if ( iSearchField )
{
TBool needRefresh( EFalse );
 
// Обрабатываем нажатие, фильтруем список
if ( AknFind::HandleFindOfferKeyEventL( aKeyEvent, aType, this,
iListBox, iSearchField,
EFalse,
needRefresh ) ==EKeyWasConsumed )
{
if ( needRefresh )
{
SizeChanged();
DrawNow();
}
 
return EKeyWasConsumed;
}
}
 
ret = iListBox->OfferKeyEventL(aKeyEvent, aType);
}
return ret;
}
}


  • Не забудьте удалить объект iSearchField и iListBox в деструкторе класса.
// -----------------------------------------------------------------------------
// CAdaptiveSearchAppView::~CAdaptiveSearchAppView()
// Деструктор.
// -----------------------------------------------------------------------------
//
CAdaptiveSearchAppView::~CAdaptiveSearchAppView()
{
.....
.....
if(iSearchField)
{
iSearchField->RemoveAdaptiveSearchTextObserver(this);
delete iSearchField;
iSearchField = NULL;
}
if(iListBox)
{
delete iListBox;
iListBox = NULL;
}
}
  • Для получения событий в OfferKeyEventL необходимо при создании отображения в функции AppUi::ConstructL() поместить отображение в стэк.
  • В деструкторе необходимо удалить из стэка отображение, помещенное туда ранее.
// -----------------------------------------------------------------------------
// CAdaptiveSearchAppUi::ConstructL()
// Symbian 2nd phase constructor can leave.
// -----------------------------------------------------------------------------
//
void CAdaptiveSearchAppUi::ConstructL()
{
// Initialise app UI with standard value.
BaseConstructL(CAknAppUi::EAknEnableSkin);
 
// Create view object
iAppView = CAdaptiveSearchAppView::NewL(ClientRect());
 
AddToStackL( iAppView ); // Добавляем отображение в стэк
....
....
....
}
 
 
// -----------------------------------------------------------------------------
// CAdaptiveSearchAppUi::~CAdaptiveSearchAppUi()
// Деструктор.
// -----------------------------------------------------------------------------
//
CAdaptiveSearchAppUi::~CAdaptiveSearchAppUi()
{
if (iAppView)
{
RemoveFromStack(iAppView); // Удаляем отображение из стэка
delete iAppView;
iAppView = NULL;
}
}

Полезные функции

CAknSearchField

  • TSearchFieldStyle::EAdaptiveSearch
  • GetSearchText()
  • SetSearchTextL()
  • HandlePointerEventL()
  • ShowAdaptiveSearchGrid()
  • SetAdaptiveGridChars()

MAdaptiveSearchTextObserver

  • AdaptiveSearchTextChanged()

Ключевые моменты

Заголовочные файлы

  • #include <aknsfld.h>

Классы

  • CAknSearchField
  • MAdaptiveSearchTextObserver

Библиотеки

  • avkon.lib

Демонстрационное приложение

Связанные ссылки



При подготовке статьи использованы следующие материалы:

Источники дополнительной информации

This page was last modified on 8 December 2011, at 23:48.
299 page views in the last 30 days.

Was this page helpful?

Your feedback about this content is important. Let us know what you think.

 

Thank you!

We appreciate your feedback.

×