使用DialogFragment至少需要实现onCreateView或者onCreateDIalog方法。onCreateView即使用定义的xml布局文件展示Dialog。onCreateDialog即利用AlertDialog或者Dialog创建出Dialog。
3、 重写onCreateView创建Dialoga)布局文件,我们创建一个设置名称的布局文件:
- package com.example.zhy_dialogfragment;
- import android.app.DialogFragment;
- import android.os.Bundle;
- import android.view.LayoutInflater;
- import android.view.View;
- import android.view.ViewGroup;
- public class EditNameDialogFragment extends DialogFragment
- {
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container,
- Bundle savedInstanceState)
- {
- View view = inflater.inflate(R.layout.fragment_edit_name, container);
- return view;
- }
- }
Main方法中调用:
- public void showEditDialog(View view)
- {
- EditNameDialogFragment editNameDialog = new EditNameDialogFragment();
- editNameDialog.show(getFragmentManager(), "EditNameDialog");
- }
- public class EditNameDialogFragment extends DialogFragment
- {
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container,
- Bundle savedInstanceState)
- {
- getDialog().requestWindowFeature(Window.FEATURE_NO_TITLE);
- View view = inflater.inflate(R.layout.fragment_edit_name, container);
- return view;
- }
- }
a)布局文件
- package com.example.zhy_dialogfragment;
- import android.app.AlertDialog;
- import android.app.Dialog;
- import android.app.DialogFragment;
- import android.content.DialogInterface;
- import android.os.Bundle;
- import android.view.LayoutInflater;
- import android.view.View;
- import android.view.ViewGroup;
- import android.widget.EditText;
- public class LoginDialogFragment extends DialogFragment
- {
- @Override
- public Dialog onCreateDialog(Bundle savedInstanceState)
- {
- AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
- // Get the layout inflater
- LayoutInflater inflater = getActivity().getLayoutInflater();
- View view = inflater.inflate(R.layout.fragment_login_dialog, null);
- // Inflate and set the layout for the dialog
- // Pass null as the parent view because its going in the dialog layout
- builder.setView(view)
- // Add action buttons
- .setPositiveButton("Sign in",
- new DialogInterface.OnClickListener()
- {
- @Override
- public void onClick(DialogInterface dialog, int id)
- {
- }
- }).setNegativeButton("Cancel", null);
- return builder.create();
- }
- }
- public void showLoginDialog(View view)
- {
- LoginDialogFragment dialog = new LoginDialogFragment();
- dialog.show(getFragmentManager(), "loginDialog");
- }
可以看到通过重写onCreateDialog同样可以实现创建对话框,效果还是很nice的。
5、传递数据给Activity从dialog传递数据给Activity,可以使用“fragment interface pattern”的方式,下面通过一个改造上面的登录框来展示这种模式。
改动比较小,直接贴代码了:
- package com.example.zhy_dialogfragment;
- import android.app.AlertDialog;
- import android.app.Dialog;
- import android.app.DialogFragment;
- import android.content.DialogInterface;
- import android.os.Bundle;
- import android.view.LayoutInflater;
- import android.view.View;
- import android.view.ViewGroup;
- import android.widget.EditText;
- public class LoginDialogFragment extends DialogFragment
- {
- private EditText mUsername;
- private EditText mPassword;
- public interface LoginInputListener
- {
- void onLoginInputComplete(String username, String password);
- }
- @Override
- public Dialog onCreateDialog(Bundle savedInstanceState)
- {
- AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
- // Get the layout inflater
- LayoutInflater inflater = getActivity().getLayoutInflater();
- View view = inflater.inflate(R.layout.fragment_login_dialog, null);
- mUsername = (EditText) view.findViewById(R.id.id_txt_username);
- mPassword = (EditText) view.findViewById(R.id.id_txt_password);
- // Inflate and set the layout for the dialog
- // Pass null as the parent view because its going in the dialog layout
- builder.setView(view)
- // Add action buttons
- .setPositiveButton("Sign in",
- new DialogInterface.OnClickListener()
- {
- @Override
- public void onClick(DialogInterface dialog, int id)
- {
- LoginInputListener listener = (LoginInputListener) getActivity();
- listener.onLoginInputComplete(mUsername
- .getText().toString(), mPassword
- .getText().toString());
- }
- }).setNegativeButton("Cancel", null);
- return builder.create();
- }
- }
MainActivity中需要实现我们的接口LoginInputListener,实现我们的方法,就可以实现当用户点击登陆时,获得我们的帐号密码了:
- c) MainActivity
- package com.example.zhy_dialogfragment;
- import com.example.zhy_dialogfragment.LoginDialogFragment.LoginInputListener;
- import android.app.Activity;
- import android.app.AlertDialog;
- import android.content.DialogInterface;
- import android.os.Bundle;
- import android.view.LayoutInflater;
- import android.view.View;
- import android.widget.Toast;
- public class MainActivity extends Activity implements LoginInputListener
- {
- @Override
- protected void onCreate(Bundle savedInstanceState)
- {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- }
- public void showLoginDialog(View view)
- {
- LoginDialogFragment dialog = new LoginDialogFragment();
- dialog.show(getFragmentManager(), "loginDialog");
- }
- @Override
- public void onLoginInputComplete(String username, String password)
- {
- Toast.makeText(this, "帐号:" + username + ", 密码 :" + password,
- Toast.LENGTH_SHORT).show();
- }
- }
我们希望,一个对话框在大屏幕上以对话框的形式展示,而小屏幕上则直接嵌入当前的Actvity中。这种效果的对话框,只能通过重写onCreateView实现。下面我们利用上面的EditNameDialogFragment来显示。
EditNameDialogFragment我们已经编写好了,直接在MainActivity中写调用
- public void showDialogInDifferentScreen(View view)
- {
- FragmentManager fragmentManager = getFragmentManager();
- EditNameDialogFragment newFragment = new EditNameDialogFragment();
- boolean mIsLargeLayout = getResources().getBoolean(R.bool.large_layout) ;
- Log.e("TAG", mIsLargeLayout+"");
- if (mIsLargeLayout )
- {
- // The device is using a large layout, so show the fragment as a
- // dialog
- newFragment.show(fragmentManager, "dialog");
- } else
- {
- // The device is smaller, so show the fragment fullscreen
- FragmentTransaction transaction = fragmentManager
- .beginTransaction();
- // For a little polish, specify a transition animation
- transaction
- .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
- // To make it fullscreen, use the 'content' root view as the
- // container
- // for the fragment, which is always the root view for the activity
- transaction.replace(R.id.id_ly, newFragment)
- .commit();
- }
- }
这个R.bool.large_layout是我们定义的资源文件:
在默认的values下新建一个bools.xml
- false
- true
左边为模拟器,右边为我的手机~~~~~
7、屏幕旋转当用户输入帐号密码时,忽然旋转了一下屏幕,帐号密码不见了~~~是不是会抓狂
传统的new AlertDialog在屏幕旋转时,第一不会保存用户输入的值,第二还会报异常,因为Activity销毁前不允许对话框未关闭。而通过DialogFragment实现的对话框则可以完全不必考虑旋转的问题。
我们直接把上面登录使用AlertDialog创建的登录框,拷贝到MainActivity中直接调用:
- public void showLoginDialogWithoutFragment(View view)
- {
- AlertDialog.Builder builder = new AlertDialog.Builder(this);
- // Get the layout inflater
- LayoutInflater inflater = this.getLayoutInflater();
- // Inflate and set the layout for the dialog
- // Pass null as the parent view because its going in the dialog layout
- builder.setView(inflater.inflate(R.layout.fragment_login_dialog, null))
- // Add action buttons
- .setPositiveButton("Sign in",
- new DialogInterface.OnClickListener()
- {
- @Override
- public void onClick(DialogInterface dialog, int id)
- {
- // sign in the user ...
- }
- }).setNegativeButton("Cancel", null).show();
- }
可以看到,传统的Dialog旋转屏幕时就消失了,且后台log会报异常~~~使用DialogFragment则不受影响。
好了,关于DialogFragment的介绍结束~~~~
有任何疑问请留言
源码点击下载