谷歌推荐FragmentDialog的书写,和LayoutInflater的方法中后两个参数的含义

本文介绍如何使用FragmentDialog创建自定义对话框,并实现数据回传至Activity。通过两种方式展示了FragmentDialog的使用方法,一种是直接继承DialogFragment并自定义布局,另一种是通过AlertDialog.Builder构建对话框。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天项目中要求写一个从底部向上的Dialog的弹窗, 当然GitHub上有大神开源库BottomSheetLayout , 专门针对底部向上弹窗的控件,使用只需要把需要弹窗的布局全部包裹起来即可,感兴趣的朋友可以去看看;  而今天在这里,我想分享下FragmentDialog的使用

为什么使用FragmentDialog:  自己写的代码,可维护性更高,并且FragmentDialog不像AlertDialog一样, 在用户输入的同时切换横竖屏会消失, 而且.美工要求说,弹窗后面背景不能为灰色的(BottomSheetLayout弹上来后后面为灰色的),  所以我们就来自己写一个FragmentDialog吧


那么,下面开始吧

package com.hanzheng.fragmentdialog;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Toast;

/**
 * 官方推荐 DialogFragment 创建对话框
 */
public class MainActivity extends AppCompatActivity implements LoginDialog.LoginInputListener{

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


    }

    public void showConfirmDialog(View view) {
        ConfimDialog confimDialog = new ConfimDialog();
        confimDialog.show(getSupportFragmentManager(),"confirmDialog");
    }

    //显示登录的对话框,用AlertDialog
    public void showLoginDialog(View view) {
        LoginDialog loginDialog = new LoginDialog();
        loginDialog.show(getFragmentManager(),"loginDialog");

    }

    @Override
    public void login(String username, String pwd) {
        Toast.makeText(this,"姓名:" + username+";密码:" + pwd,Toast.LENGTH_LONG).show();
    }
}
首先, 主布局的代码: 两个按钮的点击事件,中可以看到,DialogFragment是new出来,然后调用show()显示的,  同时主页面还实现了LoginDialog类中的LoginInputListener的接口


ConfirmDialog继承DialogFragment

布局文件的写法:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                android:layout_width="50dp"
                android:layout_height="50dp" >

    <TextView
        android:id="@+id/id_label_your_name"
        android:layout_width="wrap_content"
        android:layout_height="32dp"
        android:gravity="center_vertical"
        android:text="Your name:" />

    <EditText
        android:id="@+id/id_txt_your_name"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@id/id_label_your_name"
        android:imeOptions="actionDone"
        android:inputType="text" />

    <Button
        android:id="@+id/id_sure_edit_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_below="@id/id_txt_your_name"
        android:text="ok" />

</RelativeLayout>
代码:

package com.hanzheng.fragmentdialog;

import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.DialogFragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;

/**
 * Created by zmybi on 2017/1/9.
 *
 * 确认对话框
 */

public class ConfimDialog extends DialogFragment {

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

        //去掉Dialog上空白的标题 占的位置
        getDialog().requestWindowFeature(Window.FEATURE_NO_TITLE);
        View view = inflater.from(getActivity()).   inflate(R.layout.confirm_dialog,container);
        return view;
    }
}
这里from 中参数一定是写getActivity()来得到上下文, 因为Dialog是依附于Activity的

同时 关于LayoutInflator.inflate(int resource, ViewGroup root, boolean attachToRoot)三个参数的方法的说明:

  1. 当root=null时候, 第三个参数attachToRoot为false或者true 已经没有意义了, 表示不考虑resource布局条目的书写, 根布局写什么  也只会将它包裹起来
  2. 当root 不为null时候, 第三个参数为false  表示考虑根布局的书写,  但是如果返回一个view 将其添加到父root中,则这些layout属性将会失效
  3. 当root不为null时候,第三个参数为true, 表示给控件加载一个父布局,直接将R.layout...的布局传入某些自定义控件中,同时将当前对象this返回,返回值影响极大
  4. 在设置attachToRoot的情况下, 如果root不为null, 则attachToRoot默认为true

这就是我总结的关于LayoutInflator的三个参数的作用, 在RecyclerView中条目布局中使用极其广泛

回到上面, 当点击第一个按钮的时候,则弹出一个宽度填充父容器的对话框


2 FragmentDialog的第二种用法,这种用法也是很重要的,看LoginDialog类中的代码

package com.hanzheng.fragmentdialog;

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;
import android.widget.EditText;


/**
 * LoginDialog
 * 并且实现 从Dialog传递数据给Activity
 */

public class LoginDialog extends DialogFragment {

    private EditText mUsername;
    private EditText mPossword;

    public interface LoginInputListener{
        void login(String username,String pwd);
    }


    @NonNull
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        //返回一个Dialog用于展示
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        LayoutInflater layoutInflater = getActivity().getLayoutInflater();
        final View view = layoutInflater.inflate(R.layout.login_dialog,null);
        builder.setView(view)
                .setPositiveButton("login", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        mUsername = (EditText) view.findViewById(R.id.et_username_login);
                        mPossword = (EditText) view.findViewById(R.id.et_pwd_login);
                        LoginInputListener loginInputListener = (LoginInputListener) getActivity();
                        loginInputListener.login(mUsername.getText().toString().trim(),mPossword.getText().toString().trim());
                    }
                })
                .setNegativeButton("cancle",null);
        return builder.create();

    }

}
同样也是继承DialogFragment ,但是这次是重写了其onCreateDialog() 返回一个Dialog用于展示; 先new一个builder出来,参数同样是传入getActivity();
而这里用LayoutInflator打了一个布局出来, 我第二个参数传入的是null,下面是布局文件的写法


当点击按钮回调点击事件, 将Activity强转为我们定义的接口,并且调用接口中的方法,传入用户在Dialog中输入的username和password;  

同时在主页面我们实现了这个LoginInputListener的接口,  重写方法, 则在Activity就能得到并打印 用户用户输入的值了


至此,两个DialogFragment实现完毕







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值