標籤:
http://blog.csdn.net/wangjinyu501/article/details/22052187
在Android中到處可見介面回調機制,尤其是UI事件處理方面。舉一個最常見的例子button點擊事件,button有一個點擊方法onClick(),我們知道onclick()是一個回調方法,當使用者點擊button就執行這個方法。在源碼中是這樣定義的:
//這個是View的一個回調介面 /** * Interface definition for a callback to be invoked when a view is clicked. */ public interface OnClickListener { /** * Called when a view has been clicked. * * @param v The view that was clicked. */ void onClick(View v); }
下面看一個簡單的例子:
import android.app.Activity; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.Toast; public class MainActivity extends Activity implements OnClickListener{ private Button button; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); button = (Button)findViewById(R.id.button1); button.setOnClickListener(this); } @Override public void onClick(View v) { Toast.makeText(getApplication(), "OnClick", Toast.LENGTH_LONG).show(); } } 這就是一個很典型的例子,當然也可以這樣寫: import android.app.Activity; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; public class SSSS extends Activity { private Button button; private OnClickListener clickListener = new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub } }; @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); button = (Button)findViewById(R.id.button1); button.setOnClickListener(clickListener); } }
下面是View類的setOnClickListener方法,把和回調相關代碼貼出來。什麼貼它呢,因為Button繼承於TextView,而TextView繼承於View,在View裡面處理的回調:
/** * */ public class View implements Drawable.Callback, KeyEvent.Callback, AccessibilityEventSource { /** * Listener used to dispatch click events. * This field should be made private, so it is hidden from the SDK. * {@hide} */ protected OnClickListener mOnClickListener; /** * * Register a callback to be invoked when this view is clicked. If this view is not * clickable, it becomes clickable. * * @param l The callback that will run * * @see #setClickable(boolean) */ public void setOnClickListener(OnClickListener l) { if (!isClickable()) { setClickable(true); } mOnClickListener = l; } /** * Call this view‘s OnClickListener, if it is defined. * * @return True there was an assigned OnClickListener that was called, false * otherwise is returned. */ public boolean performClick() { sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED); if (mOnClickListener != null) { playSoundEffect(SoundEffectConstants.CLICK); mOnClickListener.onClick(this); return true; } return false; } }
那現在一起來總結一下基本的回調是如何?的,首先建立一個介面,這個介面用於你在某 個情景下執行相應的操作。接著建立一個功能類,比如這個類可以顯示一個對話方塊、可以滑動菜單、可以下載資料等等。然後,在這個類裡面聲明回調介面的對象, 之後在這個類裡面建立在某個情景下需要執行的方法,而且在這個方法裡面為聲明的介面對象賦值。最後在其他的類中使用這個功能類就可以了。所以說,最少也是 需要三個類共同來完成這個回調機制。 這下大家應該就比較明白了,那我們就自己按照這個方式和流程完成一個這樣的例子。以Dialog為例,一般我們在開發時候,經常會用到Dialog。比如一個彈出框,裡面有確認和取消。通常情況下,我們可能會這樣寫:
final Dialog dialog = new Dialog(this, R.style.MyDialogStyle); dialog.setContentView(R.layout.dialog_exit_train); dialog.show(); ImageButton ib_affirm = (ImageButton) dialog .findViewById(R.id.dialog_exit_ib_affirm); ImageButton ib_cancel = (ImageButton) dialog .findViewById(R.id.dialog_exit_ib_cancel); ib_affirm.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { saveUserData(); dialog.dismiss(); TestActivity.this.finish(); } }); ib_cancel.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { dialog.dismiss(); } }); 也就是得到點擊對象之後再去調用onClick(),這樣有一個缺點就是你每次都要寫,不利於重複使用。那我們就可以對此進行一個封裝,看代碼:
import android.app.Dialog; import android.content.Context; import android.os.Bundle; import android.text.TextPaint; import android.view.View; import android.view.Window; import android.view.WindowManager; import android.widget.Button; import android.widget.TextView; import com.fanfou.app.opensource.R; /** * * */ public class AlertInfoDialog extends Dialog implements View.OnClickListener { //建立介面 public static interface OnOKClickListener { public void onOKClick(); } private final Context mContext; private TextView mTitleView; private TextView mTextView; private Button mButtonOk; private CharSequence mTitle; private CharSequence mText; //生命介面對象 private OnOKClickListener mClickListener; public AlertInfoDialog(final Context context, final String title, final String text) { super(context, R.style.Dialog); this.mContext = context; this.mTitle = title; this.mText = text; } private void init() { setContentView(R.layout.dialog_alert); this.mTitleView = (TextView) findViewById(R.id.title); final TextPaint tp = this.mTitleView.getPaint(); tp.setFakeBoldText(true); this.mTitleView.setText(this.mTitle); this.mTextView = (TextView) findViewById(R.id.text); this.mTextView.setText(this.mText); this.mButtonOk = (Button) findViewById(R.id.button_ok); this.mButtonOk.setOnClickListener(this); } @Override public void onClick(final View v) { final int id = v.getId(); switch (id) { case R.id.button_ok: cancel();//調用 if (this.mClickListener != null) { this.mClickListener.onOKClick(); } break; default: break; } } @Override protected void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); setBlurEffect(); init(); } protected void setBlurEffect() { final Window window = getWindow(); final WindowManager.LayoutParams lp = window.getAttributes(); // lp.alpha=0.8f; lp.dimAmount = 0.6f; window.setAttributes(lp); window.addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND); // window.addFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND); } public void setMessage(final CharSequence message) { this.mText = message; this.mTextView.setText(this.mText); } public void setMessage(final int resId) { this.mText = this.mContext.getResources().getText(resId); this.mTextView.setText(this.mText); } //設定監聽器 也就是執行個體化介面 public void setOnClickListener(final OnOKClickListener clickListener) { this.mClickListener = clickListener; } @Override public void setTitle(final CharSequence title) { this.mTitle = title; this.mTitleView.setText(this.mTitle); } @Override public void setTitle(final int resId) { this.mTitle = this.mContext.getResources().getText(resId); this.mTitleView.setText(this.mTitle); } }
方式和上面介紹的一樣,感興趣的朋友可以自己去實現其他效果的。
Android 中的介面回調