一句话搞定高仿ios底部弹出提示框(Android)

简介:

最近项目里面用到了底部的弹出提示框,UI小姐姐本着设计样式还是ios的好看原则。设计了一个ios样式的底部弹出提示框。OK OK anyway,类似样式并不少见,实现方式有很多,网上随便找一个吧,还不满大街都是。嗯哼,确实不少。但是 !!! 不是讲代码就是讲布局,或者使用方法挺麻烦。

用的时候还要自己手写这部分代码,麻烦不麻烦?作为一名注定要改变世界的程序猿,你让我天天写这个?这是不能忍的。就没有简单的,快捷的,高效的,一句话就能搞定的吗?

有需求就有产品,所以,这个BottomMenu产生了。GitHub项目地址

更高,更快,更强

先来看下效果:

演示

How to use:

Step 1. Add the JitPack repository to your build file
Add it in your root build.gradle at the end of repositories:

   allprojects {
       repositories {
           ...
           maven { url 'https://jitpack.io' }
       }
   }

Step 2. Add the dependency

    dependencies {
            compile 'com.github.zhaolei9527:BottomMenu:v1.0.1'
    }

Activity文件代码:(一句话,有木有?很简单,有木有?)
基本用法:

new BottomMenuFragment(MainActivity.this)
        .addMenuItems(new MenuItem("从相册选择"))
        .addMenuItems(new MenuItem("拍照"))
        .setOnItemClickListener(new BottomMenuFragment.OnItemClickListener() {
            @Override
            public void onItemClick(TextView menu_item, int position) {
                Toast.makeText(MainActivity.this, menu_item.getText().toString().trim(), Toast.LENGTH_SHORT).show();
            }
        })
        .show();

带Title用法:

new BottomMenuFragment(MainActivity.this)
        .setTitle("标题")
        .addMenuItems(new MenuItem("从相册选择"))
        .addMenuItems(new MenuItem("拍照"))
        .setOnItemClickListener(new BottomMenuFragment.OnItemClickListener() {
            @Override
            public void onItemClick(TextView menu_item, int position) {
                Toast.makeText(MainActivity.this, menu_item.getText().toString().trim(), Toast.LENGTH_SHORT).show();
            }
        })
        .show();

指定条目样式用法:

new BottomMenuFragment(MainActivity.this)
        .setTitle("标题")
        .addMenuItems(new MenuItem("从相册选择", MenuItem.MenuItemStyle.COMMON))
        .addMenuItems(new MenuItem("拍照", MenuItem.MenuItemStyle.STRESS))
        .setOnItemClickListener(new BottomMenuFragment.OnItemClickListener() {
            @Override
            public void onItemClick(TextView menu_item, int position) {
                Toast.makeText(MainActivity.this, menu_item.getText().toString().trim(), Toast.LENGTH_SHORT).show();
            }
        })
        .show();

全部一句话搞定,还有更多功能可以自己发掘一下。

最后看下组件代码:

整体结构为三个文件,BottomMenuFragment为弹出主体内容,MenuItem为条目对象的POJO,MenuItemAdapter顾名思义是条目的适配器。代码逻辑实现方法其实挺简单,大同小异,只不过对于代码进行封装使操作更加便捷,简单且迅速。
BottomMenuFragment文件:

public class BottomMenuFragment extends DialogFragment {

    private final String TAG = "BottomMenuFragment";
    private Activity context;
    private OnItemClickListener mOnItemClickListener;
    private boolean showTitle = false;
    private String BottomTitle = "";

    public BottomMenuFragment(Activity context) {
        this.context = context;
    }

    private List<MenuItem> menuItemList = new ArrayList<MenuItem>();

    public List<MenuItem> getMenuItems() {
        return menuItemList;
    }

    public void addMenuItems(List<MenuItem> menuItems) {
        this.menuItemList.addAll(menuItems);
    }

    public BottomMenuFragment addMenuItems(MenuItem menuItems) {
        menuItemList.add(menuItems);
        return this;
    }

    public BottomMenuFragment setTitle(String BottomTitle) {
        showTitle = true;
        this.BottomTitle = BottomTitle;
        return this;
    }

