使用DialogFragment

DialogFagmet是一个特殊的碎片经常被用作在活动中展示叠加的窗口,在其他内容之上。
经常被用作展示警告对话框,确认对话框,或者为了在同一个页面来提示信息。
DialogFragment现在是一种常见的做法,而之间使用Dialog被认为不正确。

使用

创建一个DialogFragment的最简单方式是实现onCreateView 或者onCreateDialog 方法。前者是在整个对话的view的布局都是自定义的情况下使用的,而后者是只需要构建配置一个标准的Dialog类的情况下使用。
* 注意:所有的方法要求使用v4的包,而不是andorid.app *

自定义View

首先我们需要自定义一个Xml文件作为dialog的布局文件:fragment_edit_name.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/edit_name">
    <TextView
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"
        android:id="@+id/lbl_your_name"
        android:text="Your name"/>
    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/txt_your_name"
        android:inputType="text"
        android:imeOptions="actionDone"/>

</LinearLayout>

然后开始定义碎片本身:

public class EditNameDialogFragment extends DialogFragment {
    private EditText mEditText;

    public EditNameDialogFragment() {
        //要求空的构造方法
        //不要加参数
        //使用newInstance获得实例
    }

    public static EditNameDialogFragment newInstance(String title) {
        EditNameDialogFragment frag = new EditNameDialogFragment();
        Bundle args = new Bundle();
        args.putString("title", title);
        frag.setArguments(args);
        return frag;
    }

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

    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        //从biew中加载控件
        mEditText = (EditText) view.findViewById(R.id.txt_your_name);
        //从bundle中获取参数设置title
        //getArguments获得碎片实例化时的参数,返回一个bundle参数
        String title = getArguments().getString("title", "Enter name");
        getDialog().setTitle(title);
        //自动展示软键盘并且要求焦点
        mEditText.requestFocus();
        getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
    }
}

在主活动中展示:

 private void showEditDialog() {
      FragmentManager fm = getSupportFragmentManager();
      EditNameDialogFragment editNameDialogFragment = EditNameDialogFragment.newInstance("Some Title");
      editNameDialogFragment.show(fm, "fragment_edit_name");
  }

构建dialog

让我们看看怎么通过简单的自定义可用的Dialog对象构建一个dialog,

public class MyAlertDialogFragment extends DialogFragment {

    public MyAlertDialogFragment() {

    }

    public static MyAlertDialogFragment newInstance(String title) {
        MyAlertDialogFragment frag = new MyAlertDialogFragment();
        Bundle args = new Bundle();
        args.putString("title", title);
        frag.setArguments(args);
        return frag;
    }

    @NonNull
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        String title = getArguments().getString("title");
        AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(getActivity());
        alertDialogBuilder.setTitle(title);
        alertDialogBuilder.setMessage("Are you sure");
        alertDialogBuilder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {

            }
        });
        alertDialogBuilder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();
            }
        });
        return alertDialogBuilder.create();
    }
}

向活动传递数据

对于所有碎片来说可以使用创建自定义监听器的方法向活动传递数据,需要:
- 定义一个包含传递数据给活动的方法的接口
- 建立一个view事件调用自定义的监听器通过方法传递数据
- 通过定义事件的触发条件在活动中实现接口

public class EditNameDialogFragment extends DialogFragment implements TextView.OnEditorActionListener {
    private EditText mEditText;

 //定义一个接口包含传递数据的方法
    public interface EditNameDialogListener {
        void onFinishEditDialog(String inputText);
    }
    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

        View v = inflater.inflate(R.layout.fragment_edit_name, container);
        mEditText = (EditText) v.findViewById(R.id.txt_your_name);
        //当done键摁下后建立一个回调
        mEditText.setOnEditorActionListener(this);
        return v;
    }
    //无论何时输入区域有动作时调用
    //当前情况是done键触发
    //要求软件盘


    @Override
    public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
        if (EditorInfo.IME_ACTION_DONE == actionId) {
            //通过实现监听器来讲输入的文本返回
            EditNameDialogListener listener = (EditNameDialogListener) getActivity();
            listener.onFinishEditDialog(mEditText.getText().toString());
            //关闭dialog
            dismiss();
            return true;
        }
        return false;
    }

在主活动中重写在接口中定义的方法:

public class MainActivity extends AppCompatActivity implements EditNameDialogFragment.EditNameDialogListener{

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

