前言
这几天都在学习Web端的技术点,对于Android这么好玩的技术,那么也不能丢落。时间挤一挤,说不定还能挤出一条沟,呵呵..这几天看到小伙伴们在项目中在为dialog相关的问题不知所措,看了大概的需求,都涉及到自定义dialog,其实也蛮简单的,在日常开发中遇到自定义dialog的需求还是蛮多的,所以挤点时间出来练练手先.
Ⅰ.简述
看看小伙伴的效果图
效果图1
效果图2
看上面的效果图,应该不是很难吧,Android系统提供的dialog往往都不满足产品的需求,所以就需要自定义了,那么先简单说说怎么实现的吧!主要就是继承dialog类,然后给其设置布局,再进行点击事件的回调等等
Ⅱ.自定义Dialog实现
以上面图1为效果图,首页先来个布局,那么下面简单看下布局吧
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<RelativeLayout
android:id="@+id/container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true">
<TextView
android:id="@+id/bg"
android:layout_width="250dp"
android:layout_height="160dp"
android:background="#c9f4fe"
android:layout_below="@+id/iv_success"
android:text="成功领取优惠劵"
android:gravity="bottom|center"
android:textColor="#0096ff"
android:textSize="16sp"/>
<ImageView
android:id="@+id/iv_success"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/receive_success"
android:layout_centerInParent="true"/>
</RelativeLayout>
<Button
android:id="@+id/btn_cancel"
android:layout_width="30dp"
android:layout_height="30dp"
android:background="@drawable/receive_success_close"
android:layout_alignRight="@id/container"
android:layout_marginTop="150dp" />
<Button
android:id="@+id/share"
android:layout_width="250dp"
android:layout_height="60dp"
android:background="#0096ff"
android:layout_below="@id/container"
android:layout_centerHorizontal="true"
android:text="立即分享"
android:textSize="18sp"
android:textColor="#ffffff"/>
</RelativeLayout>
本来接着是要继承dialog并给其设置上面的布局,但是考虑到项目中对dialog弹窗的使用频率还是挺高的,所以简单抽取dialog,以抽象类的方式提供给其他dialog去继承,那么下面看看抽取的BaseDialog的代码:
/**
* Created by wyk on 2016/12/28.
*/
public abstract class BaseDialog extends Dialog implements View.OnClickListener{
public Context mContext;
public BaseDialog(Context context){
super(context);
this.mContext = context;
initView();
}
public BaseDialog(Context context, int themeResId){
super(context,themeResId);
this.mContext = context;
initView();
}
public abstract void initView();
public abstract void onDialogClick(View v);
/** 查找子控件,省强转 */
public <T> T findView(int id) {
T view = (T) findViewById(id);
return view;
}
public void showToast(String text) { //Toast
//tell user
}
@Override
public void onClick(View v) { //点击事件
onDialogClick(v);
}
}
接着就来实现自定义的dialog,自定义的dialog继承自BaseDialog,看下面代码:
/**
* Created by wyk on 2016/12/28.
*/
public class MyDialog extends BaseDialog{
//dialog对应布局上的点击事件,该接口进行回调
private OnCallResult mOnCallResult;
private Button mBtnCancel;
private Button mBtnShare;
public MyDialog(Context context) {
super(context);
initDate();
initListener();
}
/** 设置事件的回调接口*/
public void setCallBackListen(OnCallResult onCallResult){
mOnCallResult = onCallResult;
}
/**该方法提供于操作布局控件*/
@Override
public void initView() {
Window window = getWindow();
window.requestFeature(Window.FEATURE_NO_TITLE);
window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
setContentView(R.layout.page_dialog);
WindowManager.LayoutParams params = window.getAttributes();
params.gravity = Gravity.CENTER;
//这里是设置dialog弹出、隐藏的动画效果
//params.windowAnimations = R.style.MyDialogAnimation;
mBtnCancel = findView(R.id.btn_cancel);
mBtnShare = findView(R.id.share);
}
/**该方法提供于操作数据*/
public void initDate() {
}
/**该方法提供于设置监听事件*/
public void initListener() {
mBtnCancel.setOnClickListener(this);
mBtnShare.setOnClickListener(this);
}
/**布局的监听函数*/
@Override
public void onDialogClick(View v) {
if(mOnCallResult!=null){
switch (v.getId()) {
case R.id.btn_cancel: //取消监听
// MyDialog.this.cancel();
mOnCallResult.onCancel();
break;
case R.id.share: //分享监听
mOnCallResult.onShare();
break;
default:
break;
}
}
}
}
上面代码的OnCallResult对象,注释是回调的接口,可是OnCallResult长怎样的呢??看下面代码
/**
* Created by WYK on 2016/12/28.
*/
public interface OnCallResult {
void onCancel();
void onShare();
}
Ⅲ.效果展示
上面的代码逻辑应该还是比较清晰的,都做了注释说明,力求做到简单易懂,接着使用上面自定义的MyDialog,看看效果如何。为了实现方便,就在MainActivity的布局上添加一个按钮,点击该按钮弹出MyDialog,然后可点击取消dialog等,看代码:
/**
* Created by wyk on 2016/12/28.
*/
public class MainActivity extends AppCompatActivity {
private Button mShowDialog;
private MyDialog mDialog;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
initListener();
}
/**该方法提供于操作布局控件*/
private void initView() {
mShowDialog = (Button) findViewById(R.id.btn_show_dialog);
mDialog = new MyDialog(this);
}
/**该方法提供于设置监听事件*/
private void initListener() {
mDialog.setCallBackListen(new OnCallResult() {
@Override
public void onCancel() {
mDialog.cancel();
}
@Override
public void onShare() {
Toast.makeText(MainActivity.this, "Share Success!!!", Toast.LENGTH_SHORT).show();
mDialog.show();
}
});
mShowDialog.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mDialog.show();
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
if(mDialog!=null){ //防止突发状态造成 窗体泄露
mDialog.cancel();
mDialog = null;
}
}
}
下面是MainActivity的布局,顺便也贴上
<!--activity_main布局-->
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.wyk.dialogtest.MainActivity">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="show dialog"
android:id="@+id/btn_show_dialog"
android:layout_centerHorizontal="true"
android:layout_marginTop="173dp" />
</RelativeLayout>
上面的操作基本可以展示MyDialog,也可以点击取消/点击进行分享(分享代码略),布局和代码都很简单吧,也没什么逻辑,就这样完成了,是不是挺So easy 的。在项目开发中,dialog的坑还是蛮多的,比如上面MainActivity标识出来的窗体泄露,找时间再写篇文章总结下遇到的坑。还有1点没说的,应该看到上面的BaseDialog里的 “params.windowAnimations = R.style.MyDialogAnimation; “这一行注释的代码吧,这个是设置Dialog弹出、隐藏的动画效果,之前有篇文章已经提到,下面是Dialog动画效果那篇文章的地址,这里就不扯了。
Dialog动画效果文章Url:http://blog.csdn.net/yk377657321/article/details/51708385
最后还是来看看上面代码运行的效果图(布局丑死咯~~~怪我了):
Ⅳ.总结
1.在浏览了Dialog的代码,其实针对BaseDialog还可以进一步抽取的,笔者追求实用即可,就不再抽取了
2.针对项目中Dialog的坑,打算之后再写个文章记录下,这就当留个空白吧!
3.2016还剩几天,抓紧时间,别让心长野草了。
扯了这么多,呜呜···还是先撤了。