首页 文章 精选 留言 我的

精选列表

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

Android 底部导航栏添加消息数目提示

效果图 写一篇短小精悍,好用的知识积累吧。开发中时常会出现信息提醒,新内容提示等等一堆问题。其实就是在各种控件或者是item上面加“小圆点”。网上一搜一大堆。。。但是感觉说的好多。我们只需要基本功能2333. 下面介绍三种方式吧,但是大体套路相同。 一、解需求思路 在 RadioGroup 的 RadioButton 上面直接加小圆点,对于我来说实现有点困难,因为我下面还有文字。搞不好,文字就挤没了。 所有我现在在原有的 RadioGroup 上面加一层覆盖物,类似于 ui 常常接触的图层。 二、布局 就是在原有的 RadioGroup 上覆盖一层透明的 button 并且保证位置相同相同 <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/colorGrayBg" tools:context="cn.ln80.happybirdcloud119.activity.MainActivity"> <android.support.v4.view.ViewPager android:id="@+id/vp_main_page" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginBottom="61dp" /> <!--底栏--> <RadioGroup android:id="@+id/rg_main_bottom" android:layout_width="match_parent" android:layout_height="@dimen/iconsize_60" android:layout_alignParentBottom="true" android:background="@android:color/white" android:orientation="horizontal"> <RadioButton android:id="@+id/rb_main_task" style="@style/BottomRadio" android:drawableTop="@drawable/bg_bottom_task" android:text="可视化" android:textColor="@drawable/txt_bottom_notify" /> <RadioButton android:id="@+id/rb_main_notify" style="@style/BottomRadio" android:layout_height="match_parent" android:drawableTop="@drawable/bg_bottom_notify" android:text="通知" android:textColor="@drawable/txt_bottom_notify" /> <RadioButton android:id="@+id/rb_main_home" style="@style/BottomRadio" android:layout_marginTop="@dimen/widget_margin_5" android:checked="true" android:drawableTop="@drawable/bg_bottom_home" android:text="主页" android:textColor="@drawable/txt_bottom_notify" /> <RadioButton android:id="@+id/rb_main_inspect" style="@style/BottomRadio" android:drawableTop="@drawable/bg_bottom_inspect" android:text="巡检" android:textColor="@drawable/txt_bottom_notify" /> <RadioButton android:id="@+id/rb_main_mine" style="@style/BottomRadio" android:drawableTop="@drawable/bg_bottom_mine" android:text="我的" android:textColor="@drawable/txt_bottom_notify" /> </RadioGroup> <LinearLayout android:layout_width="match_parent" android:layout_height="@dimen/iconsize_60" android:layout_alignParentBottom="true" android:orientation="horizontal"> <Button android:id="@+id/btn_main_task" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:background="@null" /> <Button android:id="@+id/btn_main_notification" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:background="@null" /> <Button android:id="@+id/btn_main_home" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:background="@null" /> <Button android:id="@+id/btn_main_inspect" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:background="@null" /> <Button android:id="@+id/btn_main_my" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:background="@null" /> </LinearLayout> </RelativeLayout> 三、第一种方式 import android.content.Context; import android.graphics.Color; import android.graphics.Typeface; import android.graphics.drawable.ShapeDrawable; import android.graphics.drawable.shapes.RoundRectShape; import android.util.AttributeSet; import android.util.Log; import android.util.TypedValue; import android.view.Gravity; import android.view.View; import android.view.ViewGroup; import android.widget.FrameLayout; import android.widget.LinearLayout; import android.widget.TabWidget; /** * Content: * Actor:韩小呆 ヾ(゚▽゚)ノ * Time: 2018/8/6 17:47 * Update: * Time: */ public class BadgeView extends android.support.v7.widget.AppCompatTextView { private boolean mHideOnNull = true; public BadgeView(Context context) { this(context, null); } public BadgeView(Context context, AttributeSet attrs) { this(context, attrs, android.R.attr.textViewStyle); } public BadgeView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(); } private void init() { if (!(getLayoutParams() instanceof LinearLayout.LayoutParams)) { LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams( android.view.ViewGroup.LayoutParams.WRAP_CONTENT, android.view.ViewGroup.LayoutParams.WRAP_CONTENT, Gravity.END | Gravity.TOP); setLayoutParams(layoutParams); } // set default font setTextColor(Color.WHITE); setTypeface(Typeface.DEFAULT_BOLD); setTextSize(TypedValue.COMPLEX_UNIT_SP, 11); setPadding(dip2Px(5), dip2Px(1), dip2Px(5), dip2Px(1)); // set default background setBackground(9, Color.parseColor("#d3321b")); setGravity(Gravity.CENTER); // default values setHideOnNull(true); setBadgeCount(0); } public void setBackground(int dipRadius, int badgeColor) { int radius = dip2Px(dipRadius); float[] radiusArray = new float[]{radius, radius, radius, radius, radius, radius, radius, radius}; RoundRectShape roundRect = new RoundRectShape(radiusArray, null, null); ShapeDrawable bgDrawable = new ShapeDrawable(roundRect); bgDrawable.getPaint().setColor(badgeColor); setBackground(bgDrawable); } /** * @return Returns true if view is hidden on badge value 0 or null; */ public boolean isHideOnNull() { return mHideOnNull; } /** * @param hideOnNull the hideOnNull to set */ public void setHideOnNull(boolean hideOnNull) { mHideOnNull = hideOnNull; setText(getText()); } /* * (non-Javadoc) * * @see android.widget.TextView#setText(java.lang.CharSequence, android.widget.TextView.BufferType) */ @Override public void setText(CharSequence text, BufferType type) { if (isHideOnNull() && (text == null || text.toString().equalsIgnoreCase("0"))) { setVisibility(View.GONE); } else { setVisibility(View.VISIBLE); } super.setText(text, type); } public void setBadgeCount(int count) { setText(String.valueOf(count)); } public Integer getBadgeCount() { if (getText() == null) { return null; } String text = getText().toString(); try { return Integer.parseInt(text); } catch (NumberFormatException e) { return null; } } public void setBadgeGravity(int gravity) { FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) getLayoutParams(); params.gravity = gravity; setLayoutParams(params); } public int getBadgeGravity() { FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) getLayoutParams(); return params.gravity; } public void setBadgeMargin(int dipMargin) { setBadgeMargin(dipMargin, dipMargin, dipMargin, dipMargin); } public void setBadgeMargin(int leftDipMargin, int topDipMargin, int rightDipMargin, int bottomDipMargin) { FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) getLayoutParams(); params.leftMargin = dip2Px(leftDipMargin); params.topMargin = dip2Px(topDipMargin); params.rightMargin = dip2Px(rightDipMargin); params.bottomMargin = dip2Px(bottomDipMargin); setLayoutParams(params); } public int[] getBadgeMargin() { FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) getLayoutParams(); return new int[]{params.leftMargin, params.topMargin, params.rightMargin, params.bottomMargin}; } public void incrementBadgeCount(int increment) { Integer count = getBadgeCount(); if (count == null) { setBadgeCount(increment); } else { setBadgeCount(increment + count); } } public void decrementBadgeCount(int decrement) { incrementBadgeCount(-decrement); } /* * Attach the BadgeView to the TabWidget * * @param target the TabWidget to attach the BadgeView * * @param tabIndex index of the tab */ public void setTargetView(TabWidget target, int tabIndex) { View tabView = target.getChildTabViewAt(tabIndex); setTargetView(tabView); } /* * Attach the BadgeView to the target view * * @param target the view to attach the BadgeView */ public void setTargetView(View target) { if (getParent() != null) { ((ViewGroup) getParent()).removeView(this); } if (target == null) { return; } if (target.getParent() instanceof FrameLayout) { ((FrameLayout) target.getParent()).addView(this); } else if (target.getParent() instanceof ViewGroup) { ViewGroup parentContainer = (ViewGroup) target.getParent(); int groupIndex = parentContainer.indexOfChild(target); parentContainer.removeView(target); FrameLayout badgeContainer = new FrameLayout(getContext()); ViewGroup.LayoutParams parentLayoutParams = target.getLayoutParams(); badgeContainer.setLayoutParams(parentLayoutParams); target.setLayoutParams(new ViewGroup.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); parentContainer.addView(badgeContainer, groupIndex, parentLayoutParams); badgeContainer.addView(target); badgeContainer.addView(this); } else if (target.getParent() == null) { Log.e(getClass().getSimpleName(), "ParentView is needed"); } } /* * converts dip to px */ private int dip2Px(float dip) { return (int) (dip * getContext().getResources().getDisplayMetrics().density + 0.5f); } } 将这个代码直接 C、V 到自己的 类内,然后在使用的地方直接填写如下代码: BadgeView badgeView = new BadgeView(this); badgeView.setTargetView(btnMainNotification); badgeView.setBadgeCount(12); badgeView.setBackground(20, getResources().getColor(R.color.colorRed)); 这个自定义的代码是一位外国大佬搞出来的,原版代码在这,欢迎查阅:BadgeView。 这里面的一些属性: //设置依附的控件 setTargetView(View) //设置显示的数字 setBadgeCount(int) //设置显示的位置 setBadgeGravity(Gravity) //设置背景色 setBackgroundColor() //设置背景图片 setBackgroundResource() //设置显示字体 比如说加粗、倾斜、啥的 setTypeface() //设置字体阴影 setShadowLayer() 四、第二种方式 引用这位大佬的依赖 :BadgeView ---> compile 'q.rorbin:badgeview:1.1.3' 代码代码中使用: new QBadgeView(this).bindTarget(btnMainNotification).setBadgeText("99+").setBadgeBackgroundColor(getResources().getColor(R.color.colorRed)); 可以返回一个 Badge 对象提高开发者操作。 一些常用属性 //设置Badge数字 setBadgeNumber(int i); //设置Badge文本 setBadgeText(String text); //设置文本字体大小 setBadgeTextSize(int size); // 设置文本颜色 setBadgeTextColor(); //设置是否显示精确模式数值 setExactMode(); //设置Badge相对于TargetView的位置 setBadgeGravity(); //设置外边距 setGravityOffset(); //设置内边距 setBadgePadding(); //设置背景色 setBadgeBackgroundColor(); //设置背景图片 setBadgeBackground(); //设置是否显示阴影 setShowShadow(); //打开拖拽消除模式并设置监听 setOnDragStateChangedListener(); //描边 stroke(); //隐藏Badge hide(); 官方的演示 五、最后一种实现方式 BGABadgeView-Android 六、总结 总体的实现思路就是,在底部导航栏覆盖一层透明的布局,然后在透明布局内的控件上面依赖(寄生)上小圆点。

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

