首页 文章 精选 留言 我的

精选列表

搜索[Android],共10000篇文章
优秀的个人博客,低调大师

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

最近项目里面用到了底部的弹出提示框,UI小姐姐本着设计样式还是ios的好看原则。设计了一个ios样式的底部弹出提示框。OK OK anyway,类似样式并不少见,实现方式有很多,网上随便找一个吧,还不满大街都是。嗯哼,确实不少。但是 !!! 不是讲代码就是讲布局,或者使用方法挺麻烦。 用的时候还要自己手写这部分代码,麻烦不麻烦?作为一名注定要改变世界的程序猿,你让我天天写这个?这是不能忍的。就没有简单的,快捷的,高效的,一句话就能搞定的吗? 有需求就有产品,所以,这个BottomMenu产生了。GitHub项目地址 先来看下效果: How to use: Step 1. Add the JitPack repository to your build fileAdd 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项目地址

优秀的个人博客,低调大师

Android 优化个人封装仿网易新闻可滑动标题栏 TabLayout (文字或图标)

小菜在向朋友推荐了自己修改封装的仿网易顶部滑动标题栏 TabSlideLayout 滑动内容可以是文字也可以是网络图标,其原型为 FlycoTabLayout,但是因为年代很久远,小菜当时技术太渣,存在一些小问题,后期做过一些优化,今天趁机会整理一下。 优化内容: 网络状态不佳情况下,图片加载缓慢,有时加载不出来,如下图: 在部分三星手机上展示效果不佳,图片显示很小,如下图: 可以动态设置图片是否绘色,因有个别需求用户要展示的是彩色的漂亮图标,强制绘色便是画蛇添足。 问题查找: 问题一 的出现主要是因为图片加载方式不太合理,小菜以前用的是 Glide 中 BitmapImageViewTarget(iv) 方式,现在更换为 SimpleTarget<Bitmap>() 方式,两者的区别小菜还不能简洁明了的说清楚,有兴趣的朋友可以详细查看一下源码。 小菜的理解是,BitmapImageViewTarget() 方式优点:对于加载大图的整个过程处理比较好,可以设置加载过程中进度条等展示效果;而且该方式可以加载 Gif 图,也可以对 Gif 图的第一帧图进行绘色,但是没有 Gif 动画效果,就像一张普通的 png 图;缺点则是整体的处理时间较长,在网络状态不佳情况下有可能会加载失败。SimpleTarget() 方式直接优点是图片加载速度快,图片的大小根据 ImagView 来决定,不用重新计算;缺点是直接返回的 Bitmap() 不能加载 Gif 图。综合考虑,小菜觉得 SimpleTarget() 方式较合适。 问题二 的出现主要针对不同手机的适配,问题同样出在 Glide 图片加载部分,以前小菜用的 BitmapImageViewTarget() 并计算图片的宽高,现更改为 SimpleTarget() 方式解决。 问题三 的出现只是因为当时考虑不周全,可以在 attrs 中添加一个属性 is_change_color,并在图片绘色过程中处理一下即可,同时设置 set/get 方法,可以根据业务需求动态修改,详情请直接跳转 源码 Demo。 Tips:针对于问题二,图片布局中 ImageView 建议设置为 match_parent 方式,因为我们用户觉得 wrap_content 方式在部分三星手机上图不如华为手机大,小纠结。 解决方案: Glide 加载方式更换为 SimpleTarget(),如下: Glide.with(mContext).load(title).asBitmap() .placeholder(R.mipmap.top_default_bg).diskCacheStrategy(DiskCacheStrategy.SOURCE) .into(new SimpleTarget<Bitmap>() { @Override public void onResourceReady(Bitmap resource, GlideAnimation<? super Bitmap> glideAnimation) { if (mChangeColor) { resource = BitmapUtil.tintBitmap(resource, (position == 0) ? mTextSelectColor : mTextUnselectColor); } iv_tab_title.setImageBitmap(resource); } }); 在 attrs 中添加是否绘制图片颜色的属性,可以在 xml 或 Java 代码中进行设置: <!-- 设置是否绘制图片颜色 --> <attr name="tl_is_change_color" format="boolean" /> mChangeColor = ta.getBoolean(R.styleable.SlidingTabLayout_tl_is_change_color, true); public boolean isChangeColor() { return mChangeColor; } public void setChangeColor(boolean mChangeColor) { this.mChangeColor = mChangeColor; } 图标绘制统一颜色 图标不绘制颜色.jpg 小菜认为,优化是一个漫长的过程,是随着经验的积累与实际效果的反馈共同进行的,在使用过程中发现不合理的地方还请各位多多指教。 下面的是小菜的公众号,欢迎闲来吐槽哦~ 公众号.jpg

资源下载

更多资源
腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

用户登录
用户注册