使用DialogFragment
2016-07-19 11:15
369 查看
DialogFagmet是一个特殊的碎片经常被用作在活动中展示叠加的窗口,在其他内容之上。
经常被用作展示警告对话框,确认对话框,或者为了在同一个页面来提示信息。
DialogFragment现在是一种常见的做法,而之间使用Dialog被认为不正确。
* 注意:所有的方法要求使用v4的包,而不是
然后开始定义碎片本身:
在主活动中展示:
- 定义一个包含传递数据给活动的方法的接口
- 建立一个view事件调用自定义的监听器通过方法传递数据
- 通过定义事件的触发条件在活动中实现接口
在主活动中重写在接口中定义的方法:
使用第三方库:
https://github.com/afollestad/material-dialogs
https://github.com/fengdai/AlertDialogPro/
https://github.com/drakeet/MaterialDialog
经常被用作展示警告对话框,确认对话框,或者为了在同一个页面来提示信息。
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例如
dialogTheme和
alertDialogTheme如下所示
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
相关文章推荐
- spring 注解
- JAVA ActiveMQ
- Java @Deprecated注解的作用及传递性
- Quartz CronExpression表达式
- Web API应用架构设计分析(2)
- Tomcat 7 WEB-XML 报错 “:”
- spring 防sql注入
- No module named pyspark
- object与class的区别
- App测试中ios和Android的区别
- php 分页 (一页一页的查询,提高相对情况下的查询速度)
- JDBC中execute、executeQuery和executeUpdate的小结
- 插入排序的改进版本(二分查找)
- Meta http-equiv属性详解(转)
- iOS 关于适配
- MySQL索引原理及慢查询优化 美团
- Web API应用架构设计分析(1)
- javaweb回顾第四篇Servlet异常处理
- addViewController之后view里面的点击事件不响应
- 把Java程序打包成jar文件包并执行