DialogFragment实现底部弹窗布局
引言
通过DialogFragment能够非常优雅和简洁的实现底部弹窗功能. 虽然底部弹窗与普通的Dialog不同,它的布局需要紧贴页面的下部,但本质上仍属于Fragment布局,通过继承DialogFragment类,实现不同接口,即可定制不同样式的Fragment. 除了设计不同的布局之外,还需要考虑Fragment的主题样式(Theme Style),去完美的实现底部弹窗效果.
在MainActivity中,通过按钮调起弹窗
由于底部弹窗BottomDialogFragment本质仍属于Fragment, 因此需要依赖FragmentManager进行展示. 调用DialogFragment的show()方法即可显示Dialog.
import android.os.Bundle;
import android.support.v4.app.FragmentManager;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.btn).setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v) {
FragmentManager fm = getSupportFragmentManager();
BottomDialogFragment editNameDialog = new BottomDialogFragment();
editNameDialog.show(fm, "fragment_bottom_dialog");
}
});
}
}
设置底部弹窗BottomDialogFragment类的样式,属性及布局
底部弹窗BottomDialogFragment类继承DialogFragment类, 需要覆写onCreateDialog()方法,创建Dialog类. onCreateDialog()是DialogFragment的入口方法,类似Activity的OnCreate()方法.
@NonNull @Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
// 使用不带Theme的构造器, 获得的dialog边框距离屏幕仍有几毫米的缝隙。
Dialog dialog = new Dialog(getActivity(), R.style.BottomDialog);
// 在设置Content前, 设置Dialog的窗口属性(Window),不含标题,即Window.FEATURE_NO_TITLE
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
// 设置Dialog布局
dialog.setContentView(R.layout.fragment_bottom);
// 外部点击取消
dialog.setCanceledOnTouchOutside(true);
// 设置宽度为屏宽, 靠近屏幕底部。
Window window = dialog.getWindow();
WindowManager.LayoutParams lp = window.getAttributes();
lp.gravity = Gravity.BOTTOM; // 重置Dialog的窗口布局,中心为紧贴底部
lp.width = WindowManager.LayoutParams.MATCH_PARENT; // 宽度为屏幕宽度
window.setAttributes(lp);
// 注册ButterKnife,若没集成可注掉
ButterKnife.bind(this, dialog); // Dialog即View
initClickTypes();
return dialog;
}
其中需要自定义Dialog的样式,定义在res/style.xml中
<style name="BottomDialog" parent="@style/AppTheme">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">wrap_content</item>
<!--Dialog悬浮于窗口之上,即属性值true-->
<item name="android:windowIsFloating">true</item>
<!--Dialog背景设置为透明,取消暗色,即属性值false-->
<item name="android:backgroundDimEnabled">false</item>
</style>
至于BottomDialogFragment的布局,这里就不贴了. 以及BottomDialogFragment里面的逻辑也自行查看代码吧.