    public void show() {
        this.show(context.getFragmentManager(), "BottomMenuFragment");
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        getDialog().requestWindowFeature(Window.FEATURE_NO_TITLE);
        getDialog().getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));//设置背景透明
        getDialog().getWindow().setWindowAnimations(R.style.menu_animation);//添加一组进出动画
        View view = inflater.inflate(R.layout.fragment_bottom_menu, container, false);
        //view.setAnimation(AnimationUtils.loadAnimation(getActivity(), R.anim.menu_appear));//添加一个加载动画,这样的问题是没办法添加消失动画,有待进一步研究
        ((TextView) view.findViewById(tv_cancel)).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.i(TAG, "onClick: tv_cancel");
                BottomMenuFragment.this.dismiss();
            }
        });

        if (showTitle) {
            menuItemList.add(0, new MenuItem(BottomTitle, MenuItem.MenuItemStyle.COMMON));
        }

        ListView lv_menu = (ListView) view.findViewById(R.id.lv_menu);
        MenuItemAdapter menuItemAdapter = new MenuItemAdapter(getActivity().getBaseContext(), this.menuItemList);
        lv_menu.setAdapter(menuItemAdapter);
        lv_menu.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                Log.i(TAG, "onClick: ");
                if (mOnItemClickListener != null) {
                    if (showTitle) {
                        if (position == 0) {
                            return;
                        }
                    }
                    TextView menu_item = (TextView) view.findViewById(R.id.menu_item);
                    mOnItemClickListener.onItemClick(menu_item, position);
                    dismiss();
                }
            }
        });
        return view;
    }

    public interface OnItemClickListener {
        void onItemClick(TextView menu_item, int position);
    }

    public BottomMenuFragment setOnItemClickListener(@Nullable OnItemClickListener listener) {
        mOnItemClickListener = listener;
        return this;
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        Log.i(TAG, "onDestroyView: ");
    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        Log.i(TAG, "onAttach: ");
    }

    @Override
    public void onDetach() {
        super.onDetach();
        Log.i(TAG, "onDetach: ");
    }

    @Override
    public void onStart() {
        super.onStart();
        Log.i(TAG, "onStart: ");

        //设置弹出框宽屏显示,适应屏幕宽度
        DisplayMetrics dm = new DisplayMetrics();
        getActivity().getWindowManager().getDefaultDisplay().getMetrics(dm);
        getDialog().getWindow().setLayout(dm.widthPixels, getDialog().getWindow().getAttributes().height);

        //移动弹出菜单到底部
        WindowManager.LayoutParams wlp = getDialog().getWindow().getAttributes();
        wlp.gravity = Gravity.BOTTOM;
        // wlp.width = WindowManager.LayoutParams.MATCH_PARENT;
        getDialog().getWindow().setAttributes(wlp);
    }

    @Override
    public void onStop() {
        this.getView().setAnimation(AnimationUtils.loadAnimation(getActivity(), R.anim.menu_disappear));
        super.onStop();
    }
}

MenuItemAdapter文件:

public class MenuItemAdapter extends BaseAdapter {


    private Context context;//运行上下文

    private LayoutInflater listContainer;  //视图容器

    private List<MenuItem> menuItems;

    public MenuItemAdapter(Context _context, List<MenuItem> _menuItems){
        this.context = _context;
        this.listContainer = LayoutInflater.from(_context);
        this.menuItems = _menuItems;
    }

    @Override
    public int getCount() {
        return this.menuItems.size();
    }

    @Override
    public Object getItem(int position) {
        if(position >= menuItems.size() || position < 0) {
            return null;
        } else {
            return menuItems.get(position);
        }
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        View view = convertView;
        if(convertView == null) {
            view = listContainer.inflate(R.layout.menu_item, null);
        }

        MenuItem menuItem = menuItems.get(position);

        TextView textView = (TextView) view.findViewById(R.id.menu_item);
        textView.setText(menuItem.getText());
        if(menuItems.size() == 1) {
            textView.setBackgroundResource(R.drawable.bottom_menu_btn_selector);
        } else if(position == 0) {
            textView.setBackgroundResource(R.drawable.bottom_menu_top_btn_selector);
        } else if(position < menuItems.size() - 1) {
            textView.setBackgroundResource(R.drawable.bottom_menu_mid_btn_selector);
        } else {
            textView.setBackgroundResource(R.drawable.bottom_menu_bottom_btn_selector);
        }
        if(menuItem.getStyle() == MenuItem.MenuItemStyle.COMMON) {
            textView.setTextColor(ContextCompat.getColor(context, R.color.bottom_menu_btn_text_commom_color));
        } else {
            textView.setTextColor(ContextCompat.getColor(context, R.color.bottom_menu_btn_text_stress_color));
        }
        return view;
    }
}

