AndroidでのフルスクリーンDialogの実現

6411 ワード

Dialogはアプリ開発でよく使われるコントロールで、Activityと似ていて、独立したWindowウィンドウを持っていますが、DialogとActivityには一定の違いがあります.最も明らかなのは、デフォルトではDialogは全画面ではありませんので、レイアウトはActivityほど快適ではありません.例えば、上部がそろっていて、下部が揃えられていて、マージン、幅、高さなどです.Dialogをフルスクリーンに定義すると多くの問題が省け、一般的なレイアウトで完全に処理できます.ネット上での実装方法は少なくありませんが、一般的には効果的ですが、なぜ一部のウィンドウ属性(タイトルを隠す)はsetContentViewの前に設定しなければならないのか、逆に後に設定しなければならないのかという疑問もあるかもしれません.ここではいくつかの簡単な実現方法を選んで、それから原因を言って、Androidのウィンドウ管理とViewの描画はとても大きいので、ここはあまり深くありません.
ここでは2つの方法について説明します.
Dialogの実装方法
public class FullScrreenDialog extends Dialog {
    public FullScrreenDialog(Context context) {
        super(context);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        getWindow().requestFeature(Window.FEATURE_NO_TITLE);
        View view = LayoutInflater.from(getContext()).inflate(R.layout.fragment_full_screen, null);
        
        setContentView(view);
        
        getWindow().setBackgroundDrawable(new ColorDrawable(0x00000000));
        
        getWindow().setLayout(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT);
    }
}

ここでは4つのポイントに関連して、キー1はsetContentViewの前に設定され、主にいくつかの低バージョンの互換性のためにTitle部分が表示されないようにするため、キー2はよく使われるsetContentViewであり、キー3本4は全画面ダイアログボックスの修正のためであり、キー4はsetContentViewの後ろに置かなければならない.setContentViewの前に置くと、この属性はsetContentView関数によって無効になるため、原因は後で話します.統一されたフルスクリーンDialogをカプセル化したい場合は、キー1を構築方法に、キー3と4をonStartに、主にsetContentViewの実行順序を保証します.
public class FullScreenDialog extends Dialog {
    public FullScreenDialog(Context context) {
        super(context);
        getWindow().requestFeature(Window.FEATURE_NO_TITLE);
    }

    @Override
    protected void onStart() {
        getWindow().setBackgroundDrawable(new ColorDrawable(0x00000000));
        getWindow().setLayout(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT);
    }
}

DialogFragmentの実装方法
AndroidはDialogFragment実装ダイアログボックスを推奨しており、Dialogのすべてのニーズを完全に実現し、Fragmentのライフサイクル管理を多重化し、バックグラウンドで殺された後、自動的に復元することができます.フルスクリーンを実現する原理はDialogと同じで、タイミングの把握にすぎない.
public class FullScreen DialogFragment extends DialogFragment {

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_full_screen, container, false);
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
    
        getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE);
        super.onActivityCreated(savedInstanceState);
    
        getDialog().getWindow().setBackgroundDrawable(new ColorDrawable(0x00000000));
        getDialog().getWindow().setLayout(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT);
    }

}

まず、ここでonActivity Createdで処理する理由を見てみましょう.DialogFragmentの実装ソースコードを少しフォローすると、setContentViewのタイミングはonActivity Createdで、次のコードキー1を見てみましょう.
@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    if (!mShowsDialog) {
        return;
    }
    View view = getView();
    if (view != null) {
        if (view.getParent() != null) {
            throw new IllegalStateException("DialogFragment can not be attached to a container view");
        }
        
        mDialog.setContentView(view);
    }
    ...
}

もちろん、ベースクラスDialogの実装も参照できますが、setContentViewの呼び出しタイミングを把握することが重要です.