关于最近的进度和Docker的消息

Docker容器的优势是轻量和可移植,所以承载它的操作系统也应该尽量迎合这个特性。 我想这也是Docker准备使用Alpine Linux替代之前的Ubuntu做为官方默认的宿主环境的原因(基础镜像)。 Vagrant 是很好的个人开发环境,推荐大家可以试试。 关于Docker1.9版本解读: 跨主机网络:新的网络设备可以支持用户创建基于多个主机的虚拟网络,使荣期间可以跨网络通信。 持久化存储:Docker 1.9 包含一个重新设计的完整存储卷管理系统使得用户可以更加容易的从前端来管理这些插件。 Docker Swarm 1.0:修复bug并对其进行大量优化。Docker公司在在 1000 个节点上测试了 30000 个容器,swarm 可以如丝般润滑的运行。 Docker Engine 1.9:新的Docker Engine中加入了如下新特性:Dockerfile 的构建时参数,并行镜像 pull,自定义 stop 信号,AWS CloudWatch logging driver和磁盘 I/O metrics。 Docker Compose 1.5:Docker Compose 是一个定义并运行多容器应用的工具,它有如下更新:支持 Windows,Compose 文件中的环境变量,对多环境更好的支持,和 networking 集成和Compose file 校验。 Docker Toolbox:这个工具可以使Mac和Windows支持这些新特性。 Docker Registry 2.2:主要做了以下更新:支持 Google Cloud Storage,只读模式,支持可配置主机名,基于文件的存在配置和可配置的 HTTP 健康检查和可配置的 HTTP 响应 headers。 本文转自cantgis 51CTO博客,原文链接:http://blog.51cto.com/cantgis/1750936,如需转载请自行联系原作者

资源下载

更多资源
腾讯云软件源

腾讯云软件源

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

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

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文件系统,支持十年生命周期更新。

用户登录
用户注册