美化的底部彈出菜單BottomMenuDialog

官方推薦我們使用FragmentDialog來(lái)統(tǒng)一風(fēng)格铺罢,使界面更美觀历葛!
于是推出了AppCompatDialog,AppCompatDialogFragment茴晋,而B(niǎo)ottomSheetDialogFragment就是繼承它而來(lái)的,我們要在此基礎(chǔ)上再次封裝一下回窘,以適應(yīng)我們自己的需求

  1. 首先我們要引入相關(guān)的兼容包诺擅,版本號(hào)就看你自己的環(huán)境了
compile 'com.android.support:design:26.0.0-alpha1'
  1. 我們這里還需要重寫(xiě)一下BottomSheetDialog

解決使用BottomSheetDialog時(shí)狀態(tài)欄變黑的問(wèn)題

public class BottomSheetDialog extends android.support.design.widget.BottomSheetDialog{
    public BottomSheetDialog(@NonNull Context context) {
        super(context);
        BottomSheetDialogFragment dd;
    }

    public BottomSheetDialog(@NonNull Context context, @StyleRes int theme) {
        super(context, theme);

    }

    protected BottomSheetDialog(@NonNull Context context, boolean cancelable, DialogInterface.OnCancelListener cancelListener) {
        super(context, cancelable, cancelListener);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        int screenHeight = getScreenHeight(getOwnerActivity());
        int statusBarHeight = getStatusBarHeight(getContext());
        int dialogHeight = screenHeight - statusBarHeight;
        getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, dialogHeight == 0 ? ViewGroup.LayoutParams.MATCH_PARENT : dialogHeight);
    }

    private static int getScreenHeight(Activity activity) {
        DisplayMetrics displaymetrics = new DisplayMetrics();
        activity.getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
        return displaymetrics.heightPixels;
    }

    private static int getStatusBarHeight(Context context) {
        int statusBarHeight = 0;
        Resources res = context.getResources();
        int resourceId = res.getIdentifier("status_bar_height", "dimen", "android");
        if (resourceId > 0) {
            statusBarHeight = res.getDimensionPixelSize(resourceId);
        }
        return statusBarHeight;
    }
}
  1. 然后寫(xiě)我們自定義的BottomMenuDialog
public class BottomMenuDialog extends BottomSheetDialogFragment implements View.OnClickListener {
    public static final String TAG = "BOTTOM_MENU";

    //必要參數(shù) 標(biāo)題集合
    private ArrayList<String> titles;
    //必要參數(shù) 監(jiān)聽(tīng)器集合
    private Map<String, View.OnClickListener> listeners;
    //菜單文字顏色
    private int textColor = Color.parseColor("#55C1FF");

    private LinearLayout rootView;
    protected Dialog dialog;
    private Context mContext;

    protected BottomSheetBehavior mBehavior;

    public BottomMenuDialog() {
    }

    @SuppressLint("ValidFragment")
    public BottomMenuDialog(BottomMenuBuilder builder) {
        titles = builder.titles;
        listeners = builder.listeners;
    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        this.mContext = context;
    }

    @Override
    public void onStart() {
        super.onStart();
        Window window = getDialog().getWindow();
        WindowManager.LayoutParams windowParams = window.getAttributes();
        //這里設(shè)置透明度
        windowParams.dimAmount = 0.5f;

        window.setAttributes(windowParams);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        //解除緩存View和當(dāng)前ViewGroup的關(guān)聯(lián)
        ((ViewGroup) (rootView.getParent())).removeView(rootView);
    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        dialog = new BottomSheetDialog(getContext(), getTheme());
        if (rootView == null) {
            //緩存下來(lái)的View 當(dāng)為空時(shí)才需要初始化 并緩存
            initRootView();
        }
        dialog.setContentView(rootView);
        mBehavior = BottomSheetBehavior.from((View) rootView.getParent());
        ((View) rootView.getParent()).setBackgroundColor(Color.TRANSPARENT);
        rootView.post(new Runnable() {
            @Override
            public void run() {
                /**
                 * PeekHeight默認(rèn)高度256dp 會(huì)在該高度上懸浮
                 * 設(shè)置等于view的高 就不會(huì)卡住
                 */
                mBehavior.setPeekHeight(rootView.getHeight());
            }
        });

        return dialog;
    }

