您的位置:首页 > 其它

使用DialogFragment

2016-07-19 11:15 369 查看
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
例如
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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: