首页 文章 精选 留言 我的

精选列表

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

Android 仿微信通讯录列表侧边栏

先看效果图 这里写图片描述 这是比较常见的效果了吧 列表根据首字符的拼音字母来排序,且可以通过侧边栏的字母索引来进行定位 实现这样一个效果并不难,只要自定义一个索引View,然后引入一个可以对汉字进行拼音解析的jar包——pinyin4j-2.5.0即可 首先,先来定义侧边栏控件View,只要直接画出来即可 字母选中项会变为红色,且滑动时背景会变色,此时SideBar并不包含居中的提示文本 public class SideBar extends View { private Paint paint = new Paint(); private int choose = -1; private boolean showBackground; public static String[] letters = {"#", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"}; private OnChooseLetterChangedListener onChooseLetterChangedListener; public SideBar(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } public SideBar(Context context, AttributeSet attrs) { super(context, attrs); } public SideBar(Context context) { super(context); } protected void onDraw(Canvas canvas) { super.onDraw(canvas); if (showBackground) { canvas.drawColor(Color.parseColor("#D9D9D9")); } int height = getHeight(); int width = getWidth(); //平均每个字母占的高度 int singleHeight = height / letters.length; for (int i = 0; i < letters.length; i++) { paint.setColor(Color.BLACK); paint.setAntiAlias(true); paint.setTextSize(25); if (i == choose) { paint.setColor(Color.parseColor("#FF2828")); paint.setFakeBoldText(true); } float x = width / 2 - paint.measureText(letters[i]) / 2; float y = singleHeight * i + singleHeight; canvas.drawText(letters[i], x, y, paint); paint.reset(); } } @Override public boolean dispatchTouchEvent(MotionEvent event) { int action = event.getAction(); float y = event.getY(); int oldChoose = choose; int c = (int) (y / getHeight() * letters.length); switch (action) { case MotionEvent.ACTION_DOWN: showBackground = true; if (oldChoose != c && onChooseLetterChangedListener != null) { if (c > -1 && c < letters.length) { onChooseLetterChangedListener.onChooseLetter(letters[c]); choose = c; invalidate(); } } break; case MotionEvent.ACTION_MOVE: if (oldChoose != c && onChooseLetterChangedListener != null) { if (c > -1 && c < letters.length) { onChooseLetterChangedListener.onChooseLetter(letters[c]); choose = c; invalidate(); } } break; case MotionEvent.ACTION_UP: showBackground = false; choose = -1; if (onChooseLetterChangedListener != null) { onChooseLetterChangedListener.onNoChooseLetter(); } invalidate(); break; } return true; } @Override public boolean onTouchEvent(MotionEvent event) { return super.onTouchEvent(event); } public void setOnTouchingLetterChangedListener(OnChooseLetterChangedListener onChooseLetterChangedListener) { this.onChooseLetterChangedListener = onChooseLetterChangedListener; } public interface OnChooseLetterChangedListener { void onChooseLetter(String s); void onNoChooseLetter(); } } SideBar只是画出了侧边栏索引条而已,不包含居中的提示文本,这个在另一个布局添加即可 public class HintSideBar extends RelativeLayout implements SideBar.OnChooseLetterChangedListener { private TextView tv_hint; private SideBar.OnChooseLetterChangedListener onChooseLetterChangedListener; public HintSideBar(Context context, AttributeSet attrs) { super(context, attrs); LayoutInflater.from(context).inflate(R.layout.view_hint_side_bar, this); initView(); } private void initView() { SideBar sideBar = (SideBar) findViewById(R.id.sideBar); tv_hint = (TextView) findViewById(R.id.tv_hint); sideBar.setOnTouchingLetterChangedListener(this); } @Override public void onChooseLetter(String s) { tv_hint.setText(s); tv_hint.setVisibility(VISIBLE); if (onChooseLetterChangedListener != null) { onChooseLetterChangedListener.onChooseLetter(s); } } @Override public void onNoChooseLetter() { tv_hint.setVisibility(INVISIBLE); if (onChooseLetterChangedListener != null) { onChooseLetterChangedListener.onNoChooseLetter(); } } public void setOnChooseLetterChangedListener(SideBar.OnChooseLetterChangedListener onChooseLetterChangedListener) { this.onChooseLetterChangedListener = onChooseLetterChangedListener; } } HintSideBar通过回调接口来更新居中TextView的文本内容和可见性 使用到的布局 <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <com.czy.demo.SideBar android:id="@+id/sideBar" android:layout_width="30dp" android:layout_height="match_parent" android:layout_alignParentRight="true" /> <TextView android:id="@+id/tv_hint" android:layout_width="70dp" android:layout_height="70dp" android:layout_centerInParent="true" android:background="#4b0e0e0e" android:gravity="center" android:textColor="#ffffff" android:textSize="30sp" android:visibility="invisible" /> </RelativeLayout> 此时就完成了索引View的绘制,不过定位功能还需要再通过回调接口来完成 引入jar包后,先来设定一个工具类,包含一个可以解析字符串的方法,返回值为首字符对应的拼音首字母或者为包含一个空格的char类型数据 public class Utils { /** * 如果字符串的首字符为汉字,则返回该汉字的拼音大写首字母 * 如果字符串的首字符为字母,也转化为大写字母返回 * 其他情况均返回' ' * * @param str 字符串 * @return 首字母 */ public static char getHeadChar(String str) { if (str != null && str.trim().length() != 0) { char[] strChar = str.toCharArray(); char headChar = strChar[0]; //如果是大写字母则直接返回 if (Character.isUpperCase(headChar)) { return headChar; } else if (Character.isLowerCase(headChar)) { return Character.toUpperCase(headChar); } // 汉语拼音格式输出类 HanyuPinyinOutputFormat hanYuPinOutputFormat = new HanyuPinyinOutputFormat(); hanYuPinOutputFormat.setCaseType(UPPERCASE); hanYuPinOutputFormat.setToneType(WITHOUT_TONE); if (String.valueOf(headChar).matches("[\\u4E00-\\u9FA5]+")) { try { String[] stringArray = PinyinHelper.toHanyuPinyinStringArray(headChar, hanYuPinOutputFormat); if (stringArray != null && stringArray[0] != null) { return stringArray[0].charAt(0); } } catch (BadHanyuPinyinOutputFormatCombination e) { return ' '; } } } return ' '; } } 然后再定义一个实体类,包含用户名,电话,用户名首字符的拼音首字母等三个属性 需要实现Comparable 接口,用于排序 public class User implements Comparable { private String userName; private String phone; private char headLetter; public User(String userName, String phone) { this.userName = userName; this.phone = phone; headLetter = Utils.getHeadChar(userName); } public String getUserName() { return userName; } public String getPhone() { return phone; } public char getHeadLetter() { return headLetter; } @Override public boolean equals(Object object) { if (this == object) { return true; } if (object == null || getClass() != object.getClass()) { return false; } User that = (User) object; return getUserName().equals(that.getUserName()) && getPhone().equals(that.getPhone()); } @Override public int compareTo(Object object) { if (object instanceof User) { User that = (User) object; if (getHeadLetter() == ' ') { if (that.getHeadLetter() == ' ') { return 0; } return -1; } if (that.getHeadLetter() == ' ') { return 1; } else if (that.getHeadLetter() > getHeadLetter()) { return -1; } else if (that.getHeadLetter() == getHeadLetter()) { return 0; } return 1; } else { throw new ClassCastException(); } } } 主布局文件如下 <?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <android.support.v7.widget.RecyclerView android:id="@+id/rv_userList" android:layout_width="match_parent" android:layout_height="match_parent" /> <com.czy.demo.HintSideBar android:id="@+id/hintSideBar" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="right" /> </FrameLayout> 联系人列表使用的是RecyclerView,还需要定义一个Adapter public class UserAdapter extends RecyclerView.Adapter<UserAdapter.UserHolder> { private List<User> userList; private LayoutInflater inflater; public UserAdapter(Context context) { inflater = LayoutInflater.from(context); userList = new ArrayList<>(); } @Override public UserHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = inflater.inflate(R.layout.item_user, parent, false); return new UserHolder(view); } @Override public void onBindViewHolder(UserHolder holder, int position) { holder.tv_userName.setText(userList.get(position).getUserName()); holder.tv_phone.setText(userList.get(position).getPhone()); } public void setData(List<User> userList) { this.userList.clear(); this.userList = userList; } public int getFirstPositionByChar(char sign) { if (sign == '#') { return 0; } for (int i = 0; i < userList.size(); i++) { if (userList.get(i).getHeadLetter() == sign) { return i; } } return -1; } @Override public int getItemCount() { return userList.size(); } class UserHolder extends RecyclerView.ViewHolder { public TextView tv_userName; public TextView tv_phone; public UserHolder(View itemView) { super(itemView); tv_userName = (TextView) itemView.findViewById(R.id.tv_userName); tv_phone = (TextView) itemView.findViewById(R.id.tv_phone); } } } 以下方法用于获取联系人列表中第一个首字符为sign的item的位置 public int getFirstPositionByChar(char sign) 主Activity代码如下 public class MainActivity extends AppCompatActivity implements SideBar.OnChooseLetterChangedListener { private List<User> userList; private UserAdapter adapter; private RecyclerView rv_userList; private LinearLayoutManager manager; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); supportRequestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.activity_main); HintSideBar hintSideBar = (HintSideBar) findViewById(R.id.hintSideBar); rv_userList = (RecyclerView) findViewById(R.id.rv_userList); hintSideBar.setOnChooseLetterChangedListener(this); manager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false); rv_userList.setLayoutManager(manager); userList = new ArrayList<>(); adapter = new UserAdapter(this); initData(); adapter.setData(userList); rv_userList.setAdapter(adapter); } @Override public void onChooseLetter(String s) { int i = adapter.getFirstPositionByChar(s.charAt(0)); if (i == -1) { return; } manager.scrollToPositionWithOffset(i, 0); } @Override public void onNoChooseLetter() { } } initData()用于向Adapter填充数据 public void initData() { User user1 = new User("陈", "12345678"); User user2 = new User("赵", "12345678"); ... userList.add(user1); userList.add(user2); ... Collections.sort(userList); adapter.notifyDataSetChanged(); } 这样,整个效果就都完成了 代码我已上传到GitHub——HintSideBar

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

信通院发布2020年信通业十大趋势:AI从感知走向认知,量子计算落地仍需十年

云栖号:https://www.aliyun.com/#module-yedOfott8第一手的上云资讯,不同行业精选的上云企业案例库,基于众多成功案例萃取而成的最佳实践,助力您上云决策! 大数据文摘出品 在本世纪第二个十年结束之前,中国信通院副院长余晓晖在“2020年中国信通院ICT深度观察报告会”上,发布了信息通信业十大趋势,通过专业知识对行业未来发展做出预测。 其中还涉及不少公众关心的问题,比如摩尔定律是否会终结、人工智能能发展到什么程度、中国互联网产业还能不能保持高增长,以及上量子计算机何时能够落地实用等。 趋势一:5G时代起航,开创数字化转型的无限空间 报告认为,在网络覆盖方面,未来5年,将全面建成覆盖城乡、品质优良的5G网络基础设施。在用户数方面,预计2024年全球5G用户将近12个亿,我国5G用户将超过7个亿,渗透率达到约45%。 在产业赋能和经济带动方面,5G全面赋能工业、交通、能源、医疗及经济社会的各个领域,推动生产生活方式的新一轮变革。预计2024年5G直接带动经济产出增加值累计达到2万亿元,间接带动的经济总产出增加值累计达到6万亿元。 在网络覆盖方面,未来5年,将全面建成覆盖城乡、品质优良的5G网络基础设施。在用户数方面,预计2024年全球5G用户将近12个亿,我国5G用户将超过7个亿,渗透率达到约45%。 趋势二:信息网络演进重构,构筑数字经济发展的关键基石 报告认为,信息网络将以高速泛在、智能敏捷、集约高效、安全可信为特点演进重构,集感知、连接、存储、计算、处理、交换等为一体,成为数字基础设施。 趋势三:计算能力升级,打造无处不在的万物智能 未来5年,量子、类脑等颠覆式技术实现小范围应用突破,摩尔定律仍占据主导,面向细分领域的芯片架构/异构系统创新以及计算资源的灵活部署成为关键。 报告认为,5G加速边缘计算的规模应用,未来50%的数据将在边缘实现处理;面向安防、语音、自动驾驶等领域的专用智能计算芯片和异构加速系统创新活跃;结合人脑运行机制的无/弱监督学习逐步迈入工程应用;医疗健康领域的脑控(脑机接口)产品将得到应用;量子退火开始应用于人工智能领域,提升并行算法能力。 趋势四:从感知到认知,人工智能迈入后深度学习时代 算法加速向后深度学习时代演进;算力面向特定场景的需求,走向多元定制化;感知应用更加广泛,认知应用逐步成熟。 趋势五:承载可信数据,区块链打造可信任数字社会新型基础 当前,区块链主要解决多主体间信息流可信穿透问题,打通数据孤岛。区块链技术不断创新、区块链应用方向不断拓展、区块链治理与监管不断完善成为区块链未来发展的三大重点。区块链与人工智能、物联网等技术深度融合,共同组成泛在、信任的数字社会新型基础。 趋势六:“一深一广”,工业互联网平台成为数字化转型核心载体 报告分析,“一深”是指提供数字线程与建模工具,支撑数字孪生构建,更精准描述和优化物理世界,构建智能决策载体;“一广”是指汇集优化生产要素,驱动模式创新与资源配置,成为未来产业生态核心载体。 趋势七:技术与需求驱动,推动安全理念与实践双向变革 报告认为,ICT技术深度融合,虚拟化架构快速兴起,万物互联时代来临,数字浪潮推动各领域转型,带来网络安全新需求。技术演进+应对需求,驱动网络安全向按需安全、智能安全、主动安全、安全一体化方向发展。 趋势八:冲破阴霾,ICT产业开启新一轮增长周期 值得关注的是,5G、人工智能、边缘计算、区块链等新一代信息技术创新,经济社会数字化转型驱动ICT产业新一轮增长。与此同时,由于全球政治和贸易格局的不确定性影响经济走势,技术创新、投资回报、商业模式和产业生态的不确定性加深,未来五年ICT产业增长的不确定性也在加深。 趋势九:开放合作,共塑全球数字治理规则体系 围绕数据跨境流动、知识产权保护、数字贸易、数字税收等规则正成为数字经济时代全球治理规则建构的重要内容,亟需在分歧与争议中寻找利益契合点,共塑全球数字治理规则体系。 趋势十:蓄势待发,量子信息技术探索中寻求突 报告认为,在量子通信方面,基于量子密钥分发(QKD)的量子保密通信将在高安全性需求的专网领域继续开展应用探索,但工程化和实用化水平仍需进一步提升;量子保密通信的规模化网络建设应充分论证,分阶段稳步实施;基于量子隐形传态(QT)和量子存储中继实现量子态信息传输与组网,是未来量子通信发展的主要方向。 在量子计算方面,量子计算优越性得到实验验证;专用量子计算机用于解决经典计算难以处理的特定问题,未来3-5年有望在优化、模拟、人工智能等领域取得突破并探索实际应用;通用量子计算机用于解决普适性问题,需量子比特数量及质量,编码、算法和软件等进一步提升,技术路线将逐步收敛,业界普遍预计突破仍需十年以上。 在量子测量方面,各领域技术成熟度和发展水平不一,量子时间基准、惯性导航、目标识别等方向样机系统有望在通信网络、航空航天和国防等领域率先应用;量子测量设备和系统的集成化与芯片化将是未来长期发展目标。 原文发布时间:2019-12-27本文作者:大数据文摘出品本文来自阿里云云栖号合作伙伴“大数据文摘”,了解相关信息可以关注“大数据文摘” 云栖号:https://www.aliyun.com/#module-yedOfott8第一手的上云资讯,不同行业精选的上云企业案例库,基于众多成功案例萃取而成的最佳实践,助力您上云决策!

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

基于微信小程序的校园失物招领系统

随着高校规模扩大与师生活动频次提升,校园内物品遗失与拾获现象日益普遍,据调研超过70%的师生有过校园失物经历,而传统失物招领模式已难以适配校园服务需求。当前多数高校仍依赖公告栏张贴、人工登记等传统方式,存在信息传播范围有限、更新滞后、匹配效率低下等问题,导致失物找回率不足15%,既给失主带来不便与损失,也增加了校园管理负担。

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

腾讯云软件源

腾讯云软件源

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

Rocky Linux

Rocky Linux

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

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册