    private void initRootView() {
        rootView = new LinearLayout(mContext);
        rootView.setOrientation(LinearLayout.VERTICAL);
        rootView.setPadding(dp2px(mContext, 10), 0, dp2px(mContext, 10), dp2px(mContext, 10));

        if (titles == null || titles.size() == 0) {
            return;
        }
        if (titles.size() == 1) {
            View childView = initView(titles.get(0), 1, false, false);
            childView.setBackgroundDrawable(getDrawableListByType(true, true, true, true));
            return;
        }

        if (titles.size() == 2) {
            View childView = initView(titles.get(0), 1, false, true);
            childView.setBackgroundDrawable(getDrawableListByType(true, true, true, true));
            childView = initView(titles.get(1), 2, false, false);
            childView.setBackgroundDrawable(getDrawableListByType(true, true, true, true));
            return;
        }

        for (int i = 0; i < titles.size(); i++) {
            View childView = null;
            if (i == 0) {
                childView = initView(titles.get(0), i + 1, true, false);
                childView.setBackgroundDrawable(getDrawableListByType(true, true, false, false));
                continue;
            }
            if (i == (titles.size() - 2)) {
                childView = initView(titles.get(i), i + 1, false, true);
                childView.setBackgroundDrawable(getDrawableListByType(false, false, true, true));
                continue;
            }
            if (i == (titles.size() - 1)) {
                //false, false, true, true
                childView = initView(titles.get(i), i + 1, false, false);
                childView.setBackgroundDrawable(getDrawableListByType(true, true, true, true));
                continue;
            }

            childView = initView(titles.get(i), i + 1, true, false);
            childView.setBackgroundDrawable(getDrawableListByType(false, false, false, false));
        }

    }

    private View initView(String button, int position, boolean hasBottomLine, boolean hasBottomGap) {
        TextView childView = new TextView(mContext);
        childView.setText(button);
        childView.setTextSize(18);
        childView.setTextColor(textColor);
        childView.setTag(position);
        childView.setGravity(Gravity.CENTER);
        childView.setOnClickListener(this);
        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, dp2px(mContext, 50));
        if (hasBottomGap) params.bottomMargin = dp2px(mContext, 10);
        rootView.addView(childView, params);

        if (hasBottomLine) {
            View line = new View(mContext);
            line.setBackgroundColor(Color.LTGRAY);
            rootView.addView(line, LinearLayout.LayoutParams.MATCH_PARENT, 1);
        }

        return childView;
    }


    public void setTextColor(int color) {
        this.textColor = color;
    }

    public StateListDrawable getDrawableListByType(boolean leftTop, boolean rightTop, boolean rightBottom, boolean leftBottom) {
        StateListDrawable stateListDrawable = new StateListDrawable();
        Drawable selectDrawable = getWhitShape(5, 0xffCCCCCC, leftTop, rightTop, rightBottom, leftBottom);
        Drawable defaultDrawable = getWhitShape(5, 0xffffffff, leftTop, rightTop, rightBottom, leftBottom);

        stateListDrawable.addState(new int[]{android.R.attr.state_pressed}, selectDrawable);
        stateListDrawable.addState(new int[]{}, defaultDrawable);
        return stateListDrawable;
    }

    public Drawable getWhitShape(int radius, int bgColor, boolean leftTop, boolean rightTop, boolean rightBottom, boolean leftBottom) {
        float r = dp2px(getContext(), radius);
        float a1 = 0, a2 = 0, a3 = 0, a4 = 0, a5 = 0, a6 = 0, a7 = 0, a8 = 0;
        if (leftTop) {
            a1 = r;
            a2 = r;
        }
        if (rightTop) {
            a3 = r;
            a4 = r;
        }

        if (rightBottom) {
            a5 = r;
            a6 = r;
        }

        if (leftBottom) {
            a7 = r;
            a8 = r;
        }

        float[] outerRadii = new float[]{a1, a2, a3, a4, a5, a6, a7, a8};
        RoundRectShape rrs = new RoundRectShape(outerRadii, null, null);
        ShapeDrawable sd = new ShapeDrawable(rrs);
        sd.getPaint().setColor(bgColor);
        return sd;
    }

    public void show(FragmentManager manager) {
        if (!this.isAdded())
            show(manager, TAG);
    }


    public static int dp2px(Context context, float dpVal) {
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
                dpVal, context.getResources().getDisplayMetrics());
    }

    @Override
    public void onClick(View v) {
        Object o = v.getTag();
        if (o == null) {
            return;
        }
        String key = String.valueOf(o);
        if (listeners.get(key) != null) {
            listeners.get(key).onClick(v);
        }
        dismiss();
    }

    public static class BottomMenuBuilder {
        //必要參數(shù) 標(biāo)題集合
        private ArrayList<String> titles;
        //必要參數(shù) 監(jiān)聽(tīng)器集合
        private Map<String, View.OnClickListener> listeners;

        public BottomMenuBuilder() {
            titles = new ArrayList<>();
            listeners = new HashMap<>();
        }

        public BottomMenuDialog build() {
            if (titles == null || titles.isEmpty()) {

                L.e(TAG, "can not empty titles");
            }

            return new BottomMenuDialog(this);
        }


        public BottomMenuBuilder addItem(String title, View.OnClickListener listener) {
            titles.add(title);
            listeners.put(String.valueOf(titles.size()), listener);
            return this;
        }
    }

}
  1. 使用
