Android 自定义一个好看的dialog,并实现水波纹特效(兼容低版本)

来源:互联网 发布:mysql.data.dll网盘 编辑:程序博客网 时间:2024/04/27 20:16

今天,我就直奔主题,动手撸一个自定义的dialog,而且点击按钮能够展示水波纹特效(能够兼容5.0以下的版本哦)的控件。记录下来,以便日后能在项目中直接使用!


首先看效果图:



可以看到,点击按钮,显示了一个自定义的dialog,该dialog的样式是目前十分流行的,各大app上几乎都在使用这种风格的dialog。而且,我给dialog的button添加了点击时的水波纹特效,尽管当前我使用的是android 6.0 版本,但为了兼容5.0以下的版本,我也对该效果做了兼容处理,代码其实很简单,不过要注意一些细节。


1,项目的结构:



由项目结构可以看到,代码并不多,主要是一些drawable文件的处理。


2,先看看我们的xml布局文件:


①self_dialog.xml:

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:background="@android:color/transparent">    <LinearLayout        android:layout_width="260dp"        android:layout_height="140dp"        android:layout_centerHorizontal="true"        android:layout_centerVertical="true"        android:background="@drawable/self_dialog_bg"        android:orientation="vertical">        <TextView            android:id="@+id/title"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_gravity="center"            android:layout_margin="20dp"            android:gravity="center"            android:text="提示"            android:textColor="#C71585"            android:textSize="25dp" />        <View            android:layout_width="match_parent"            android:layout_height="1dp"            android:layout_marginTop="15dp"            android:background="#3000" />        <LinearLayout            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:orientation="horizontal">            <Button                android:id="@+id/no"                android:layout_width="0dp"                android:layout_height="match_parent"                android:layout_weight="1"                android:background="@drawable/lbt_ripple"                android:gravity="center"                android:singleLine="true"                android:text="No"                android:textColor="#525252"                android:textSize="20dp" />            <View                android:layout_width="1dp"                android:layout_height="match_parent"                android:background="#3000" />            <Button                android:id="@+id/yes"                android:layout_width="0dp"                android:layout_height="match_parent"                android:layout_weight="1"                android:background="@drawable/rbt_ripple"                android:gravity="center"                android:singleLine="true"                android:text="Yes"                android:textColor="#C71585"                android:textSize="20dp" />        </LinearLayout>    </LinearLayout></RelativeLayout>

着重看含有background属性的控件,LinearLayout节点下的background属性是用来设置我们dialog的背景,而Button的background是用来设置状态选择器即点击效果的。所以,思路就很清晰了,我们只要在drawable里面配置好相应的background属性就能展示出我们想要的效果了。


②Linearlayout的background属性配置:

配置文件为self_dialog_bg.xml

<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android">    <solid android:color="#ffffff" />    <stroke        android:width="0.8dp"        android:color="#ffffff" />    <!-- 圆角 -->    <corners android:radius="12dp" /></shape>

可以看到,我们新建了一个shape节点的xml文件,solid color属性为dialog背景的颜色,这里为白色;stroke为外框线条的属性,我们也设置为白色;corners属性最为关键,是用来设置背景的四个角的圆滑度的,radius的值越大,圆弧的弧度也越大,这里我们设置为12dp,预览效果:



③再来设置button的background属性

之前也说过,button的background属性其实就是一个状态选择器。只是在5.0以上的系统我们将这种selector简化了,而且还能自带水波纹效果。先来看看5.0以上的设置方式:


在res目录下新建drawable-v21文件夹,5.0以上的系统会自动识别该文件夹,然后new一个Drawable resource file,注意,这里我们新建一个节点为ripple的xml文件,ripple翻译过来为“涟漪”的意思,顾名思义,就是水波纹效果!要分别对“确定”和“取消”按钮设置不同的水波纹效果,所以需要新建两个xml文件,分别为:lbt_ripple.xml和rbt_ripple.xml。


lbt_ripple.xml:

<?xml version="1.0" encoding="utf-8"?><ripple xmlns:android="http://schemas.android.com/apk/res/android"    android:color="#C71585">    <item android:drawable="@drawable/lbt_ripple_background" /></ripple>


rbt_ripple.xml:

<?xml version="1.0" encoding="utf-8"?><ripple xmlns:android="http://schemas.android.com/apk/res/android"    android:color="#C71585">    <item android:drawable="@drawable/rbt_ripple_background" /></ripple>

配置很简单,设置背景颜色和点击后的颜色,然后就会自带水波纹效果了,是不是很easy?

lbt_ripple_background.xml文件和rbt_ripple_background.xml类似,其实就是设置了不同的背景图片,两个的圆角方向是对称的,以便匹配整体dialog的风格,当然你也可以自定义别的形状。


lbt_ripple_background.xml:

<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android"    android:shape="rectangle">    <corners android:bottomLeftRadius="12dp" />    <solid android:color="#fff" /></shape>
怎么分别设置矩形四个角的圆角弧度呢?上面的coeners属性其实已经给出答案了:

bottomLeftRadius为左下角的圆角弧度,可以推测:bottomRightRadius即为右下角的圆角弧度,topLeftRadius为左上角的圆角弧度,topRightRadius为右上角的圆角弧度。这里设置12dp是为了与dialog的边角弧度保持一致。


