Android ApiDemos樣本解析(118):Views->Focus->4. Int

來源:互聯網
上載者:User

上一篇:http://www.bkjia.com/kf/201208/146799.html


使用方向鍵或是traceball 移動UI焦點時,有一些UI控制項,如Listview ,GridView 內部可以帶有子UI (如清單項目,Cell項),當Focus移動到這類UI控制項後,再使用使用方向鍵或是traceball 可以在Listview 或是 GridView 內部移動當前選中的清單項目或是Cell項等。

本例介紹了一個自訂UI控制項InternalSelectionView ,自訂UI控制項的步驟可以參見Android ApiDemos樣本解析(109):Views->Custom

InternalSelectionView 可以顯示一個矩形列表,矩形的寬度為View的寬度,允許自訂欄表的行數,矩形的高度為View的高度平分為列表的行數。預設行數為5.

其onDraw 顯示 矩形,並以高亮(紅色)顯示當前選中的矩形。否則以黑色顯示.

[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);
}
...
}


註:黑色背景矩形顯示看不大清楚,這裡改為綠色。

和UI焦點(Focus)相關的幾個方法如下:

1. 處理方向鍵“上”,“下” ,InternalSelectionView 顯示了一個縱向矩形列表,可以使用“上”,“下”鍵移動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.  重載getFocusedRect 方法,設定被選中地區矩形框大小, 預設情況(對應沒有內部選擇功能的UI控制項) getFocusedRect 和 getDrawingRect大小相同,也就是和View大小相同。當將UI焦點從本控制項移動到下一個UI控制項時,Android系統將根據本UI控制項的Focused Rect位置根據UI焦點移動的方向找到和這個Focused Rect距離最近的下一個UI控制項。 對應支援內部選擇的View(如本例或ListView)getFocusedRect 應正確設定選中地區矩形的大小:

 

[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);
}


本例將Focused Rect 設定成當前選中的矩形的大小。

3. 重載 onFocusChanged ,這個方法在當前UI View Focus狀態發生變化時調用,狀態為取得焦點和失去焦點。 重載時記住要調用基類的方法以保證標準Focus移動行為。

[java] 
@Override 
protected void onFocusChanged(boolean focused, 
 int direction, 
 Rect previouslyFocusedRect) { 
 super.onFocusChanged(focused, direction, 
 previouslyFocusedRect); 
 
 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 (previouslyFocusedRect != null) { 
 int y = previouslyFocusedRect.top 
 + (previouslyFocusedRect.height() / 2); 
 int yPerRow = getHeight() / mNumRows; 
 mSelectedRow = y / yPerRow; 
 } else { 
 mSelectedRow = 0; 
 } 
 break; 
 default: 
 // can't gleam any useful information about what internal  
 // selection should be...  
 return; 
 } 
 invalidate(); 
 } 

@Override
protected void onFocusChanged(boolean focused,
 int direction,
 Rect previouslyFocusedRect) {
 super.onFocusChanged(focused, direction,
 previouslyFocusedRect);

 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 (previouslyFocusedRect != null) {
 int y = previouslyFocusedRect.top
 + (previouslyFocusedRect.height() / 2);
 int yPerRow = getHeight() / mNumRows;
 mSelectedRow = y / yPerRow;
 } else {
 mSelectedRow = 0;
 }
 break;
 default:
 // can't gleam any useful information about what internal
 // selection should be...
 return;
 }
 invalidate();
 }
}
函數參數:

focused: 為true時表示此View擷取焦點,否則為失去焦點。
direction: 當前焦點移動的方向,可以為上,下,左,右,前向或是後向。
previouslyFocusedRect: 不為null時表示前一個擷取焦點UI控制項(View整體)的矩形地區大小。
對於本例來說,只有FOCUS_LEFT 和 FOCUS_RIGHT 會被執行到。 InternalSelectionFocus 從左至右並排顯示3個InternalSelectionView的樣本。 “左”,“右”鍵可以在左,中,右三個InternalSelectionView 來回移動UI焦點。 “上”,“下”就可以在當前擷取UI焦點的一個InternalSelectionView對象上下選擇一個矩形。

看看“左”,“右”鍵移動UI焦點時,下一個擷取焦點的InternalSelectionView 中哪個矩形會被選中:

[java]
if (previouslyFocusedRect != null) { 
 int y = previouslyFocusedRect.top 
 + (previouslyFocusedRect.height() / 2); 
 int yPerRow = getHeight() / mNumRows; 
 mSelectedRow = y / yPerRow; 

if (previouslyFocusedRect != null) {
 int y = previouslyFocusedRect.top
 + (previouslyFocusedRect.height() / 2);
 int yPerRow = getHeight() / mNumRows;
 mSelectedRow = y / yPerRow;
}
由於三個View的頂部和底部對齊 ,也就是previouslyFocusedRect 的top 和bottom 對於當前選中哪個View都是一樣的,因此算出來的mSelectuedRow 都一樣,對應本例都為3. 因此使用”左”,”右” 移動UI焦點時,下一個擷取焦點的InternalSelectionView 總是首先選中序號為3的矩形。

 
作者:mapdigit
 
 

 

 

 




相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.