MenuItem文件:

public class MenuItem {
    public MenuItem() {

    }

    /**
     * @param _item_name               菜单项名称
     * @param _text                    菜单项显示内容
     * @param _style                   菜单类型
     */
    public MenuItem(String _item_name, String _text, MenuItemStyle _style) {
        this.item_name = _item_name;
        this.text = _text;
        this.style = _style;
    }

    public MenuItem(String _text, MenuItemStyle _style) {
        this.text = _text;
        this.style = _style;
    }

    public MenuItem(String _text) {
        this.text = _text;
    }

    private String item_name;
    private String text;
    private MenuItemStyle style = MenuItemStyle.COMMON;

    public String getItem_name() {
        return item_name;
    }

    public String getText() {
        return text;
    }

    public MenuItemStyle getStyle() {
        return style;
    }

    public void setItem_name(String item_name) {
        this.item_name = item_name;
    }

    public void setText(String text) {
        this.text = text;
    }

    /**
     * @param style 菜单类型
     */
    public void setStyle(MenuItemStyle style) {
        this.style = style;
    }

    public enum MenuItemStyle {
        COMMON, STRESS
    }

}

总结

代码整体满足了一句话搞定高仿ios底部弹出提示框的功能,当然,

有了需求才有了功能,有了想法才有了创作,你的反馈会是使我进步的最大动力。

觉得还不够方便?还想要什么功能?告诉我!欢迎反馈,欢迎Star。源码入口:BottomMenu-GitHub项目地址

