美文网首页Andorid的好东西自定义Android资料库_dialog_toast_window
Android-自定义Dialog和其样式以及自定义控件思路详解

Android-自定义Dialog和其样式以及自定义控件思路详解

作者: JackFrost_fuzhu | 来源:发表于2016-08-10 14:44 被阅读12661次

    我们自己清楚,android的原生控件实在是不堪入目,在很多时候无法满足项目需求,所以在项目进行的过程中,我们很多时候就需要自定义控件,继承重写从而实现我们的需求。并且自定义控件将体现代码的复用,分层的架构学管理,妙用无穷。本文将详细介绍自定义Dialog的多种思路以及给出如何进行自定义控件的指南。


    文章结构(两种思路实现):1.复用率不高的,而且在dialog进行的逻辑处理较多的情况下,建议使用将dialog封装成一个类,继承基本的Dialog类实现。(在这里的后面会详细说明自定义样式的问题喔!)2.复用率高,而且每个dialog都要求有固定的布局格式的话,建议使用一个BaseDialog类作为你实际实现dialog的父类


    先上图: 这里写图片描述 就是这种仿谷歌风格的自定义dialog啦!!


    一、第一种思路实现的详解:

    首先当然是你想要的dialog布局,这里你自己想怎么折腾就怎么折腾随你。由于这里使用了radiobutton的多向运用,可在此不详细解析,欲想看明radiobutton的多向运用请看我的另一篇博客: Android之RadioButton和RadioGroup结合Dialog的多种运用详解

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="360dp"
        android:layout_height="match_parent"
        android:orientation="vertical">
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="30dp"
            android:layout_gravity="center"
            android:layout_marginTop="20dp"
            android:orientation="horizontal">
    
            <ImageView
                android:id="@+id/icon_title"
                android:layout_width="30dp"
                android:layout_height="30dp"
                android:layout_marginLeft="18dp"
                android:gravity="center"
                android:src="@drawable/setting" />
    
            <TextView
                android:id="@+id/title"
                android:layout_width="match_parent"
                android:layout_height="30dp"
                android:layout_marginLeft="20dp"
                android:gravity="center_vertical"
                android:text="广播周期设定"
                android:textSize="17sp" />
        </LinearLayout>
    
        <RadioGroup
            android:id="@+id/groupBroadcast"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginBottom="18dp"
            android:layout_marginTop="10dp"
            android:orientation="vertical">
    
            <RadioButton
                android:id="@+id/rbtn_BroadcastClose"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:button="@null"
                android:checked="true"
                android:drawableLeft="@drawable/settingbroadst_checked_style"
                android:drawablePadding="20dp"
                android:paddingLeft="18dp"
                android:text="关闭"
                android:textColor="@android:color/black"
                android:textSize="17sp" />
    
            <RadioButton
                android:id="@+id/rbtn_BroadcastFifteen"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="10dp"
                android:layout_weight="1"
                android:button="@null"
                android:drawableLeft="@drawable/settingbroadst_checked_style"
                android:drawablePadding="20dp"
                android:paddingLeft="18dp"
                android:text="15秒"
                android:textColor="@android:color/black"
                android:textSize="17sp" />
    
            <RadioButton
                android:id="@+id/rbtn_BroadcastThirty"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="10dp"
                android:layout_weight="1"
                android:button="@null"
                android:drawableLeft="@drawable/settingbroadst_checked_style"
                android:drawablePadding="20dp"
                android:paddingLeft="18dp"
                android:text="30秒"
                android:textColor="@android:color/black"
                android:textSize="17sp" />
    
            <RadioButton
                android:id="@+id/rbtn_BroadcastFourty"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="10dp"
                android:layout_weight="1"
                android:button="@null"
                android:drawableLeft="@drawable/settingbroadst_checked_style"
                android:drawablePadding="20dp"
                android:paddingLeft="18dp"
                android:text="45秒"
                android:textColor="@android:color/black"
                android:textSize="17sp" />
    
            <RadioButton
                android:id="@+id/rbtn_BroadcastMinute"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginBottom="10dp"
                android:layout_marginTop="10dp"
                android:layout_weight="1"
                android:button="@null"
                android:drawableLeft="@drawable/settingbroadst_checked_style"
                android:drawablePadding="20dp"
                android:paddingLeft="18dp"
                android:text="60秒"
                android:textColor="@android:color/black"
                android:textSize="17sp" />
        </RadioGroup>
    </LinearLayout>
    

    然后就是封装的dialog的类啦

    package org.fishDroneGCS.view;
    
    import android.app.Activity;
    import android.app.Dialog;
    import android.content.Context;
    import android.os.Bundle;
    import android.view.Display;
    import android.view.Gravity;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.Window;
    import android.view.WindowManager;
    import android.widget.AdapterView;
    import android.widget.RadioButton;
    import android.widget.RadioGroup;
    
    import org.fishDroneGCS.android.R;
    
    /**
     * Created by 符柱成on 2016/8/7.
     */
    public class RadioButtonDialog extends Dialog {
    
        private Context context;
        private String title;     //这里定义个title,一会可以看到是指向上面xml文件的控件title的,也就是我们可以通过这个进行动态修改title
        private AdapterView.OnItemClickListener   onItemClickListener;      //这里定义了一个监听是为了实现内部的监听接口处理,从而实现代码分层管理
    //可以看到两个构造器,想自定义样式的就用第二个啦
        public RadioButtonDialog(Context context) {
            super(context);
            this.context = context;
        }
    
        public RadioButtonDialog(Context context, int theme) {
            super(context, theme);
            this.context = context;
        }
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            init();
        }
    
        public void setTitle(String title) {
            this.title = title;
        }
    
        public String getTitle() {
            return title;
        }
    
        public void setOnItemClickListener(AdapterView.OnItemClickListener onItemClickListener) {
            if (onItemClickListener != null)
                this.onItemClickListener = onItemClickListener;
        }
    //控件的声明
        RadioButton rbtn_BroadcastClose;
        RadioButton rbtn_BroadcastFifteen;
        RadioButton rbtn_BroadcastThirty;
        RadioButton rbtn_BroadcastFourty;
        RadioButton rbtn_BroadcastMinute;
    
        private void init() {
        //以view的方式引入,然后回调activity方法,setContentView,实现自定义布局
            View view = LayoutInflater.from(context).inflate(R.layout.dialog_broadcast, null);
            setContentView(view);
            //radiobutton的初始化
            RadioGroup groupBroadcast = (RadioGroup) view.findViewById(R.id.groupBroadcast);
            rbtn_BroadcastClose = (RadioButton) view.findViewById(R.id.rbtn_BroadcastClose);
            rbtn_BroadcastFifteen = (RadioButton) view.findViewById(R.id.rbtn_BroadcastFifteen);
            rbtn_BroadcastThirty = (RadioButton) view.findViewById(R.id.rbtn_BroadcastThirty);
            rbtn_BroadcastFourty = (RadioButton) view.findViewById(R.id.rbtn_BroadcastFourty);
            rbtn_BroadcastMinute = (RadioButton) view.findViewById(R.id.rbtn_BroadcastMinute);
            groupBroadcast.setOnCheckedChangeListener(listener);
            //设置dialog大小,这里是一个小赠送,模块好的控件大小设置
            Window dialogWindow = getWindow();
            WindowManager manager = ((Activity) context).getWindowManager();
            WindowManager.LayoutParams params = dialogWindow.getAttributes(); // 获取对话框当前的参数值
            dialogWindow.setGravity(Gravity.CENTER);//设置对话框位置
            Display d = manager.getDefaultDisplay(); // 获取屏幕宽、高度
            params.width = (int) (d.getWidth() * 0.8); // 宽度设置为屏幕的0.65,根据实际情况调整
            dialogWindow.setAttributes(params);
    
        }
        //监听接口
        private RadioGroup.OnCheckedChangeListener listener = new RadioGroup.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(RadioGroup group, int checkedId) {
                if (checkedId == rbtn_BroadcastClose.getId()) {
    
                } else if (checkedId == rbtn_BroadcastFifteen.getId()) {
    
                } else if (checkedId == rbtn_BroadcastThirty.getId()) {
    
                } else if (checkedId == rbtn_BroadcastFourty.getId()) {
    
                } else if (checkedId == rbtn_BroadcastMinute.getId()) {
    
                }
            }
        };
    }
    

    调用:

      RadioButtonDialog radioButtonDialog=new RadioButtonDialog(getActivity(),R.style.Dialog);
            radioButtonDialog.setTitle("广播周期设定");
            radioButtonDialog.create();
            radioButtonDialog.show();
    
    

    就是这么简单的调用,使其代码的简约,逻辑分层管理的实现了。此外,大家注意到那个我们这里使用的是自定义样式。

    在style文件里面定义以下:

      <style name="Dialog" parent="android:style/Theme.Dialog">
      <!-- 第一个是dialog的背景色,当然你可以设置图片,不拦大家 -->
            <item name="android:background">@color/white</item>
            <!-- 第二个就是弹出dialog后,下面的activity层的颜色啦-->
            <item name="android:windowBackground">@android:color/transparent</item>
            <!--这里设置为没有标题栏,如果这里不设置的话,你会发现无论布局怎么改都会出现多一栏白色 -->
            <item name="android:windowNoTitle">true</item>
            <item name="android:windowFrame">@null</item><!--边框-->
        </style>
    

    好了第一种思路的实现就是这样啦。这里补充一些关于自定义dialog样式的style标签

    <item name="android:windowIsFloating">true</item><!--是否浮现在activity之上-->
    <item name="android:windowIsTranslucent">false</item><!--半透明-->
    <item name="android:backgroundDimEnabled">false</item><!--模糊-->
    

    二、第二种思路实现方式详解:

    首先是dialog的xml文件我们并不改变它

    父类dialog的封装:BaseDialog.java

    public abstract class BaseDialog extends Dialog {
    
        private Context context;    //下面三个定义的跟上面讲得就是一样的啦
        private String title;   
        private OnItemCheckListener onItemCheckListener;
        protected View view;    //看到这里我们定义的就清楚,我们也是借用view这个父类来引入布局的
    
        public BaseDialog(Context context) {
            super(context);
        }
    
        public BaseDialog(Context context, int themeResId) {
            super(context, themeResId);
        }
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            init();
        }
    
    
        public void setTitle(String title) {
            this.title = title;
        }
    
        public String getTitle() {
            return title;
        }
    
        public void setOnItemCheckListener(OnItemCheckListener onItemCheckListener) {
            if (onItemCheckListener != null)
                this.onItemCheckListener = onItemCheckListener;
        }
    
    
        protected void init() {
        //以view来引入布局
            View view = LayoutInflater.from(context).inflate(getLayoutId(), null);
            this.view=view;
            setContentView(view);
            //设置dialog大小
            Window dialogWindow = getWindow();
            WindowManager manager = ((Activity) context).getWindowManager();
            WindowManager.LayoutParams params = dialogWindow.getAttributes(); // 获取对话框当前的参数值
            dialogWindow.setGravity(Gravity.CENTER);
            Display d = manager.getDefaultDisplay(); // 获取屏幕宽、高度
            params.width = (int) (d.getWidth() * 0.8); // 宽度设置为屏幕的0.65,根据实际情况调整
            dialogWindow.setAttributes(params);
        }
    
    
    //可以看到这里定义了一个抽象方法,这个将交由子类去实现
        public abstract int getLayoutId();
    //为了逻辑分层管理,接口的管理实现方式
        public interface OnItemCheckListener {
            void onItemCheck(int checkedId);
        }
    }
    

    然后就是到了我们具体的dialog子类啦。

    public class RadioButtonDialog extends BaseDialog {
    
        private Context context;
        private String title;
        private OnItemCheckListener onItemCheckListener;
    
        public RadioButtonDialog(Context context) {
            super(context);
            this.context = context;
        }
    
        public RadioButtonDialog(Context context, int theme) {
            super(context, theme);
        }
    //回调这个方法啦
        @Override
        public int getLayoutId() {
            return 0;
        }
    //也回调了父类的init,利用getLayoutId传入了布局的id
        @Override
        protected void init() {
            super.init();
    
            RadioGroup groupBroadcast = (RadioGroup) view.findViewById(R.id.groupBroadcast);
            groupBroadcast.setOnCheckedChangeListener(listener);
        }
    
        private RadioGroup.OnCheckedChangeListener listener = new RadioGroup.OnCheckedChangeListener() {
    
            @Override
            public void onCheckedChanged(RadioGroup group, int checkedId) {
                onItemCheckListener.onItemCheck(checkedId);
            }
        };
    
        public interface OnItemCheckListener {
            void onItemCheck(int checkedId);
        }
    
    }
    
    

    实现的时候new出子类,然后用getLayoutId来set上布局id,就可以完成啦!!!


    这里给出继承父类dialog的布局格式的思路:

    比如:标题和确定键以及取消键都要求固定格式,实现:

    1.子类要设置布局,所以要在父类留一个设置内容的方法,就像上面父类那样,写一个抽象方法,然后dialog中间布局就写一个布局并且附上id,在父类方法addView,像getLayoutId那样,然后子类回调这个方法,在addView里面,set上我们自定义的dialog内容布局就可以实现啦!!!

    好了,这个就是实现自定义dialog的两种思路,以及如何进行自己的自定义控件的思路详解啦!!!代码里面都有详细解析,就此结束啦!!

    欢迎在下方指出错误,共同学习!

    转载请表明【JackFrost的博客】

    相关文章

      网友评论

        本文标题:Android-自定义Dialog和其样式以及自定义控件思路详解

        本文链接:https://www.haomeiwen.com/subject/pjkjsttx.html