上线项目功能抽取,在项目开发中,咱们会在许多地方会用到底部自定义弹窗,好比设置:我的帐户退出,切换,照片的拍照或者相册的调出,或者一些底部弹出列表,本文对自定义底部弹出窗-dialog,作个开发记录,但愿对读者有所帮助.java
本文实现的抽取的代码实例:安卓两种底部弹出窗dialog实现方式,一种是列表弹窗实现,2是灵活底部弹窗,传入布局以及控件idandroid
实现方式一:
web
实现方式二:编程
两种dialog实现方式的调用服务器
package com.kx.kxbottomdialog; import android.content.Context; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.widget.AdapterView; import java.util.ArrayList; import java.util.List; public class MainActivity extends AppCompatActivity implements View.OnClickListener { private Context mContext; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); init(); } private void init() { mContext = this; findViewById(R.id.bt1).setOnClickListener(this); findViewById(R.id.bt2).setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.bt1: bt1ListView(); break; case R.id.bt2://退出登陆 Bt2Loginout(); break; } } /** * 底部列表弹窗 */ private void bt1ListView() { List<String> names = new ArrayList<>(); names.add("随堂测验"); names.add("单元考试"); names.add("期中(末)考试"); showDialog(new BottomCirTraDialog.SelectDialogListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { switch (position) { case 0: //随堂测验 showToast("随堂测验"); break; case 1://单元考试 showToast("单元考试"); break; case 2://期中(末)考试 showToast("期中(末)考试"); break; default: break; } } }, names); } private BottomCirTraDialog showDialog(BottomCirTraDialog.SelectDialogListener listener, List<String> names) { BottomCirTraDialog dialog = new BottomCirTraDialog(this, R.style.transparentFrameWindowStyle, listener, names); if (!this.isFinishing()) { dialog.show(); } return dialog; } /** * 退出登陆 * 传入布局实现 */ private void Bt2Loginout() { BottomDialog dialog = new BottomDialog(mContext, R.layout.dialog_login_out, new int[]{R.id.tv_choice_out, R.id.tv_cancel}); dialog.show(); dialog.setOnBottomItemClickListener(new BottomDialog.OnBottomItemClickListener() { @Override public void onBottomItemClick(BottomDialog dialog, View view) { switch (view.getId()) { case R.id.tv_choice_out: //退出登陆 //服务器登出 mCenterPI.logout(); dialog.cancel(); break; case R.id.tv_cancel: //取消 dialog.cancel(); break; } } }); } /** * Toast * * @param s */ public void showToast(String s) { ToastUtil.toast(this, s); } }
简单的两个按钮控件app
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="com.kx.kxbottomdialog.MainActivity"> <TextView android:padding="10dp" android:textColor="#000" android:gravity="center_horizontal" android:text="自定义底部弹窗" android:layout_width="match_parent" android:layout_height="wrap_content"/> <Button android:text="列表弹窗" android:id="@+id/bt1" android:layout_width="match_parent" android:layout_height="wrap_content"/> <Button android:text="传入布局" android:id="@+id/bt2" android:layout_width="match_parent" android:layout_height="wrap_content"/> </LinearLayout>
package com.kx.kxbottomdialog; import android.app.Activity; import android.app.Dialog; import android.content.Context; import android.os.Bundle; import android.support.annotation.NonNull; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.Window; import android.view.WindowManager; import android.widget.AdapterView; import android.widget.BaseAdapter; import android.widget.Button; import android.widget.ListView; import android.widget.TextView; import java.util.List; /** * @ 建立: kx * @ 时间: 2018/10/22 * @ 描述: */ public class BottomCirTraDialog extends Dialog implements AdapterView.OnItemClickListener { private List<String> mList; private SelectDialogListener mListener; private Activity mActivity; private boolean mUseCustomColor = false; private int mFirstItemColor; private int mOtherItemColor; private Button mBtnCancel; public BottomCirTraDialog(@NonNull Context context) { super(context); } public BottomCirTraDialog(Activity activity, int theme, SelectDialogListener listener, List<String> names) { super(activity, theme); mActivity = activity; mListener = listener; mList = names; //点击Dialog外部消失 setCanceledOnTouchOutside(true); } public interface SelectDialogListener { void onItemClick(AdapterView<?> parent, View view, int position, long id); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); View view = getLayoutInflater().inflate(R.layout.dialog_exam_type, null); setContentView(view, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)); Window window = getWindow(); //设置动画 window.setWindowAnimations(R.style.main_menu_animstyle); WindowManager.LayoutParams attributes = window.getAttributes(); attributes.x = 0; attributes.y = mActivity.getWindowManager().getDefaultDisplay().getHeight(); //保证按钮水平满屏 attributes.width = ViewGroup.LayoutParams.MATCH_PARENT; attributes.height = ViewGroup.LayoutParams.WRAP_CONTENT; //设置显示位置 onWindowAttributesChanged(attributes); initView(); } private void initView() { DialogAdapter dialogAdapter = new DialogAdapter(mList); ListView listView = findViewById(R.id.dialog_list); mBtnCancel = (Button) findViewById(R.id.btn_cancel); listView.setOnItemClickListener(this); listView.setAdapter(dialogAdapter); mBtnCancel.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if(mCancelListener != null){ mCancelListener.onCancelClick(v); } dismiss(); } }); } @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { mListener.onItemClick(parent, view, position, id); dismiss(); } private class DialogAdapter extends BaseAdapter { private List<String> mStrings; private Viewholder viewholder; private LayoutInflater layoutInflater; public DialogAdapter(List<String> strings) { this.mStrings = strings; this.layoutInflater = mActivity.getLayoutInflater(); } @Override public int getCount() { return mStrings.size(); } @Override public Object getItem(int position) { return mStrings.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { if (null == convertView) { viewholder = new Viewholder(); convertView = layoutInflater.inflate(R.layout.view_dialog_item, null); viewholder.dialogItemButton = (TextView) convertView.findViewById(R.id.dialog_item_bt); convertView.setTag(viewholder); } else { viewholder = (Viewholder) convertView.getTag(); } viewholder.dialogItemButton.setText(mStrings.get(position)); if (!mUseCustomColor) { mFirstItemColor = mActivity.getResources().getColor(R.color.color_0073FF); mOtherItemColor = mActivity.getResources().getColor(R.color.color_0073FF); } //根据数量 设置圆角 数量为1,其余上下,剩余中 if (1 == mStrings.size()) { viewholder.dialogItemButton.setTextColor(mFirstItemColor); viewholder.dialogItemButton.setBackgroundResource(R.drawable.dialog_item_bg_only); } else if (position == 0) { viewholder.dialogItemButton.setTextColor(mFirstItemColor); viewholder.dialogItemButton.setBackgroundResource(R.drawable.select_dialog_item_bg_top); } else if (position == mStrings.size() - 1) { viewholder.dialogItemButton.setTextColor(mOtherItemColor); viewholder.dialogItemButton.setBackgroundResource(R.drawable.select_dialog_item_bg_buttom); } else { viewholder.dialogItemButton.setTextColor(mOtherItemColor); viewholder.dialogItemButton.setBackgroundResource(R.drawable.select_dialog_item_bg_center); } return convertView; } } public static class Viewholder { public TextView dialogItemButton; } /** * 取消事件监听接口 * */ private SelectDialogCancelListener mCancelListener; public interface SelectDialogCancelListener { void onCancelClick(View v); } }
package com.kx.kxbottomdialog; import android.app.Dialog; import android.content.Context; import android.os.Bundle; import android.view.Gravity; import android.view.View; import android.view.Window; import android.view.WindowManager; /** * @ 建立: kx * @ 时间: 2018/10/22 * @ 描述: */ public class BottomDialog extends Dialog implements View.OnClickListener { private Context context; private int layoutRes; private View view; private int[] clickIds; //须要设置点击事件的ID.须要其余ID,在dialog实例化后在dialog上fbc. public BottomDialog(Context context, int layoutRes, int[] clickIds) { super(context, R.style.dialog_full); //设置主题 this.context = context; this.layoutRes = layoutRes; this.clickIds = clickIds; } public BottomDialog(Context context, View view, int[] clickIds) { super(context, R.style.dialog_full); //设置主题 this.context = context; this.view = view; this.clickIds = clickIds; } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Window window = getWindow(); //底部弹出的Dialog window.setGravity(Gravity.BOTTOM); //底部弹出的动画 window.setWindowAnimations(R.style.DialogBottomAnimation); if(view != null) { setContentView(view); }else{ setContentView(layoutRes); } getWindow().setLayout(WindowManager.LayoutParams.MATCH_PARENT,WindowManager.LayoutParams.MATCH_PARENT); //点击Dialog外部消失 setCanceledOnTouchOutside(true); //禁用返回键 setCancelable(true); //设置点击事件 if (clickIds != null) { for (int id : clickIds) { findViewById(id).setOnClickListener(this); } } } public View getView() { if (view == null) { return getLayoutInflater().inflate(layoutRes, null); } return view; } private OnBottomItemClickListener listener; public interface OnBottomItemClickListener { void onBottomItemClick(BottomDialog dialog, View view); } public void setOnBottomItemClickListener(OnBottomItemClickListener listener) { this.listener = listener; } @Override public void onClick(View v) { listener.onBottomItemClick(this, v); } }
<resources> <!-- Base application theme. --> <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> <!-- Customize your theme here. --> <item name="colorPrimary">@color/colorPrimary</item> <item name="colorPrimaryDark">@color/colorPrimaryDark</item> <item name="colorAccent">@color/colorAccent</item> </style> <style name="transparentFrameWindowStyle" parent="android:style/Theme.Dialog"> <item name="android:windowBackground">@drawable/photo_choose_bg</item> </style> <style name="main_menu_animstyle"> <item name="android:windowEnterAnimation">@anim/photo_dialog_in_anim</item> <item name="android:windowExitAnimation">@anim/photo_dialog_out_anim</item> </style> <!--自定义Dialog弹出的全屏样式,不要继承系统Dialog的样式会出现抖动的状况--> <style name="dialog_full"> <item name="android:windowIsFloating">true</item> <!--是否悬浮在界面上--> <item name="android:windowIsTranslucent">true</item> <!--是否半透明--> <item name="android:windowNoTitle">true</item> <!--是否有标题--> <item name="android:windowBackground">@android:color/transparent</item> <!--窗口背景色透明--> <item name="android:backgroundDimEnabled">true</item> <!--背景是否模糊显示--> </style> <!--自定义Dialog的底部弹出的动画,直接从中间弹出的不加动画--> <style name="DialogBottomAnimation" parent="android:Animation"> <item name="android:windowEnterAnimation">@anim/dialog_bottom_enter</item> <item name="android:windowExitAnimation">@anim/dialog_bottom_exit</item> </style> </resources>
photo_dialog_in_animide
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" > <translate android:duration="200" android:fromXDelta="0" android:fromYDelta="1000" android:toXDelta="0" android:toYDelta="0" /> </set>
photo_dialog_out_anim.xmlsvg
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" > <translate android:duration="300" android:fromXDelta="0" android:fromYDelta="0" android:toXDelta="0" android:toYDelta="1000" /> </set>
为本身技术增值,量变引发质变.对象亦来源于生活,模式亦来源于验证的OO经验,那么请学会使用轮子,再到感觉制造轮子的乐趣,你会发现原来编程那么美妙.若有错误或不当之处,请读者留言,博主好吸收经验,互相交流学习,对你有帮助请点赞,粉一波哦布局