一个基于MD风格的android对话框,代码兼容性很好,样式也非常简洁

下面先来几张图看看:
这里写图片描述
这里写图片描述
这里写图片描述

怎么样,看样式还是不错的吧,这是一个从github上找的一个项目
项目地址:https://github.com/drakeet/MaterialDialog

写这个文章的主要目的首先是介绍这个项目,第二是把源代码拿出来分享,第三是介绍几种用法
先上源码

package me.drakeet.materialdialog;

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.widget.AutoCompleteTextView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.TextView;


public class MaterialDialog {

    private final static int BUTTON_BOTTOM = 9;
    private final static int BUTTON_TOP = 9;

    private boolean mCancel;
    private Context mContext;
    private AlertDialog mAlertDialog;
    private MaterialDialog.Builder mBuilder;
    private View mView;
    private int mTitleResId;
    private CharSequence mTitle;
    private int mMessageResId;
    private CharSequence mMessage;
    private Button mPositiveButton;
    private LinearLayout.LayoutParams mLayoutParams;
    private Button mNegativeButton;
    private boolean mHasShow = false;
    private int mBackgroundResId = -1;
    private Drawable mBackgroundDrawable;
    private View mMessageContentView;
    private int mMessageContentViewResId;
    private DialogInterface.OnDismissListener mOnDismissListener;
    private int pId = -1, nId = -1;
    private String pText, nText;
    View.OnClickListener pListener, nListener;


    public MaterialDialog(Context context) {
        this.mContext = context;
    }


    public void show() {
        if (!mHasShow) {
            mBuilder = new Builder();
        }
        else {
            mAlertDialog.show();
        }
        mHasShow = true;
    }


    public MaterialDialog setView(View view) {
        mView = view;
        if (mBuilder != null) {
            mBuilder.setView(view);
        }
        return this;
    }


    public MaterialDialog setContentView(View view) {
        mMessageContentView = view;
        mMessageContentViewResId = 0;
        if (mBuilder != null) {
            mBuilder.setContentView(mMessageContentView);
        }
        return this;
    }


    /**
     * Set a custom view resource to be the contents of the dialog.
     *
     * @param layoutResId resource ID to be inflated
     */
    public MaterialDialog setContentView(int layoutResId) {
        mMessageContentViewResId = layoutResId;
        mMessageContentView = null;
        if (mBuilder != null) {
            mBuilder.setContentView(layoutResId);
        }
        return this;
    }


    public MaterialDialog setBackground(Drawable drawable) {
        mBackgroundDrawable = drawable;
        if (mBuilder != null) {
            mBuilder.setBackground(mBackgroundDrawable);
        }
        return this;
    }


    public MaterialDialog setBackgroundResource(int resId) {
        mBackgroundResId = resId;
        if (mBuilder != null) {
            mBuilder.setBackgroundResource(mBackgroundResId);
        }
        return this;
    }


    public void dismiss() {
        mAlertDialog.dismiss();
    }


