一句话搞定高仿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项目地址

目录
相关文章
|
6天前
|
安全 Android开发 iOS开发
深入探索Android与iOS的差异:从系统架构到用户体验
在当今的智能手机市场中,Android和iOS无疑是最受欢迎的两大操作系统。本文旨在探讨这两个平台之间的主要差异,包括它们的系统架构、开发环境、安全性、以及用户体验等方面。通过对比分析,我们可以更好地理解为何不同的用户群体可能会偏好其中一个平台,以及这些偏好背后的技术原因。
|
13天前
|
存储 安全 Android开发
探索Android与iOS的隐私保护机制
在数字化时代,移动设备已成为我们生活的一部分,而隐私安全是用户最为关注的问题之一。本文将深入探讨Android和iOS两大主流操作系统在隐私保护方面的策略和实现方式,分析它们各自的优势和不足,以及如何更好地保护用户的隐私。
|
13天前
|
安全 数据安全/隐私保护 Android开发
探索Android与iOS的隐私保护策略
在数字时代,智能手机已成为我们生活中不可或缺的一部分,而随之而来的则是对个人隐私和数据安全的日益关注。本文将深入探讨Android与iOS两大操作系统在隐私保护方面的策略和实践,分析它们如何应对日益严峻的隐私挑战,以及用户应如何保护自己的数据安全。通过对比分析,我们将揭示两大系统在隐私保护方面的优势和不足,为用户提供有价值的见解和建议。
|
13天前
|
Android开发 Swift iOS开发
深入探索iOS与Android操作系统的架构差异及其对应用开发的影响
在当今数字化时代,移动设备已经成为我们日常生活和工作不可或缺的一部分。其中,iOS和Android作为全球最流行的两大移动操作系统,各自拥有独特的系统架构和设计理念。本文将深入探讨iOS与Android的系统架构差异,并分析这些差异如何影响应用开发者的开发策略和用户体验设计。通过对两者的比较,我们可以更好地理解它们各自的优势和局限性,从而为开发者提供有价值的见解,帮助他们在这两个平台上开发出更高效、更符合用户需求的应用。
|
22天前
|
安全 Android开发 数据安全/隐私保护
深入探讨iOS与Android系统安全性对比分析
在移动操作系统领域,iOS和Android无疑是两大巨头。本文从技术角度出发,对这两个系统的架构、安全机制以及用户隐私保护等方面进行了详细的比较分析。通过深入探讨,我们旨在揭示两个系统在安全性方面的差异,并为用户提供一些实用的安全建议。
|
8天前
|
安全 定位技术 Android开发
深入探索Android与iOS操作系统的安全性差异
【10月更文挑战第21天】 在当今数字化时代,智能手机已成为我们生活中不可或缺的一部分。其中,Android和iOS作为两大主流操作系统,各自拥有庞大的用户群体。然而,它们在安全性方面的表现却大相径庭。本文将深入探讨Android与iOS在安全机制、隐私保护以及应对恶意软件方面的差异,帮助读者更全面地了解这两个平台的安全特性。
|
14天前
|
前端开发 Android开发 开发者
探索Android与iOS的跨平台开发策略
在当今多元化的移动设备市场中,开发者面临着为不同操作系统设计应用的挑战。本文深入探讨了Android和iOS两大主流平台的跨平台开发策略。我们将分析使用Flutter、React Native等框架进行跨平台开发的优劣,并讨论如何克服各平台间的差异性,以实现高效、一致的用户体验。此外,文章还将提供一些实用的技巧和最佳实践,帮助开发者优化跨平台应用的性能和兼容性。
33 4
|
16天前
|
安全 Android开发 iOS开发
深入探讨Android与iOS操作系统的差异性
本文旨在通过对比分析Android和iOS两大主流移动操作系统,揭示它们在设计理念、用户体验、安全性、应用生态及系统更新等方面的根本差异。不同于传统的功能列表式摘要,本摘要强调了两大系统背后的哲学思想及其对用户日常使用的实际影响,为读者提供了一个宏观且深入的视角来理解这两种操作系统的独特之处。
|
15天前
|
Android开发 Swift iOS开发
探索安卓与iOS开发的差异和挑战
【10月更文挑战第37天】在移动应用开发的广阔舞台上,安卓和iOS这两大操作系统扮演着主角。它们各自拥有独特的特性、优势以及面临的开发挑战。本文将深入探讨这两个平台在开发过程中的主要差异,从编程语言到用户界面设计,再到市场分布的不同影响,旨在为开发者提供一个全面的视角,帮助他们更好地理解并应对在不同平台上进行应用开发时可能遇到的难题和机遇。
|
15天前
|
存储 安全 数据安全/隐私保护
深入探索Android与iOS的隐私保护机制:一场没有硝烟的较量####
本文深度剖析了Android与iOS两大移动操作系统在用户隐私保护方面的策略与实践,揭示两者在设计理念、技术实现及用户体验上的异同。通过对比分析,旨在为读者提供一个全面而深入的视角,理解两大平台如何在保障用户隐私的同时,实现功能的丰富与便捷。本文不涉及具体产品推荐或品牌偏好,仅从技术角度出发,探讨隐私保护的现状与挑战。 ####