Android作成ウィンドウ(二)Dialogの作成
5623 ワード
Android作成ウィンドウ(一)作成アプリケーションウィンドウでは、アプリケーションウィンドウの作成手順について説明し、Dialogの作成手順について説明します.Dialogの作成とアプリケーションウィンドウの作成には似たような点がたくさんあります.前のファイルで紹介したので、ここで似たようなところをスキップしました.
まず、Dialogを表示する方法を見てみましょう.
Dialogのコードを表示するのは簡単ですが、次は一歩一歩分析してみましょう.
1.アプリケーションウィンドウを作成します.まずActivityオブジェクトを作成します.Dialogを作成することもDialogオブジェクトを作成することになります.まず、Dialogのコンストラクション関数を見てみましょう.
やはりアプリウィンドウと同じように、まずWindowオブジェクトを作成しました.
2.次にcontentviewを設定します.
Dialogはこのタスクをwindowに任せて完了し、Activityと同様にwindowでレイアウトファイルを追加します.PhoneWindowのsetContentViewメソッド:
Android作成ウィンドウ(一)作成アプリケーションウィンドウでこの方法を紹介していますが、ここではあまりお話ししません.これはレイアウトファイルをdecorviewに追加することです.
3.WindowにDecorViewを追加して表示する
このステップはDialogのshowメソッドで完成しました.ソースコードを見てみましょう.
showメソッドはまずmDecorがnullとして保存されているかどうかを判断し、nullでなければ表示し、nullであれば初期化し、decorviewをwindowに追加します.
以上の3つのステップから、Dialogの作成とActivityの作成のプロセスには多くの類似点があることがわかる.
Dialogのdismissを見てみましょう
これは比較的簡単で、Dialogが閉じるとWindowManagerでdecorviewをwindowから削除します.
ソース分析によるAndroidウィンドウの作成:Android作成ウィンドウ(一)アプリケーションウィンドウAndroid作成ウィンドウ(二)Dialog Android作成ウィンドウ(三)Toastの作成
まず、Dialogを表示する方法を見てみましょう.
Dialog dialog=new Dialog(MainActivity.this);
dialog.setContentView(R.layout.dialog);
dialog.show();
Dialogのコードを表示するのは簡単ですが、次は一歩一歩分析してみましょう.
1.アプリケーションウィンドウを作成します.まずActivityオブジェクトを作成します.Dialogを作成することもDialogオブジェクトを作成することになります.まず、Dialogのコンストラクション関数を見てみましょう.
Dialog(@NonNull Context context, @StyleRes int themeResId, boolean createContextThemeWrapper) {
...
mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
final Window w = new PhoneWindow(mContext);
mWindow = w;
w.setCallback(this);
w.setOnWindowDismissedCallback(this);
w.setWindowManager(mWindowManager, null, null);
w.setGravity(Gravity.CENTER);
mListenersHandler = new ListenersHandler(this);
}
やはりアプリウィンドウと同じように、まずWindowオブジェクトを作成しました.
2.次にcontentviewを設定します.
public void setContentView(@LayoutRes int layoutResID) {
mWindow.setContentView(layoutResID);
}
Dialogはこのタスクをwindowに任せて完了し、Activityと同様にwindowでレイアウトファイルを追加します.PhoneWindowのsetContentViewメソッド:
public void setContentView(int layoutResID) {
// Note: FEATURE_CONTENT_TRANSITIONS may be set in the process of installing the window
// decor, when theme attributes and the like are crystalized. Do not check the feature
// before this happens.
if (mContentParent == null) {
installDecor();
} else if (!hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
mContentParent.removeAllViews();
}
if (hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
final Scene newScene = Scene.getSceneForLayout(mContentParent, layoutResID,
getContext());
transitionTo(newScene);
} else {
mLayoutInflater.inflate(layoutResID, mContentParent);
}
mContentParent.requestApplyInsets();
final Callback cb = getCallback();
if (cb != null && !isDestroyed()) {
cb.onContentChanged();
}
mContentParentExplicitlySet = true;
}
Android作成ウィンドウ(一)作成アプリケーションウィンドウでこの方法を紹介していますが、ここではあまりお話ししません.これはレイアウトファイルをdecorviewに追加することです.
3.WindowにDecorViewを追加して表示する
このステップはDialogのshowメソッドで完成しました.ソースコードを見てみましょう.
/**
* Start the dialog and display it on screen. The window is placed in the
* application layer and opaque. Note that you should not override this
* method to do initialization when the dialog is shown, instead implement
* that in {@link #onStart}.
*/
public void show() {
if (mShowing) {
if (mDecor != null) {// decorview ,
if (mWindow.hasFeature(Window.FEATURE_ACTION_BAR)) {
mWindow.invalidatePanelMenu(Window.FEATURE_ACTION_BAR);
}
mDecor.setVisibility(View.VISIBLE);
}
return;
}
mCanceled = false;
if (!mCreated) {
dispatchOnCreate(null);
} else {
// Fill the DecorView in on any configuration changes that
// may have occured while it was removed from the WindowManager.
final Configuration config = mContext.getResources().getConfiguration();
mWindow.getDecorView().dispatchConfigurationChanged(config);
}
onStart();
// decorview
mDecor = mWindow.getDecorView();
if (mActionBar == null && mWindow.hasFeature(Window.FEATURE_ACTION_BAR)) {
final ApplicationInfo info = mContext.getApplicationInfo();
mWindow.setDefaultIcon(info.icon);
mWindow.setDefaultLogo(info.logo);
mActionBar = new WindowDecorActionBar(this);
}
WindowManager.LayoutParams l = mWindow.getAttributes();
if ((l.softInputMode
& WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION) == 0) {
WindowManager.LayoutParams nl = new WindowManager.LayoutParams();
nl.copyFrom(l);
nl.softInputMode |=
WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION;
l = nl;
}
// decorView window
mWindowManager.addView(mDecor, l);
mShowing = true;
sendShowMessage();
}
showメソッドはまずmDecorがnullとして保存されているかどうかを判断し、nullでなければ表示し、nullであれば初期化し、decorviewをwindowに追加します.
以上の3つのステップから、Dialogの作成とActivityの作成のプロセスには多くの類似点があることがわかる.
Dialogのdismissを見てみましょう
/**
* Dismiss this dialog, removing it from the screen. This method can be
* invoked safely from any thread. Note that you should not override this
* method to do cleanup when the dialog is dismissed, instead implement
* that in {@link #onStop}.
*/
@Override
public void dismiss() {
if (Looper.myLooper() == mHandler.getLooper()) {
dismissDialog();
} else {
mHandler.post(mDismissAction);
}
}
void dismissDialog() {
if (mDecor == null || !mShowing) {
return;
}
if (mWindow.isDestroyed()) {
Log.e(TAG, "Tried to dismissDialog() but the Dialog's window was already destroyed!");
return;
}
try {
mWindowManager.removeViewImmediate(mDecor);
} finally {
if (mActionMode != null) {
mActionMode.finish();
}
mDecor = null;
mWindow.closeAllPanels();
onStop();
mShowing = false;
sendDismissMessage();
}
}
これは比較的簡単で、Dialogが閉じるとWindowManagerでdecorviewをwindowから削除します.
ソース分析によるAndroidウィンドウの作成:Android作成ウィンドウ(一)アプリケーションウィンドウAndroid作成ウィンドウ(二)Dialog Android作成ウィンドウ(三)Toastの作成