    private int dip2px(float dpValue) {
        final float scale = mContext.getResources().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);
    }


    private static boolean isLollipop() {
        return Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP;
    }


    public MaterialDialog setTitle(int resId) {
        mTitleResId = resId;
        if (mBuilder != null) {
            mBuilder.setTitle(resId);
        }
        return this;
    }


    public MaterialDialog setTitle(CharSequence title) {
        mTitle = title;
        if (mBuilder != null) {
            mBuilder.setTitle(title);
        }
        return this;
    }


    public MaterialDialog setMessage(int resId) {
        mMessageResId = resId;
        if (mBuilder != null) {
            mBuilder.setMessage(resId);
        }
        return this;
    }


    public MaterialDialog setMessage(CharSequence message) {
        mMessage = message;
        if (mBuilder != null) {
            mBuilder.setMessage(message);
        }
        return this;
    }


    public MaterialDialog setPositiveButton(int resId, final View.OnClickListener listener) {
        this.pId = resId;
        this.pListener = listener;
        return this;
    }


    public Button getPositiveButton() {
        return mPositiveButton;
    }


    public Button getNegativeButton() {
        return mNegativeButton;
    }


    public MaterialDialog setPositiveButton(String text, final View.OnClickListener listener) {
        this.pText = text;
        this.pListener = listener;
        return this;
    }


    public MaterialDialog setNegativeButton(int resId, final View.OnClickListener listener) {
        this.nId = resId;
        this.nListener = listener;
        return this;
    }


    public MaterialDialog setNegativeButton(String text, final View.OnClickListener listener) {
        this.nText = text;
        this.nListener = listener;
        return this;
    }


    public MaterialDialog setCanceledOnTouchOutside(boolean cancel) {
        this.mCancel = cancel;
        if (mBuilder != null) {
            mBuilder.setCanceledOnTouchOutside(mCancel);
        }
        return this;
    }


    public MaterialDialog setOnDismissListener(DialogInterface.OnDismissListener onDismissListener) {
        this.mOnDismissListener = onDismissListener;
        return this;
    }


    private class Builder {

        private TextView mTitleView;
        private ViewGroup mMessageContentRoot;
        private TextView mMessageView;
        private Window mAlertDialogWindow;
        private LinearLayout mButtonLayout;


        private Builder() {
            mAlertDialog = new AlertDialog.Builder(mContext).create();
            mAlertDialog.show();

            mAlertDialog.getWindow()
                        .clearFlags(
                                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
                                        WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
            mAlertDialog.getWindow()
                        .setSoftInputMode(
                                WindowManager.LayoutParams.SOFT_INPUT_MASK_STATE);

            mAlertDialogWindow = mAlertDialog.getWindow();
            View contentView = LayoutInflater.from(mContext)
                                             .inflate(
                                                     R.layout.layout_materialdialog,
                                                     null);
            contentView.setFocusable(true);
            contentView.setFocusableInTouchMode(true);

            mAlertDialogWindow.setBackgroundDrawableResource(
                    R.drawable.material_dialog_window);

            mAlertDialogWindow.setContentView(contentView);

            mTitleView = (TextView) mAlertDialogWindow.findViewById(R.id.title);
            mMessageView = (TextView) mAlertDialogWindow.findViewById(
                    R.id.message);
            mButtonLayout = (LinearLayout) mAlertDialogWindow.findViewById(
                    R.id.buttonLayout);
            mPositiveButton = (Button) mButtonLayout.findViewById(R.id.btn_p);
            mNegativeButton = (Button) mButtonLayout.findViewById(R.id.btn_n);
            mMessageContentRoot = (ViewGroup) mAlertDialogWindow.findViewById(
                    R.id.message_content_root);
            if (mView != null) {
                LinearLayout linearLayout
                        = (LinearLayout) mAlertDialogWindow.findViewById(
                        R.id.contentView);
                linearLayout.removeAllViews();
                linearLayout.addView(mView);
            }
            if (mTitleResId != 0) {
                setTitle(mTitleResId);
            }
            if (mTitle != null) {
                setTitle(mTitle);
            }
            if (mTitle == null && mTitleResId == 0) {
                mTitleView.setVisibility(View.GONE);
            }
            if (mMessageResId != 0) {
                setMessage(mMessageResId);
            }
            if (mMessage != null) {
                setMessage(mMessage);
            }
            if (pId != -1) {
                mPositiveButton.setVisibility(View.VISIBLE);
                mPositiveButton.setText(pId);
                mPositiveButton.setOnClickListener(pListener);
                if (isLollipop()) {
                    mPositiveButton.setBackgroundResource(
                            android.R.color.transparent);
                }
            }
            if (nId != -1) {
                mNegativeButton.setVisibility(View.VISIBLE);
                mNegativeButton.setText(nId);
                mNegativeButton.setOnClickListener(nListener);
                if (isLollipop()) {
                    mNegativeButton.setBackgroundResource(
                            android.R.color.transparent);
                }
            }
            if (!isNullOrEmpty(pText)) {
                mPositiveButton.setVisibility(View.VISIBLE);
                mPositiveButton.setText(pText);
                mPositiveButton.setOnClickListener(pListener);
                if (isLollipop()) {
                    mPositiveButton.setBackgroundResource(
                            android.R.color.transparent);
                }
            }

            if (!isNullOrEmpty(nText)) {
                mNegativeButton.setVisibility(View.VISIBLE);
                mNegativeButton.setText(nText);
                mNegativeButton.setOnClickListener(nListener);
                if (isLollipop()) {
                    mNegativeButton.setBackgroundResource(
                            android.R.color.transparent);
                }
            }
            if (isNullOrEmpty(pText) && pId == -1) {
                mPositiveButton.setVisibility(View.GONE);
            }
            if (isNullOrEmpty(nText) && nId == -1) {
                mNegativeButton.setVisibility(View.GONE);
            }
            if (mBackgroundResId != -1) {
                LinearLayout linearLayout
                        = (LinearLayout) mAlertDialogWindow.findViewById(
                        R.id.material_background);
                linearLayout.setBackgroundResource(mBackgroundResId);
            }
            if (mBackgroundDrawable != null) {
                LinearLayout linearLayout
                        = (LinearLayout) mAlertDialogWindow.findViewById(
                        R.id.material_background);
                linearLayout.setBackground(mBackgroundDrawable);
            }

            if (mMessageContentView != null) {
                this.setContentView(mMessageContentView);
            }
            else if (mMessageContentViewResId != 0) {
                this.setContentView(mMessageContentViewResId);
            }
            mAlertDialog.setCanceledOnTouchOutside(mCancel);
            if (mOnDismissListener != null) {
                mAlertDialog.setOnDismissListener(mOnDismissListener);
            }
        }


        public void setTitle(int resId) {
            mTitleView.setText(resId);
        }


        public void setTitle(CharSequence title) {
            mTitleView.setText(title);
        }


        public void setMessage(int resId) {
            if (mMessageView != null) {
                mMessageView.setText(resId);
            }
        }


        public void setMessage(CharSequence message) {
            if (mMessageView != null) {
                mMessageView.setText(message);
            }
        }


        /**
         * set positive button
         *
         * @param text the name of button
         */
        public void setPositiveButton(String text, final View.OnClickListener listener) {
            Button button = new Button(mContext);
            LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
                    LinearLayout.LayoutParams.WRAP_CONTENT,
                    LinearLayout.LayoutParams.WRAP_CONTENT);
            button.setLayoutParams(params);
            button.setBackgroundResource(R.drawable.material_card);
            button.setTextColor(Color.argb(255, 35, 159, 242));
            button.setText(text);
            button.setGravity(Gravity.CENTER);
            button.setTextSize(14);
            button.setPadding(dip2px(12), 0, dip2px(32), dip2px(BUTTON_BOTTOM));
            button.setOnClickListener(listener);
            mButtonLayout.addView(button);
        }


        /**
         * set negative button
         *
         * @param text the name of button
         */
        public void setNegativeButton(String text, final View.OnClickListener listener) {
            Button button = new Button(mContext);
            LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
                    LinearLayout.LayoutParams.WRAP_CONTENT,
                    LinearLayout.LayoutParams.WRAP_CONTENT);
            button.setLayoutParams(params);
            button.setBackgroundResource(R.drawable.material_card);
            button.setText(text);
            button.setTextColor(Color.argb(222, 0, 0, 0));
            button.setTextSize(14);
            button.setGravity(Gravity.CENTER);
            button.setPadding(0, 0, 0, dip2px(8));
            button.setOnClickListener(listener);
            if (mButtonLayout.getChildCount() > 0) {
                params.setMargins(20, 0, 10, dip2px(BUTTON_BOTTOM));
                button.setLayoutParams(params);
                mButtonLayout.addView(button, 1);
            }
            else {
                button.setLayoutParams(params);
                mButtonLayout.addView(button);
            }
        }


        public void setView(View view) {
            LinearLayout l = (LinearLayout) mAlertDialogWindow.findViewById(
                    R.id.contentView);
            l.removeAllViews();
            ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(
                    ViewGroup.LayoutParams.MATCH_PARENT,
                    ViewGroup.LayoutParams.WRAP_CONTENT);
            view.setLayoutParams(layoutParams);

            view.setOnFocusChangeListener(new View.OnFocusChangeListener() {
                @Override public void onFocusChange(View v, boolean hasFocus) {
                    mAlertDialogWindow.setSoftInputMode(
                            WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
                    // show imm
                    InputMethodManager imm
                            = (InputMethodManager) mContext.getSystemService(
                            Context.INPUT_METHOD_SERVICE);
                    imm.toggleSoftInput(InputMethodManager.SHOW_FORCED,
                            InputMethodManager.HIDE_IMPLICIT_ONLY);
                }
            });

            l.addView(view);

            if (view instanceof ViewGroup) {

                ViewGroup viewGroup = (ViewGroup) view;

                for (int i = 0; i < viewGroup.getChildCount(); i++) {
                    if (viewGroup.getChildAt(i) instanceof EditText) {
                        EditText editText = (EditText) viewGroup.getChildAt(i);
                        editText.setFocusable(true);
                        editText.requestFocus();
                        editText.setFocusableInTouchMode(true);
                    }
                }
                for (int i = 0; i < viewGroup.getChildCount(); i++) {
                    if (viewGroup.getChildAt(
                            i) instanceof AutoCompleteTextView) {
                        AutoCompleteTextView autoCompleteTextView
                                = (AutoCompleteTextView) viewGroup.getChildAt(
                                i);
                        autoCompleteTextView.setFocusable(true);
                        autoCompleteTextView.requestFocus();
                        autoCompleteTextView.setFocusableInTouchMode(true);
                    }
                }
            }
        }


        public void setContentView(View contentView) {
            ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(
                    ViewGroup.LayoutParams.MATCH_PARENT,
                    ViewGroup.LayoutParams.MATCH_PARENT);
            contentView.setLayoutParams(layoutParams);
            if (contentView instanceof ListView) {
                setListViewHeightBasedOnChildren((ListView) contentView);
            }
            LinearLayout linearLayout
                    = (LinearLayout) mAlertDialogWindow.findViewById(
                    R.id.message_content_view);
            if (linearLayout != null) {
                linearLayout.removeAllViews();
                linearLayout.addView(contentView);
            }
            for (int i = 0;
                 i < (linearLayout != null ? linearLayout.getChildCount() : 0);
                 i++) {
                if (linearLayout.getChildAt(
                        i) instanceof AutoCompleteTextView) {
                    AutoCompleteTextView autoCompleteTextView
                            = (AutoCompleteTextView) linearLayout.getChildAt(i);
                    autoCompleteTextView.setFocusable(true);
                    autoCompleteTextView.requestFocus();
                    autoCompleteTextView.setFocusableInTouchMode(true);
                }
            }
        }


        /**
         * Set a custom view resource to be the contents of the dialog. The
         * resource will be inflated into a ScrollView.
         *
         * @param layoutResId resource ID to be inflated
         */
        public void setContentView(int layoutResId) {
            mMessageContentRoot.removeAllViews();
            // Not setting this to the other content view because user has defined their own
            // layout params, and we don't want to overwrite those.
            LayoutInflater.from(mMessageContentRoot.getContext())
                          .inflate(layoutResId, mMessageContentRoot);
        }


        public void setBackground(Drawable drawable) {
            LinearLayout linearLayout
                    = (LinearLayout) mAlertDialogWindow.findViewById(
                    R.id.material_background);
            linearLayout.setBackground(drawable);
        }


        public void setBackgroundResource(int resId) {
            LinearLayout linearLayout
                    = (LinearLayout) mAlertDialogWindow.findViewById(
                    R.id.material_background);
            linearLayout.setBackgroundResource(resId);
        }


        public void setCanceledOnTouchOutside(boolean canceledOnTouchOutside) {
            mAlertDialog.setCanceledOnTouchOutside(canceledOnTouchOutside);
        }
    }


    private boolean isNullOrEmpty(String nText) {
        return nText == null || nText.isEmpty();
    }


    /**
     * 动态测量list view item的高度
     */
    public static void setListViewHeightBasedOnChildren(ListView listView) {
        ListAdapter listAdapter = listView.getAdapter();
        if (listAdapter == null) {
            // pre-condition
            return;
        }

        int totalHeight = 0;
        for (int i = 0; i < listAdapter.getCount(); i++) {
            View listItem = listAdapter.getView(i, null, listView);
            listItem.measure(0, 0);
            totalHeight += listItem.getMeasuredHeight();
        }

        ViewGroup.LayoutParams params = listView.getLayoutParams();
        params.height = totalHeight +
                (listView.getDividerHeight() * (listAdapter.getCount() - 1));
        listView.setLayoutParams(params);
    }
}