④向下兼容:

上文也说过,为了可以兼容5.0以下的系统,水波纹需要做另外的处理,其实也很简单,在drawable目录下放置文件名同样为lbt_ripple.xml和rbt_ripple.xml文件,但是不同的是,这里就不能使用ripple属性了,5.0以下的系统默认是没有该属性的,我们需要做的是,创建一个selector属性的文件:

<?xml version="1.0" encoding="utf-8"?><selector xmlns:android="http://schemas.android.com/apk/res/android">    <item android:color="#C71585" android:state_pressed="true" />    <item android:drawable="@drawable/lbt_ripple_background" /></selector>
说白了其实就是一个状态选择器,就不做过多介绍了。


3,初始化自定义dialog


布局文件我们已经配置好了,接下来是如何使用它。


创建一个类TestAlertDialog继承Dialog:

package com.test.blogdemo;import android.app.Dialog;import android.content.Context;import android.os.Bundle;import android.view.View;import android.widget.Button;import android.widget.TextView;/** * Created by zy_style * 自定义AlertDialog */public class TestAlertDialog extends Dialog {    private Button bt_yes;    private Button bt_no;    private TextView tv_title;    private String title;    private onNoOnclickListener noOnclickListener;    private onYesOnclickListener yesOnclickListener;    public TestAlertDialog(Context context) {        super(context, R.style.SelfDialog);    }    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.self_dialog);        //按空白处不能取消动画        setCanceledOnTouchOutside(false);        //点击鼠标返回键不取消动画        setCancelable(false);        initView();        initData();        //初始化界面控件的事件        initEvent();    }    /**     * 初始化界面的确定和取消监听器     */    private void initEvent() {        //设置确定按钮被点击后,向外界提供监听        bt_yes.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                if (yesOnclickListener != null) {                    yesOnclickListener.onYesClick();                }            }        });        //设置取消按钮被点击后,向外界提供监听        bt_no.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                if (noOnclickListener != null) {                    noOnclickListener.onNoClick();                }            }        });    }    /**     * 初始化界面控件的显示数据     */    private void initData() {        //设置按钮的文字        bt_yes.setText("确定");        bt_no.setText("取消");        tv_title.setText(title);    }    /**     * 初始化界面控件     */    private void initView() {        bt_yes = (Button) findViewById(R.id.yes);        bt_no = (Button) findViewById(R.id.no);        tv_title = (TextView) findViewById(R.id.title);    }    /**     * 设置确定按钮和取消被点击的接口     */    public interface onYesOnclickListener {        void onYesClick();    }    public interface onNoOnclickListener {        void onNoClick();    }    /**     * 设置标题     *     * @param title     */    public void setTitle(String title) {        this.title = title;    }    /**     * 设置取消按钮的显示内容和监听     *     * @param onNoOnclickListener     */    public void setNoButton(onNoOnclickListener onNoOnclickListener) {        this.noOnclickListener = onNoOnclickListener;    }    /**     * 设置确定按钮的显示内容和监听     *     * @param onYesOnclickListener     */    public void setYesButton(onYesOnclickListener onYesOnclickListener) {        this.yesOnclickListener = onYesOnclickListener;    }}


①注意:在构造方法里,我们需要给自定义dialog设置一个主题风格R.style.SelfDialog:

<!--自定义dialog背景全透明无边框theme -->    <style name="SelfDialog" parent="android:style/Theme.Dialog">        <!--背景颜色及和透明程度-->        <item name="android:windowBackground">@android:color/transparent</item>        <!--是否去除标题 -->        <item name="android:windowNoTitle">true</item>        <!--是否去除边框-->        <item name="android:windowFrame">@null</item>        <!--是否浮现在activity之上-->        <item name="android:windowIsFloating">true</item>        <!--是否模糊-->        <item name="android:backgroundDimEnabled">true</item>    </style>


②重写onCreate()方法,在方法里初始化dialog相关的view,data以及点击的监听事件,就这么简单。


4,使用自定义dialog


在MainActivity里面使用自定义的dialog,使用方式和原生的dialog一样,我们能设置title,设置“取消”、“确定”之后的事件处理等:

package com.test.blogdemo;import android.content.Context;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.util.Log;import android.view.View;public class MainActivity extends AppCompatActivity {    private static final String TAG = "MainActivity";    private Context context = MainActivity.this;    private TestAlertDialog dialog;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);    }    public void showDialog(View view) {        dialog = new TestAlertDialog(context);        dialog.setTitle("充值提醒");        dialog.setYesButton(new TestAlertDialog.onYesOnclickListener() {            @Override            public void onYesClick() {                Log.d(TAG, "onYesClick: 确定键被点击了");                dialog.dismiss();            }        });        dialog.setNoButton(new TestAlertDialog.onNoOnclickListener() {            @Override            public void onNoClick() {                Log.d(TAG, "onNoClick: 取消键被点击了");                dialog.dismiss();            }        });        dialog.show();    }}

最终的效果就如开篇那样,就到这里了,我们主要关注的是如何设置dialog的样式以及水波纹的兼容处理。记录下来,以后在项目中直接使用!



3 0
原创粉丝点击