×
Namespaces

Variants
Actions

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

From Nokia Developer Wiki
Jump to: navigation, search
Article Metadata

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

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

Статья
Автор: A.A.M. (A.A.M.)
Последнее редактирование: hamishwillee (09 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 9 December 2011, at 02:48.
94 page views in the last 30 days.
×