android使用者介面-事件處理

來源:互聯網
上載者:User

 處理UI事件
  在android上, 有多種方法擷取使用者與應用程式的互動資訊. 當考慮UI內部的事件時, 我們的方法是抓取特定的與使用者互動的View對象產生的事件.
  在你用來組成布局的View對象中,你可能會注意到一些用於處理UI事件的回呼函數. 這些方法是被Android架構調用的. 例如,當一個View被按下時, 它的onTouchEvent()方法被調用. 但是,為了截獲這個資訊,你必須擴充這個類並改寫這個方法. 而擴充每個View對象來處理這樣的事件可能是不實際的. 這就是為什麼View類還包含一組你可以更方便定義的嵌套介面. 這些介面被稱為監聽器, 它們是你用來抓取使用者動作的利器.
  雖然你可能更加常用事件監聽器來監聽使用者動作, 有時候你可能確實希望通過擴充一個View類的方法來做這一點. 可能你希望擴充Button類來做一些巧妙的事情. 在這個情況下, 你能夠使用時間處理器來定義該類的預設的事件行為.
  Event Listeners 事件監聽器
  一個事件監聽器是View類的一個介面. 該介面包含的方法會在View註冊的事件監聽器被觸發時被Android調用.
  在事件監聽器中有下列方法:
  * onClick() 位於View.OnClickListener中. 在使用者觸摸該對象,或者使用軌跡球等使該對象獲得焦點, 並按下"enter"鍵或者按下軌跡球時被調用.
  * onLongClick() 位於 View.OnLongClickListener中. 在使用者按住該元素,或者按住軌跡球時調用.
  * onFocusChange() 位於 View.OnFocusChangeListener中. 該對象獲得或失去焦點時調用.
  * onKey() 位於 View.OnKeyListener中. 在該對象獲得焦點,並且按下一個鍵時調用.
  * onTouch() View.OnTouchListener. 當使用者在View對象的範圍內進行一個觸摸動作時. 例如按下,放開,或者任何的移動手勢.
  * onCreateContextMenu() View.OnCreateContextMenuListener. 當一個捷徑功能表被顯示時(當使用者長按).
  這些方法只是它們對應介面的唯一方法. 為了定義這些方法, 可以在你的Activity中實現這個介面, 也可以使用一個匿名類. 然後, 將實現該介面執行個體傳給對應的View.set...Listener方法.
  以OnClickListener為例:
  // Create an anonymous implementation of OnClickListener
  private OnClickListener mCorkyListener = new OnClickListener() {
  public void onClick(View v) {
  
  // do something when the button is clicked
  }
  };
  protected void onCreate(Bundle savedValues) {
  ...
  // Capture our button from layout
  Button button = (Button)findViewById(R.id.corky);
  // Register the onClick listener with the implementation above
  button.setOnClickListener(mCorkyListener);
  ...
  }
  你可能覺得將OnClickListener 實現為activity的一部分會更加方便. 這可以避免額外的類. 例如:
  public class ExampleActivity extends Activity implements OnClickListener {
  protected void onCreate(Bundle savedValues) {
  ...
  Button button = (Button)findViewById(R.id.corky);
  button.setOnClickListener(this);
  }
  // Implement the OnClickListener callback
  public void onClick(View v) {
  // do something when the button is clicked
  }
  ...
  }
  注意 onClick() 沒有傳回值, 但有些事件監聽器必須有一個布爾傳回值. 下面是一些原因:
  * onLongClick() - 返回一個布爾值表示你是否消耗了該event. 也就是,如果你已經處理了該event, 則它應該停止了,就返回true, 而如果你沒有處理它,而是將它留給其它的on-click監聽器, 則返回false.
  * onKey() - 同上.
  * onTouch() - 返回一個布爾值表示你是否消耗了該event. 該event可以有多個動作. 如果在向下的動作接收時你返回false, 就表示你沒有消耗該event, 並且對後續動作也不感興趣. 也就是說, 後面的手勢動作,以及最後的向上動作都將不會再被通知.
  鍵事件永遠會被發送到當前獲得焦點的View. 它們是從View層次的頂端開始指派, 然後向下直到合適的目的地. 如果你的View現在擁有焦點, 那麼你可以從dispatchKeyEvent()方法中看到事件的指派過程. 除了使用veiw之外,你也可以使用你的Activity的onKeyDown()和onKeyUp()方法來擷取所有的時間.
  注意: Android將首先呼叫事件處理器, 然後調用合適的預設處理器. 因此, 從這些事件監聽器中返回true將使其它監聽器和預設處理器失效. 因此在你返回true時要小心.
  Event Handlers 事件處理器
  如果你從View來建立一個自訂的component,那麼你可以定義一些預設事件處理器。在 Building Custom Components文檔中,你將看到這些回呼函數:
  * onKeyDown(int, KeyEvent) -當一個新的鍵盤時間開始被調用。
  * onKeyUp(int, KeyEvent) -當一個鍵被釋放時調用。
  * onTrackballEvent(MotionEvent) -當軌跡球移動時調用。
  * onTouchEvent(MotionEvent) - 當螢幕發生移動事件時調用。
  * onFocusChanged(boolean, int, Rect) -當一個View丟失焦點時調用。
  有一些不屬於View,但是也能直接影響到事件處理的方法:
  * Activity.dispatchTouchEvent(MotionEvent) -可以在這些事件被指派到視窗之前讓Activity截獲所有的事件。
  * ViewGroup.onInterceptTouchEvent(MotionEvent) -讓ViewGroup在事件指派到子View之前看到這些事件。
  * ViewParent.requestDisallowInterceptTouchEvent(boolean) - 讓父View不要使用onInterceptTouchEvent(MotionEvent)來截獲event.