接下来介绍几种用法:
第一种,最普通的用法

MaterialDialog mMaterialDialog = new MaterialDialog(this);
mMaterialDialog.setTitle("MaterialDialog").setMessage(
                    "Hi! This is a MaterialDialog. It's very easy to use, you just new and show() it " +"then the beautiful AlertDialog will show automatically. It is artistic, conforms to Google Material Design." +" I hope that you will like it, and enjoy it. ^ ^")
//可以设置背景mMaterialDialog.setBackgroundResource(R.drawable.background);
              .setPositiveButton("OK", new View.OnClickListener() {
                        @Override public void onClick(View v) {
                            mMaterialDialog.dismiss();
                        }
              }).setNegativeButton("CANCEL", new View.OnClickListener() {
                    @Override public void onClick(View v) {
                        mMaterialDialog.dismiss();
                }
             }).setCanceledOnTouchOutside(false)
                    .setOnDismissListener(
                            new DialogInterface.OnDismissListener() {
                                @Override
                                public void onDismiss(DialogInterface dialog) {
                                    Toast.makeText(MyActivity.this, "onDismiss",
                                            Toast.LENGTH_SHORT).show();
                                }
                            })
             .show();
// 你可以在任何时候改变消息内容
mMaterialDialog.setTitle("提示");
mMaterialDialog.setMessage("嗨!这是一个 MaterialDialog. 它非常方便使用,你只需将它实例化,这个美观的对话框便会自动地显示出来。它简洁小巧,完全遵照 Google 2014 年发布的 Material Design 风格,希望你能喜欢它!^ ^");

