1、简单介绍
本篇主要介绍如何通过自定义Dialog实现Dialog从底部弹出然后从底部退出,话不多说,如下图所示。
2、代码实现
2.1 动画准备
动画的弹入弹出,主要采用的是android提供的translate动画。在项目的res文件夹下创建anim文件夹,添加如下两个文件。
1、dialog_enter.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="400"
android:fromYDelta="100%p" />
</set>
2、dialog_exit.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="400"
android:toYDelta="100%p" />
</set>
接下来在styles.xml文件中添加动画样式:
<style name="DialogAnimation" parent="android:Animation">
<item name="@android:windowEnterAnimation">@anim/dialog_enter</item>
<item name="@android:windowExitAnimation">@anim/dialog_exit</item>
</style>
准备好动画样式后,开始着手准备自定义Dialog了。
2.2 Dialog的实现
2.2.1 对于Dialog,我们需要准备一个Dialog的样式
<style name="DialogStyle">
<!--是否去除边框-->
<item name="android:windowFrame">@null</item>
<!--是否去除标题 -->
<item name="android:windowNoTitle">true</item>
<!--半透明-->
<item name="android:windowIsTranslucent">false</item>
<!--是否浮现在activity之上-->
<item name="android:windowIsFloating">true</item>
<!--背景颜色及和透明程度-->
<item name="android:windowBackground"> @android:color/transparent </item>
<item name="android:windowContentOverlay">@null</item>
</style>
2.2.2 自定义MyDialog
MyDialog中加载一个布局,布局文件中包含一个RecyclerView和一个TextView,布局文件如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="#ffffff">
<android.support.v7.widget.RecyclerView
android:id="@+id/rv_catalog_filter"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="10dp"
android:paddingBottom="10dp">
</android.support.v7.widget.RecyclerView>
<View
android:layout_width="match_parent"
android:layout_height="0.1dp"
android:background="#b8b8b7"/>
<TextView
android:id="@+id/tv_cancel"
android:layout_width="match_parent"
android:layout_height="46dp"
android:background="#ffffff"
android:gravity="center"
android:text="取消"
android:textSize="18sp"
android:textColor="#333333"/>
</LinearLayout>
下面看看 MyDialog的具体实现:
public class MyDialog extends Dialog {
private View mRootView;
private TextView tvCancel;
private RecyclerView rvCatalogFilter;
private List<String> mDatas;
private RvDialogSelectAdapter mAdapter;
private int mScreenWidth;
public MyDialog(@NonNull Context context,int screenWidth) {
this(context, R.style.DialogStyle, screenWidth);
}
public MyDialog(@NonNull Context context, @StyleRes int themeResId, int screenWidth) {
super(context, themeResId);
this.mScreenWidth = screenWidth;
init();
}
private void init(){
initData();
initDialog();
initView();
bindListenr();
}
private void initData(){
mDatas = new ArrayList<>();
for(int i=0; i<6; i++){
mDatas.add("按钮 "+i);
}
}
private void initDialog(){
Window dialogWindow = this.getWindow();
dialogWindow.setGravity(Gravity.BOTTOM);// 显示在底部
dialogWindow.setWindowAnimations(R.style.DialogAnimation); // 添加动画
this.mRootView = getLayoutInflater().inflate(R.layout.dialog_catalog_filter, null);
this.setContentView(this.mRootView);
this.setCancelable(true);
this.setCanceledOnTouchOutside(true);
WindowManager.LayoutParams lp = this.getWindow().getAttributes();
lp.width = this.mScreenWidth; //设置宽度
this.getWindow().setAttributes(lp);
}
private void initView(){
this.tvCancel = (TextView) this.mRootView.findViewById(R.id.tv_cancel);
this.rvCatalogFilter = (RecyclerView) this.mRootView.findViewById(R.id.rv_catalog_filter);
this.rvCatalogFilter.setLayoutManager(new GridLayoutManager(getContext(), 2));
this.mAdapter = new RvDialogSelectAdapter(getContext(), mDatas);
this.rvCatalogFilter.setAdapter(mAdapter);
}
private void bindListenr(){
this.tvCancel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dismiss();
}
});
this.mAdapter.setOnItemClickListener(new RvDialogSelectAdapter.OnItemClickListener() {
@Override
public void onItemClick(int position) {
Toast.makeText(getContext(), mDatas.get(position), Toast.LENGTH_SHORT).show();
dismiss();
}
});
}
}
将RecyclerView与RvDialogSelectAdapter进行数据绑定,下面看看RvDialogSelectAdapter代码实现:
public class RvDialogSelectAdapter extends RecyclerView.Adapter<RvDialogSelectAdapter.ViewHolder>{
private LayoutInflater mLayoutInflater;
private Context mContext;
private List<String> mDatas;
public RvDialogSelectAdapter(Context mContext, List<String> datas) {
this.mContext = mContext;
this.mLayoutInflater = LayoutInflater.from(mContext);
this.mDatas = datas;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(this.mContext).inflate(R.layout.item_dialog_select , parent , false);
ViewHolder viewHolder = new ViewHolder(view);
return viewHolder;
}
@Override
public void onBindViewHolder(ViewHolder holder, final int position) {
holder.tvFilterName.setText(mDatas.get(position));
holder.tvFilterName.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(onItemClickListener != null){
onItemClickListener.onItemClick(position);
}
}
});
}
@Override
public int getItemCount() {
return (mDatas == null) ? 0:mDatas.size() ;
}
class ViewHolder extends RecyclerView.ViewHolder{
TextView tvFilterName;
public ViewHolder(View itemView) {
super(itemView);
initView(itemView);
}
private void initView(View view){
tvFilterName = (TextView) itemView.findViewById(R.id.tv_filter_name);
}
}
private OnItemClickListener onItemClickListener;
public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
this.onItemClickListener = onItemClickListener;
}
public interface OnItemClickListener{
void onItemClick(int position);
}
}
item_dialog_select.xml布局文件:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="60dp"
android:orientation="vertical"
android:padding="10dp"
android:background="#ffffff">
<TextView
android:id="@+id/tv_filter_name"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:text="aa"
android:background="@drawable/layout_frame_corner_circle"
android:textSize="14sp"
android:textColor="#666666"/>
</LinearLayout>
layout_frame_corner_circle.xml 文件,改文件主要实现当按下按钮时颜色设置问题。
<?xml version="1.0" encoding="utf-8"?>
<!-- 实现功能: 下边为圆角 按下时颜色加深 -->
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:state_enabled="true" android:state_pressed="true">
<shape >
<!-- 内部填充颜色 -->
<solid android:color="#f5f5f5" />
<!-- 圆角 -->
<corners
android:radius="5dp" />
<!-- 边框颜色 -->
<stroke
android:width="0.01dp"
android:color="#b8b8b7" />
</shape>
</item>
<item android:state_enabled="true" android:state_pressed="false">
<shape >
<!-- 内部填充颜色 -->
<solid android:color="#ffffff" />
<!-- 圆角 -->
<corners
android:radius="5dp"
/>
<!-- 边框颜色 -->
<stroke
android:width="0.01dp"
android:color="#b8b8b7" />
</shape>
</item>
</selector>
完成如上代码,算大功告成了。。。。
MyDialog实现完成了,那么外部如何调用呢?
3、外部使用
private MyDialog myDialog;
private void showDialog(){
if(myDialog == null){
WindowManager windowManager = getWindowManager();
Display display = windowManager.getDefaultDisplay();
myDialog = new MyDialog(this, display.getWidth());
}
myDialog.show();
}