目录
相关文章
|
7天前
|
IDE Android开发 iOS开发
探索Android与iOS开发的差异:平台选择对项目成功的影响
【9月更文挑战第27天】在移动应用开发的世界中,Android和iOS是两个主要的操作系统平台。每个系统都有其独特的开发环境、工具和用户群体。本文将深入探讨这两个平台的关键差异点,并分析这些差异如何影响应用的性能、用户体验和最终的市场表现。通过对比分析,我们将揭示选择正确的开发平台对于确保项目成功的重要作用。
|
10天前
|
IDE Android开发 iOS开发
深入解析Android与iOS的系统架构及开发环境差异
本文旨在探讨Android和iOS两大主流移动操作系统在系统架构、开发环境和用户体验方面的显著差异。通过对比分析,我们将揭示这两种系统在设计理念、技术实现以及市场策略上的不同路径,帮助开发者更好地理解其特点,从而做出更合适的开发决策。
38 2
|
16天前
|
安全 Android开发 数据安全/隐私保护
探索安卓与iOS的安全性差异:一场永无止境的较量
在移动操作系统的世界中,安卓(Android)和iOS一直是备受关注的两大巨头。它们不仅在市场份额、用户体验和功能特性上竞争激烈,还在安全性这一关键领域展开了激烈的角逐。本文将深入探讨安卓与iOS在安全性方面的不同之处,分析两者在应对安全威胁时的策略和技术手段,并展望未来移动操作系统安全的发展趋势。通过对比分析,我们将揭示这场永无止境的较量中,究竟谁能更胜一筹,以及用户又该如何在两者之间做出明智的选择。
35 0
|
4天前
|
开发框架 移动开发 Android开发
安卓与iOS开发中的跨平台解决方案:Flutter入门
【9月更文挑战第30天】在移动应用开发的广阔舞台上,安卓和iOS两大操作系统各自占据半壁江山。开发者们常常面临着选择:是专注于单一平台深耕细作,还是寻找一种能够横跨两大系统的开发方案?Flutter,作为一种新兴的跨平台UI工具包,正以其现代、响应式的特点赢得开发者的青睐。本文将带你一探究竟,从Flutter的基础概念到实战应用,深入浅出地介绍这一技术的魅力所在。
21 7
|
7天前
|
开发框架 前端开发 Android开发
安卓与iOS开发中的跨平台解决方案
【9月更文挑战第27天】在移动应用开发的广阔天地中,安卓和iOS两大操作系统如同双子星座般耀眼。开发者们在这两大平台上追逐着创新的梦想,却也面临着选择的难题。如何在保持高效的同时,实现跨平台的开发?本文将带你探索跨平台开发的魅力所在,揭示其背后的技术原理,并通过实际案例展示其应用场景。无论你是安卓的忠实拥趸,还是iOS的狂热粉丝,这篇文章都将为你打开一扇通往跨平台开发新世界的大门。
|
8天前
|
安全 Android开发 数据安全/隐私保护
探索安卓与iOS的安全性差异:技术深度分析与实践建议
本文旨在深入探讨并比较Android和iOS两大移动操作系统在安全性方面的不同之处。通过详细的技术分析,揭示两者在架构设计、权限管理、应用生态及更新机制等方面的安全特性。同时,针对这些差异提出针对性的实践建议,旨在为开发者和用户提供增强移动设备安全性的参考。
|
11天前
|
监控 Android开发 iOS开发
深入探索安卓与iOS的系统架构差异:理解两大移动平台的技术根基在移动技术日新月异的今天,安卓和iOS作为市场上最为流行的两个操作系统,各自拥有独特的技术特性和庞大的用户基础。本文将深入探讨这两个平台的系统架构差异,揭示它们如何支撑起各自的生态系统,并影响着全球数亿用户的使用体验。
本文通过对比分析安卓和iOS的系统架构,揭示了这两个平台在设计理念、安全性、用户体验和技术生态上的根本区别。不同于常规的技术综述,本文以深入浅出的方式,带领读者理解这些差异是如何影响应用开发、用户选择和市场趋势的。通过梳理历史脉络和未来展望,本文旨在为开发者、用户以及行业分析师提供有价值的见解,帮助大家更好地把握移动技术发展的脉络。
|
15天前
|
开发工具 Android开发 iOS开发
掌握安卓与iOS应用开发:关键技术与未来展望
本文深入探讨了安卓和iOS平台下的应用开发技术,重点比较了两大平台的架构、开发工具和市场策略。通过分析最新的技术趋势和开发者社区的反馈,文章为读者提供了一个全面的对比视角,旨在帮助开发者做出更明智的平台选择和开发决策。
|
10天前
|
安全 Java Android开发
掌握安卓与iOS应用开发中的关键技术
本文深入探讨了安卓和iOS平台上应用开发的关键性技术,包括平台特性、开发工具选择、性能优化技巧及跨平台开发的可行性分析。通过对比两种平台的开发环境与实践案例,旨在为开发者提供全面的视角以理解和把握移动应用开发的核心技术。无论是安卓的Java与Kotlin之争,还是iOS的Swift语言革命,本文都将一一解析其优势与应用场景,帮助开发者在技术选型上有更明智的决策。此外,文章还将触及到当前流行的跨平台框架如React Native和Flutter,评估它们在项目实施中的实用性和限制,为有意进行多平台同步开发的团队提供参考。通过对这些关键技术的梳理,本文期望能够启发开发者深化对移动平台开发的理解,并
|
13天前
|
人工智能 vr&ar Android开发
探索安卓与iOS的无限可能:移动操作系统的技术革新与未来展望
本文旨在探讨安卓和iOS这两大主流移动操作系统在技术上的创新与突破,以及它们如何塑造我们的数字生活。通过深入分析两者的最新进展、面临的挑战以及未来的发展趋势,文章揭示了移动操作系统在推动科技进步和满足用户需求方面的关键作用。我们将从技术角度出发,解读安卓的开放性与iOS的封闭性如何影响应用生态和用户体验,并探讨这些差异背后的设计理念和商业考量。同时,我们还将关注两大系统在安全性、隐私保护、人工智能集成等方面的最新动态,以及它们如何应对日益增长的网络安全威胁和用户对隐私保护的需求。此外,文章还将展望未来移动操作系统的发展,分析5G、物联网等新兴技术如何为安卓和iOS带来新的机遇和挑战,以及这两大
37 6