第二种,提供两种方式修改dialog的背景

MaterialDialog mMaterialDialog = new MaterialDialog(this);
//第一种方式利用id设置
mMaterialDialog.setBackgroundResource(R.drawable.background);
//第二种方式利用BitmapDrawable设置,BitmapDrawable是目前比较稳定的类型,不太容易oom
//Resources res = getResources();
//Bitmap bmp = BitmapFactory.decodeResource(res,R.drawable.background2);
//BitmapDrawable bitmapDrawable = new BitmapDrawable(getResources(), bmp);
//mMaterialDialog.setBackground(bitmapDrawable);
mMaterialDialog.setCanceledOnTouchOutside(true).show();

第三种,设置contentView

final MaterialDialog alert = new MaterialDialog(this).setTitle(
"MaterialDialog").setContentView( R.layout.custom_message_content);
alert.setPositiveButton("OK", new View.OnClickListener() {
    @Override public void onClick(View v) {
        alert.dismiss();
    }
});
alert.show();
final MaterialDialog mMaterialDialog = new MaterialDialog(this);
View view = LayoutInflater.from(this).inflate(R.layout.progressbar_item,
                                                  null);
mMaterialDialog.setView(view).show();
final ArrayAdapter<String> arrayAdapter
                        = new ArrayAdapter<String>(this,
                        android.R.layout.simple_list_item_1);
                for (int j = 0; j < 38; j++) {
                    arrayAdapter.add("This is item " + j);
                }

                ListView listView = new ListView(this);
                listView.setLayoutParams(new ViewGroup.LayoutParams(
                        ViewGroup.LayoutParams.MATCH_PARENT,
                        ViewGroup.LayoutParams.MATCH_PARENT));
                float scale = getResources().getDisplayMetrics().density;
                int dpAsPixels = (int) (8 * scale + 0.5f);
                listView.setPadding(0, dpAsPixels, 0, dpAsPixels);
                listView.setDividerHeight(0);
                listView.setAdapter(arrayAdapter);

                final MaterialDialog alert = new MaterialDialog(this).setTitle(
                        "MaterialDialog").setContentView(listView);

                alert.setPositiveButton("OK", new View.OnClickListener() {
                    @Override public void onClick(View v) {
                        alert.dismiss();
                    }
                });

                alert.show();
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是基于Python的MD-DBSCAN处理带有题头的点云数据CSV文件的代码: ```python import pandas as pd import numpy as np from scipy.spatial import KDTree from sklearn.mixture import GaussianMixture from sklearn.metrics import pairwise_distances class MDBSCAN: def __init__(self, eps, min_samples, num_mixtures=1, covariance_type='full'): self.eps = eps self.min_samples = min_samples self.num_mixtures = num_mixtures self.covariance_type = covariance_type self.density_est = None self.labels_ = None def fit(self, X): self.density_est = GaussianMixture(n_components=self.num_mixtures, covariance_type=self.covariance_type) self.density_est.fit(X) density = self.density_est.score_samples(X) tree = KDTree(X) visited = np.zeros(X.shape[0], dtype=bool) labels = np.zeros(X.shape[0], dtype=int) cluster_id = 1 for i in range(X.shape[0]): if visited[i]: continue visited[i] = True neighbors = tree.query_radius(X[i].reshape(1,-1), self.eps)[0] if len(neighbors) < self.min_samples: labels[i] = -1 else: points = [i] + list(neighbors) mixture_probs = self.density_est.predict_proba(X[points]) mixture_probs /= mixture_probs.sum(axis=1)[:,np.newaxis] for j in range(self.num_mixtures): labels[points[mixture_probs[:,j] > 0.5]] = cluster_id cluster_id += 1 self.labels_ = labels return self ``` 这个代码使用了 scikit-learn 库中的 GaussianMixture 模型来估计每个簇的概率密度,并使用 KDTree 来加速点之间的距离计算。在 fit 方法中,输入点云数据 X 是一个 Pandas DataFrame,其中第一列是题头信息,后面的列是点的坐标。可以使用 Pandas 库中的 read_csv 方法来读取 CSV 文件并转换为 DataFrame。使用方法如下: ```python df = pd.read_csv('point_cloud.csv') X = df.iloc[:,1:].values mdbscan = MDBSCAN(eps=0.5, min_samples=5, num_mixtures=3) mdbscan.fit(X) labels = mdbscan.labels_ ``` 其中,eps 和 min_samples 分别是 MDBSCAN 算法中的两个超参数,num_mixtures 是 GaussianMixture 模型中的高斯混合分量数量,可以根据具体数据集进行调整。labels_ 属性是算法输出的每个点的簇标签,-1 表示噪点。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值