Previous: http://www.bkjia.com/kf/201208/146799.html
When a direction key or traceball is used to move the UI Focus, there are some UI controls, such as Listview, which can contain sub-UIS (such as list items and Cell items) in the GridView. After the Focus is moved to this type of UI control, you can use the direction keys or traceball to move the selected list items or Cell items within the Listview or GridView.
This example introduces a Custom UI control InternalSelectionView. For details about how to customize the UI control, see Android ApiDemos example resolution (109): Views-> Custom
InternalSelectionView can display a list of rectangles. The width of the rectangle is the width of the View. You can customize the number of rows in the list. The height of the rectangle is the height of the View and is equally divided into the number of rows in the list. The default number of rows is 5.
Its onDraw shows the rectangle and the selected rectangle is highlighted in red. Otherwise, it is displayed in black.
[Java]
@ Override
Protected void onDraw (Canvas canvas ){
...
// Draw forground rect
If (I = mSelectedRow & hasFocus ()){
MPainter. setColor (Color. RED );
MPainter. setAlpha (0xF0 );
MTextPaint. setAlpha (0xFF );
} Else {
MPainter. setColor (Color. GREEN );
MPainter. setAlpha (0x40 );
MTextPaint. setAlpha (0xF0 );
}
...
}
@ Override
Protected void onDraw (Canvas canvas ){
...
// Draw forground rect
If (I = mSelectedRow & hasFocus ()){
MPainter. setColor (Color. RED );
MPainter. setAlpha (0xF0 );
MTextPaint. setAlpha (0xFF );
} Else {
MPainter. setColor (Color. GREEN );
MPainter. setAlpha (0x40 );
MTextPaint. setAlpha (0xF0 );
}
...
}
Note: The black background rectangle is not clear. Here it is changed to green.
The methods related to the UI Focus are as follows:
1. process the arrow keys "up", "down", and InternalSelectionView to display a list of vertical rectangles. You can use the "up" and "down" keys to move the selected rectangle of InternalSelectionView.
[Java
@ Override
Public boolean onKeyDown (int keyCode, KeyEvent event ){
Switch (event. getKeyCode ()){
Case KeyEvent. KEYCODE_DPAD_UP:
If (mSelectedRow> 0 ){
MSelectedRow --;
Invalidate ();
EnsureRectVisible ();
Return true;
}
Break;
Case KeyEvent. KEYCODE_DPAD_DOWN:
If (mSelectedRow <(mNumRows-1 )){
MSelectedRow ++;
Invalidate ();
EnsureRectVisible ();
Return true;
}
Break;
}
Return false;
}
@ Override
Public boolean onKeyDown (int keyCode, KeyEvent event ){
Switch (event. getKeyCode ()){
Case KeyEvent. KEYCODE_DPAD_UP:
If (mSelectedRow> 0 ){
MSelectedRow --;
Invalidate ();
EnsureRectVisible ();
Return true;
}
Break;
Case KeyEvent. KEYCODE_DPAD_DOWN:
If (mSelectedRow <(mNumRows-1 )){
MSelectedRow ++;
Invalidate ();
EnsureRectVisible ();
Return true;
}
Break;
}
Return false;
}
2. Reload the getFocusedRect method to set the size of the rectangle in the selected area. By default, getFocusedRect and getDrawingRect are the same size as those in the View. When you move the UI focus from the current control to the next UI control, the Android system will find the next UI control closest to this Focused Rect Based on the Focused Rect position of the UI Focus movement. The size of the rectangle in the selected area should be set correctly for the View (such as the example or ListView) getFocusedRect that supports internal selection:
[Java]
@ Override
Public void getFocusedRect (Rect r ){
GetRectForRow (r, mSelectedRow );
}
Public void getRectForRow (Rect rect, int row ){
Final int rowHeight = getRowHeight ();
Final int top = getPaddingTop () + row * rowHeight;
Rect. set (getPaddingLeft (),
Top,
GetWidth ()-getPaddingRight (),
Top + rowHeight );
}
@ Override
Public void getFocusedRect (Rect r ){
GetRectForRow (r, mSelectedRow );
}
Public void getRectForRow (Rect rect, int row ){
Final int rowHeight = getRowHeight ();
Final int top = getPaddingTop () + row * rowHeight;
Rect. set (getPaddingLeft (),
Top,
GetWidth ()-getPaddingRight (),
Top + rowHeight );
}
In this example, the Focused Rect is set to the size of the selected rectangle.
3. Reload onFocusChanged. This method is called when the current UI View Focus status changes. The status is Focus and Focus is lost. Remember to call the method of the base class to ensure the standard Focus moving behavior during overload.
[Java]
@ Override
Protected void onFocusChanged (boolean focused,
Int direction,
Rect previuslyfocusedrect ){
Super. onFocusChanged (focused, direction,
Previuslyfocusedrect );
If (focused ){
Switch (direction ){
Case View. FOCUS_DOWN:
MSelectedRow = 0;
Break;
Case View. FOCUS_UP:
MSelectedRow = mNumRows-1;
Break;
Case View. FOCUS_LEFT: // fall through
Case View. FOCUS_RIGHT:
// Set the row that is closest to the rect
If (previuslyfocusedrect! = Null ){
Int y = previuslyfocusedrect. top
+ (Previuslyfocusedrect. height ()/2 );
Int yPerRow = getHeight ()/mNumRows;
MSelectedRow = y/yPerRow;
} Else {
MSelectedRow = 0;
}
Break;
Default:
// Can't gleam any useful information about what internal
// Selection shocould be...
Return;
}
Invalidate ();
}
}
@ Override
Protected void onFocusChanged (boolean focused,
Int direction,
Rect previuslyfocusedrect ){
Super. onFocusChanged (focused, direction,
Previuslyfocusedrect );
If (focused ){
Switch (direction ){
Case View. FOCUS_DOWN:
MSelectedRow = 0;
Break;
Case View. FOCUS_UP:
MSelectedRow = mNumRows-1;
Break;
Case View. FOCUS_LEFT: // fall through
Case View. FOCUS_RIGHT:
// Set the row that is closest to the rect
If (previuslyfocusedrect! = Null ){
Int y = previuslyfocusedrect. top
+ (Previuslyfocusedrect. height ()/2 );
Int yPerRow = getHeight ()/mNumRows;
MSelectedRow = y/yPerRow;
} Else {
MSelectedRow = 0;
}
Break;
Default:
// Can't gleam any useful information about what internal
// Selection shocould be...
Return;
}
Invalidate ();
}
}
Function parameters:
If the value of focused is true, the View obtains the focus; otherwise, the focus is lost.
Direction: the direction in which the current focus is moved. It can be up, down, left, right, forward, or backward.
Previuslyfocusedrect: if it is not null, it indicates the size of the rectangle area of the previous UI control (View whole.
In this example, only FOCUS_LEFT and FOCUS_RIGHT are executed. InternalSelectionFocus displays three examples of InternalSelectionView from left to right. The "Left" and "right" keys can be left, center, and right to move the UI focus back and forth. Click "up" and "down" to select a rectangle from the upper and lower of an InternalSelectionView object that obtains the UI focus.
When the left and right buttons move the UI focus, which rectangle in the next InternalSelectionView that gets the focus will be selected:
[Java]
If (previuslyfocusedrect! = Null ){
Int y = previuslyfocusedrect. top
+ (Previuslyfocusedrect. height ()/2 );
Int yPerRow = getHeight ()/mNumRows;
MSelectedRow = y/yPerRow;
}
If (previuslyfocusedrect! = Null ){
Int y = previuslyfocusedrect. top
+ (Previuslyfocusedrect. height ()/2 );
Int yPerRow = getHeight ()/mNumRows;
MSelectedRow = y/yPerRow;
}
Because the top and bottom of the three views are aligned, that is, the top and bottom of previuslyfocusedrect are the same for the selected View, the calculated mSelectuedRow is the same, and the corresponding example is 3. therefore, when "Left" and "right" are used to move the UI focus, the next InternalSelectionView that obtains the focus always selects the rectangle with the serial number 3.
Author: mapdigit