Touch Mode 觸摸模式
  但一個使用者使用方向鍵或者軌跡球來在UI上移動時, 需要讓可動作的UI元素獲得焦點, 這樣使用者可以看到什麼東西將獲得他們的輸入。如果裝置具有觸摸能力,使用者使用觸摸的方式來互動,那麼就沒有必要給一個元素焦點。因此,有一種互動的模式叫做“觸摸模式”。
  對於一個可觸摸的裝置,一旦使用者觸摸了螢幕,裝置就進入觸摸模式。在這以後,只有isFocusableInTouchMode()為真的View是可以獲得焦點的,例如文字框。其它的View可以觸摸,例如按鈕,在觸摸的時候不會獲得焦點。它們只是啟動對應的on-click監聽器。在使用者按下方向鍵或者旋轉軌跡球時,裝置將退出觸摸模式,並尋找一個view並使他獲得焦點。現在,使用者可以不觸控螢幕幕來互動。
  觸摸模式狀態在整個系統中被維護。你可以使用isInTouchMode()來查詢目前狀態。
  Handling Focus 處理焦點
  android架構會根據使用者輸入來處理焦點的移動。這包含了在View被移除或隱藏或再次出現時改變焦點。View使用isFocusable()和setFocusable()方法來表示和設定它們能否獲得焦點。在觸摸模式下,可以使用isFocusableInTouchMode()和setFocusableInTouchMode().。
  焦點移動時基於在某方向上最近距離元素的演算法。在很少見的情形下,預設的演算法可能和開發人員的想法不一樣。在這種情況下,你可以提供一個演算法,修改以下幾個

  
xml屬性:nextFocusDown, nextFocusLeft, nextFocusRight和 nextFocusUp. 例如:
  《LinearLayout
  android:orientation="vertical"
  ... 》
  《Button android:
  android:nextFocusUp="@+id/bottom"
  ... /》
  《Button android:
  android:nextFocusDown="@+id/top"
  ... /》
  《/LinearLayout》
  一般來說,在這個豎直向下的布局中,從第一個按鈕向上不會走到哪裡。加入上述代碼後,從第一個按鈕向上會使第二個按鈕擷取焦點。
  如果你希望將一個View設為可擷取焦點,那麼加入xml屬性android:focusable="true" 和 android:focusableInTouchMode = "true".
  希望一個View獲得焦點時,調用requestFocus().
  要監聽焦時間點事件,使用onFocusChange()。

 

執行個體:

代碼

package com.amaker.test;

import android.app.Activity;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnFocusChangeListener;
import android.view.View.OnKeyListener;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.Toast;
import android.widget.CompoundButton.OnCheckedChangeListener;

/**
*
* 測試事件
*/
public class MainActivity extends Activity {
/** Called when the activity is first created. */

private EditText myEdit1, myEdit2;
private CheckBox cb1;
private Button b1, b2;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

myEdit1 = (EditText) findViewById(R.id.EditText01);
myEdit2 = (EditText) findViewById(R.id.EditText02);

cb1 = (CheckBox) findViewById(R.id.CheckBox01);
b1 = (Button) findViewById(R.id.Button01);
b2 = (Button) findViewById(R.id.Button02);

// 編輯文字框的按鍵事件
myEdit1.setOnKeyListener(new OnKeyListener() {
public boolean onKey(View v, int keyCode, KeyEvent event) {
myEdit1.setText("");
return false;
}
});

// 編輯文字框的按鍵事件
myEdit2.setOnKeyListener(new OnKeyListener() {
public boolean onKey(View v, int keyCode, KeyEvent event) {
myEdit2.setText("");
return false;
}
});

// 編輯文字框的焦時間點事件
myEdit1.setOnFocusChangeListener(new OnFocusChangeListener() {
public void onFocusChange(View v, boolean hasFocus) {
Toast.makeText(getApplicationContext(), myEdit1.getText(),
Toast.LENGTH_LONG);
}
});
// 編輯文字框的焦時間點事件
myEdit2.setOnFocusChangeListener(new OnFocusChangeListener() {
public void onFocusChange(View v, boolean hasFocus) {
Toast.makeText(getApplicationContext(), myEdit2.getText(),
Toast.LENGTH_LONG);
}
});
// 多選框的選擇事件
cb1.setOnCheckedChangeListener(new OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
Toast.makeText(getApplicationContext(), cb1.isChecked() + "",
Toast.LENGTH_LONG);
}
});
// 按鈕的選擇事件
b1.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Toast.makeText(getApplicationContext(), b1.getText(),
Toast.LENGTH_LONG);
}
});
// 按鈕的選擇事件
b2.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Toast.makeText(getApplicationContext(), b2.getText(),
Toast.LENGTH_LONG);
}
});

}
}

 

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.