new BottomMenuDialog.BottomMenuBuilder()
                        .addItem("相機(jī)", new View.OnClickListener() {
                            @Override
                            public void onClick(View v) {

                            }
                        })
                        .addItem("相冊(cè)", new View.OnClickListener() {
                            @Override
                            public void onClick(View v) {

                            }
                        })
                        .addItem("取消",null)
                        .build().show(getSupportFragmentManager());

最好不要添加過(guò)多數(shù)據(jù),撐滿屏幕是不會(huì)擴(kuò)展的啡直,最后看效果:

image.png

更多功能就需要我們自己探索了烁涌!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末苍碟,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子撮执,更是在濱河造成了極大的恐慌微峰,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,185評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件抒钱,死亡現(xiàn)場(chǎng)離奇詭異蜓肆,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)谋币,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,652評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門仗扬,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人蕾额,你說(shuō)我怎么就攤上這事早芭。” “怎么了凡简?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,524評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵逼友,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我秤涩,道長(zhǎng)帜乞,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,339評(píng)論 1 293
  • 正文 為了忘掉前任筐眷,我火速辦了婚禮黎烈,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘匀谣。我一直安慰自己照棋,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,387評(píng)論 6 391
  • 文/花漫 我一把揭開(kāi)白布武翎。 她就那樣靜靜地躺著烈炭,像睡著了一般。 火紅的嫁衣襯著肌膚如雪宝恶。 梳的紋絲不亂的頭發(fā)上符隙,一...
    開(kāi)封第一講書(shū)人閱讀 51,287評(píng)論 1 301
  • 那天,我揣著相機(jī)與錄音垫毙,去河邊找鬼霹疫。 笑死,一個(gè)胖子當(dāng)著我的面吹牛综芥,可吹牛的內(nèi)容都是我干的丽蝎。 我是一名探鬼主播,決...
    沈念sama閱讀 40,130評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼膀藐,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼屠阻!你這毒婦竟也來(lái)了红省?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 38,985評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤栏笆,失蹤者是張志新(化名)和其女友劉穎类腮,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體蛉加,經(jīng)...
    沈念sama閱讀 45,420評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡蚜枢,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,617評(píng)論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了针饥。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片厂抽。...
    茶點(diǎn)故事閱讀 39,779評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖丁眼,靈堂內(nèi)的尸體忽然破棺而出筷凤,到底是詐尸還是另有隱情,我是刑警寧澤苞七,帶...
    沈念sama閱讀 35,477評(píng)論 5 345
  • 正文 年R本政府宣布藐守,位于F島的核電站,受9級(jí)特大地震影響蹂风,放射性物質(zhì)發(fā)生泄漏卢厂。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,088評(píng)論 3 328
  • 文/蒙蒙 一惠啄、第九天 我趴在偏房一處隱蔽的房頂上張望慎恒。 院中可真熱鬧,春花似錦撵渡、人聲如沸融柬。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,716評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)粒氧。三九已至,卻和暖如春节腐,著一層夾襖步出監(jiān)牢的瞬間靠欢,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,857評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工铜跑, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人骡澈。 一個(gè)月前我還...
    沈念sama閱讀 47,876評(píng)論 2 370
  • 正文 我出身青樓锅纺,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親肋殴。 傳聞我的和親對(duì)象是個(gè)殘疾皇子囤锉,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,700評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容