support.v4.app.DialogFragment使用問題總結

因app需求問題,須要實現如圖這種dialog java

看到這裏,你可能會說如此easy的事情,還說什麼! 那麼繼續往下看! android

場景1: app

import android.app.Dialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.DialogFragment;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.view.LayoutInflater;
import android.view.View;

public class AlertDialogFragmentActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_alert_dialog_fragment);

        findViewById(R.id.show).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showDialog();
            }
        });
    }

    public static class MyAlertDialogFragment extends DialogFragment {
        public static MyAlertDialogFragment newInstance(int title) {
            MyAlertDialogFragment frag = new MyAlertDialogFragment();
            Bundle args = new Bundle();
            args.putInt("title", title);
            frag.setArguments(args);
            return frag;
        }

        @NonNull
        @Override
        public Dialog onCreateDialog(Bundle savedInstanceState) {
            int title = getArguments().getInt("title");
            // AlertDialog 的內容區
            View contentView = LayoutInflater.from(getActivity()).inflate(R.layout.basic_dialog_fragment, null);
            return new AlertDialog.Builder(getActivity())
                    .setIcon(R.drawable.ic_about)
                    .setTitle(title)
                    .setView(contentView)
                    .setPositiveButton("ok", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {

                        }
                    })
                    .setNegativeButton("cancel", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {

                        }
                    })
                    .create();
        }

    }
    void showDialog() {
        DialogFragment newFragment = MyAlertDialogFragment.newInstance(R.string.two_buttons_title);
        newFragment.show(getSupportFragmentManager(), "dialog");
    }
}

實際效果圖成了這樣 ide

title區的內容不是縱橫向居中的,button區徹底走樣右對齊了,如上圖所示,只有綠色內容區是自定義內容,(title和button樣式都是Android內置) 佈局

這是什麼緣由形成的? ui

這是由於當前這個AlertDialogFragmentActivity的theme屬性的緣由,它繼承自AppCompatActivity要求使用 Theme.AppCompat.xxx 系列theme this

代碼中(AppCompatActivity,DialogFragment,AlertDialog)都是support library中的類,這些的類是配套使用的,你不能在Activity中直接使用support library中的DialogFragment和AlertDialog spa

嘗試在AndroidManifest.xml中將AppCompatActivity的android:theme屬性改爲"@android:style/Theme.Holo"等,後續獲得一個如下異常 code

Caused by: java.lang.IllegalStateException: You need to use a Theme.AppCompat theme (or descendant) with this activity. xml

Theme.AppCompat.xxx 系列theme能夠用於非support library包中的類,反過來Theme.Holo.xxx 或者 Theme.Light.xxx 等系列則沒法用於support library包中的類

嘗試修改 MyAlertDialogFragment的onCreateDialog 中的AlertDialog.Builder()代碼

new AlertDialog.Builder(getActivity(),android.R.style.Theme_Holo_Dialog)

獲得的效果圖以下,反而更差

場景2:

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.view.LayoutInflater;
import android.view.View;



public class AlertDialogFragmentActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_alert_dialog_fragment);

        findViewById(R.id.show).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showDialog();
            }
        });
    }

    public static class MyAlertDialogFragment extends DialogFragment {
        public static MyAlertDialogFragment newInstance(int title) {
            MyAlertDialogFragment frag = new MyAlertDialogFragment();
            Bundle args = new Bundle();
            args.putInt("title", title);
            frag.setArguments(args);
            return frag;
        }

        @NonNull
        @Override
        public Dialog onCreateDialog(Bundle savedInstanceState) {
            int title = getArguments().getInt("title");
            // AlertDialog 的內容區
            View contentView = LayoutInflater.from(getActivity()).inflate(R.layout.basic_dialog_fragment, null);
            return new AlertDialog.Builder(getActivity())
                    .setIcon(R.drawable.ic_about)
                    .setTitle(title)
                    .setView(contentView)
                    .setPositiveButton("ok", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {

                        }
                    })
                    .setNegativeButton("cancel", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {

                        }
                    })
                    .create();
        }

    }
    void showDialog() {
        DialogFragment newFragment = MyAlertDialogFragment.newInstance(R.string.two_buttons_title);
        newFragment.show(getFragmentManager(), "dialog");
    }
}

獲得的效果圖基本理想:

場景2中沒有使用support library中類,並且Theme.AppCompat.xxx系列theme能夠兼容低版本API,可是你的App的最小API也要11以上。

鑑於以上緣由,最好自定義Dialog的內容區(在你自定義時,模仿將title和button都定義到你的佈局中),而後不設置Dialog的title,button屬性,只調用AlertDialog.Builder#setView(view),或者Dialog#setContentView(View view)

相關文章
相關標籤/搜索