    private void showEditDialog() {
        FragmentManager fm = getSupportFragmentManager();
        //创建实例
        EditNameDialogFragment editNameDialogFragment = EditNameDialogFragment.newInstance("Some Title");
        editNameDialogFragment.show(fm, "fragment_edit_name");
    }

    @Override
    public void onFinishEditDialog(String inputText) {
        Toast.makeText(this, "hi"+ inputText, Toast.LENGTH_SHORT).show();
    }
}

向父碎片中传递的数据

。。。

带风格的对话

自定义风格的对话

这要求我们改变相关的主要属性styels.xml 例如dialogThemealertDialogTheme 如下所示res/values/styles.xml

<!-- In res/values/colors.xml -->
<color name="dark_blue">#180065</color>
<color name="light_blue">#334ee9ff</color>
<color name="medium_green">#3d853e</color>
<color name="light_green">#3c2ae668</color>

<!-- In res/values/styles.xml -->
<style name="AppTheme" parent="Theme.AppCompat.Light">
    <!-- Apply default style for dialogs -->
    <item name="android:dialogTheme">@style/AppDialogTheme</item>
    <!-- Apply default style for alert dialogs -->
    <item name="android:alertDialogTheme">@style/AppAlertTheme</item>
</style>

<!-- Define your custom dialog theme here extending from base -->
<style name="AppDialogTheme" parent="Theme.AppCompat.Light.Dialog">
    <!-- Define color properties as desired -->
    <item name="colorPrimary">@color/dark_blue</item>
    <item name="colorPrimaryDark">#000</item>
    <item name="android:textColorHighlight">@color/light_blue</item>
    <item name="colorAccent">@color/dark_blue</item>
    <item name="colorControlNormal">@color/dark_blue</item>
    <!-- Define window properties as desired -->
    <item name="android:windowNoTitle">false</item>
    <item name="android:windowFullscreen">false</item>
    <item name="android:windowBackground">@color/medium_green</item>
    <item name="android:windowIsFloating">true</item>
    <item name="android:windowCloseOnTouchOutside">true</item>
</style>

<!-- Define your custom alert theme here extending from base -->
<style name="AppAlertTheme" parent="Theme.AppCompat.Light.Dialog.Alert">
    <item name="colorPrimary">@color/dark_blue</item>
    <item name="colorAccent">@color/dark_blue</item>
    <item name="colorPrimaryDark">#000</item>
    <item name="colorControlNormal">@color/dark_blue</item>
    <item name="android:textColorHighlight">@color/light_blue</item>
</style>

风格化Titlebar of Dialog

我们可以使用android:windowTitleStyle 来定义:

<style name="AppTheme" parent="Theme.AppCompat.Light">
    <!-- Apply default style for dialogs -->
    <item name="android:dialogTheme">@style/AppDialogTheme</item>
    <!-- Apply default style for alert dialogs -->
    <item name="android:alertDialogTheme">@style/AppAlertTheme</item>
</style>

<style name="AppDialogTheme" parent="Theme.AppCompat.Light.Dialog">
    <item name="android:windowTitleStyle">@style/DialogWindowTitle</item>
    <!-- ...other stuff here... -->
</style>


<style name="AppAlertTheme" parent="Theme.AppCompat.Light.Dialog.Alert">
    <item name="android:windowTitleStyle">@style/DialogWindowTitle</item>
    <!-- ...other stuff here... -->
</style>

<style name="DialogWindowTitle" parent="Base.DialogWindowTitle.AppCompat">
    <item name="android:background">@color/light_green</item>
    <item name="android:gravity">center</item>
    <item name="android:textAppearance">@style/DialogWindowTitleText</item>
</style>

<style name="DialogWindowTitleText" parent="@android:style/TextAppearance.DialogWindowTitle">
    <item name="android:textSize">24sp</item>
</style>

移除TitleBar

我们可以简单的从DialogFragment移除通过重写onCreateDialog

@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
    Dialog dialog = super.onCreateDialog(savedInstanceState);
    // request a window without the title
    dialog.getWindow().requestFeature(Window.FEATURE_NO_TITLE);
    return dialog;
}

透明的Dialogs

<style name="AppDialogTheme" parent="Theme.AppCompat.Light.Dialog">
    <item name="android:windowIsTranslucent">true</item>
    <item name="android:windowBackground">@android:color/transparent</item>
    <!-- ...other stuff here... -->
</style>

使用第三方库:
https://github.com/afollestad/material-dialogs
https://github.com/fengdai/AlertDialogPro/
https://github.com/drakeet/MaterialDialog

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值