精华内容
下载资源
问答
  • Java实现汉字转换为拼音- Java - 技术应用 创建时间:2010年7月20日(星期二) 中午11:46 | 分类:分类 | 天气:广州多云 | 字数:9779 | 发送到我Qzone | 另存为... | 打印 [code="java"]package wjw...
    Java实现汉字转换为拼音- Java - 技术应用 创建时间:2010年7月20日(星期二) 中午11:46 | 分类:未分类 | 天气:广州多云 | 字数:9779 | 发送到我的Qzone | 另存为... | 打印 
    package wjw;      
    public class ChinesetoPinyin {
    private static int[] pyvalue = new int[] { -20319, -20317, -20304, -20295, -20292, -20283, -20265, -20257, -20242, -20230, -20051, -20036, -20032, -20026, -20002, -19990, -19986, -19982, -19976, -19805, -19784, -19775, -19774, -19763, -19756, -19751, -19746, -19741, -19739, -19728, -19725, -19715, -19540, -19531, -19525, -19515, -19500, -19484, -19479, -19467, -19289, -19288, -19281, -19275, -19270, -19263, -19261, -19249, -19243, -19242, -19238, -19235, -19227, -19224, -19218, -19212, -19038, -19023, -19018, -19006, -19003, -18996, -18977, -18961, -18952, -18783, -18774, -18773, -18763, -18756, -18741, -18735, -18731, -18722, -18710, -18697, -18696, -18526, -18518, -18501, -18490, -18478, -18463, -18448, -18447, -18446, -18239, -18237, -18231, -18220, -18211, -18201, -18184, -18183, -18181, -18012, -17997, -17988, -17970, -17964, -17961, -17950, -17947, -17931, -17928, -17922, -17759, -17752, -17733, -17730, -17721, -17703, -17701, -17697, -17692, -17683, -17676, -17496, -17487, -17482, -17468, -17454, -17433, -17427, -17417, -17202, -17185, -16983, -16970, -16942, -16915, -16733, -16708, -16706, -16689, -16664, -16657, -16647, -16474, -16470, -16465, -16459, -16452, -16448, -16433, -16429, -16427, -16423, -16419, -16412, -16407, -16403, -16401, -16393, -16220, -16216, -16212, -16205, -16202, -16187, -16180, -16171, -16169, -16158, -16155, -15959, -15958, -15944, -15933, -15920, -15915, -15903, -15889, -15878, -15707, -15701, -15681, -15667, -15661, -15659, -15652, -15640, -15631, -15625, -15454, -15448, -15436, -15435, -15419, -15416, -15408, -15394, -15385, -15377, -15375, -15369, -15363, -15362, -15183, -15180, -15165, -15158, -15153, -15150, -15149, -15144, -15143, -15141, -15140, -15139, -15128, -15121, -15119, -15117, -15110, -15109, -14941, -14937, -14933, -14930, -14929, -14928, -14926, -14922, -14921, -14914, -14908, -14902, -14894, -14889, -14882, -14873, -14871, -14857, -14678, -14674, -14670, -14668, -14663, -14654, -14645, -14630, -14594, -14429, -14407, -14399, -14384, -14379, -14368, -14355, -14353, -14345, -14170, -14159, -14151, -14149, -14145, -14140, -14137, -14135, -14125, -14123, -14122, -14112, -14109, -14099, -14097, -14094, -14092, -14090, -14087, -14083, -13917, -13914, -13910, -13907, -13906, -13905, -13896, -13894, -13878, -13870, -13859, -13847, -13831, -13658, -13611, -13601, -13406, -13404, -13400, -13398, -13395, -13391, -13387, -13383, -13367, -13359, -13356, -13343, -13340, -13329, -13326, -13318, -13147, -13138, -13120, -13107, -13096, -13095, -13091, -13076, -13068, -13063, -13060, -12888, -12875, -12871, -12860, -12858, -12852, -12849, -12838, -12831, -12829, -12812, -12802, -12607, -12597, -12594, -12585, -12556, -12359, -12346, -12320, -12300, -12120, -12099, -12089, -12074, -12067, -12058, -12039, -11867, -11861, -11847, -11831, -11798, -11781, -11604, -11589, -11536, -11358, -11340, -11339, -11324, -11303, -11097, -11077, -11067, -11055, -11052, -11045, -11041, -11038, -11024, -11020, -11019, -11018, -11014, -10838, -10832, -10815, -10800, -10790, -10780, -10764, -10587, -10544, -10533, -10519, -10331, -10329, -10328, -10322, -10315, -10309, -10307, -10296, -10281, -10274, -10270, -10262, -10260, -10256, -10254 };

    private static String[] pystr = new String[] { "a", "ai", "an", "ang", "ao", "ba", "bai", "ban", "bang", "bao", "bei", "ben", "beng", "bi", "bian", "biao", "bie", "bin", "bing", "bo", "bu", "ca", "cai", "can", "cang", "cao", "ce", "ceng", "cha", "chai", "chan", "chang", "chao", "che", "chen", "cheng", "chi", "chong", "chou", "chu", "chuai", "chuan", "chuang", "chui", "chun", "chuo", "ci", "cong", "cou", "cu", "cuan", "cui", "cun", "cuo", "da", "dai", "dan", "dang", "dao", "de", "deng", "di", "dian", "diao", "die", "ding", "diu", "dong", "dou", "du", "duan", "dui", "dun", "duo", "e", "en", "er", "fa", "fan", "fang", "fei", "fen", "feng", "fo", "fou", "fu", "ga", "gai", "gan", "gang", "gao", "ge", "gei", "gen", "geng", "gong", "gou", "gu", "gua", "guai", "guan", "guang", "gui", "gun", "guo", "ha", "hai", "han", "hang", "hao", "he", "hei", "hen", "heng", "hong", "hou", "hu", "hua", "huai", "huan", "huang", "hui", "hun", "huo", "ji", "jia", "jian", "jiang", "jiao", "jie", "jin", "jing", "jiong", "jiu", "ju", "juan", "jue", "jun", "ka", "kai", "kan", "kang", "kao", "ke", "ken", "keng", "kong", "kou", "ku", "kua", "kuai", "kuan", "kuang", "kui", "kun", "kuo", "la", "lai", "lan", "lang", "lao", "le", "lei", "leng", "li", "lia", "lian", "liang", "liao", "lie", "lin", "ling", "liu", "long", "lou", "lu", "lv", "luan", "lue", "lun", "luo", "ma", "mai", "man", "mang", "mao", "me", "mei", "men", "meng", "mi", "mian", "miao", "mie", "min", "ming", "miu", "mo", "mou", "mu", "na", "nai", "nan", "nang", "nao", "ne", "nei", "nen", "neng", "ni", "nian", "niang", "niao", "nie", "nin", "ning", "niu", "nong", "nu", "nv", "nuan", "nue", "nuo", "o", "ou", "pa", "pai", "pan", "pang", "pao", "pei", "pen", "peng", "pi", "pian", "piao", "pie", "pin", "ping", "po", "pu", "qi", "qia", "qian", "qiang", "qiao", "qie", "qin", "qing", "qiong", "qiu", "qu", "quan", "que", "qun", "ran", "rang", "rao", "re", "ren", "reng", "ri", "rong", "rou", "ru", "ruan", "rui", "run", "ruo", "sa", "sai", "san", "sang", "sao", "se", "sen", "seng", "sha", "shai", "shan", "shang", "shao", "she", "shen", "sheng", "shi", "shou", "shu", "shua", "shuai", "shuan", "shuang", "shui", "shun", "shuo", "si", "song", "sou", "su", "suan", "sui", "sun", "suo", "ta", "tai", "tan", "tang", "tao", "te", "teng", "ti", "tian", "tiao", "tie", "ting", "tong", "tou", "tu", "tuan", "tui", "tun", "tuo", "wa", "wai", "wan", "wang", "wei", "wen", "weng", "wo", "wu", "xi", "xia", "xian", "xiang", "xiao", "xie", "xin", "xing", "xiong", "xiu", "xu", "xuan", "xue", "xun", "ya", "yan", "yang", "yao", "ye", "yi", "yin", "ying", "yo", "yong", "you", "yu", "yuan", "yue", "yun", "za", "zai", "zan", "zang", "zao", "ze", "zei", "zen", "zeng", "zha", "zhai", "zhan", "zhang", "zhao", "zhe", "zhen", "zheng", "zhi", "zhong", "zhou", "zhu", "zhua", "zhuai", "zhuan", "zhuang", "zhui", "zhun", "zhuo", "zi", "zong", "zou", "zu", "zuan", "zui", "zun", "zuo" };
    private StringBuilder buffer;

    private String resource;

    private static ChinesetoPinyin testchinese = new ChinesetoPinyin();

    public static ChinesetoPinyin getInstance() {
    return testchinese;
    }

    public String getResource() {
    return resource;
    }

    public void setResource(String resource) {
    this.resource = resource;
    }

    private int getChsAscii(String chs) {
    int asc = 0;
    try {
    byte[] bytes = chs.getBytes("gb2312");
    if (bytes == null || bytes.length > 2 || bytes.length <= 0) { // 错误
    throw new RuntimeException("illegal resource string");
    } if (bytes.length == 1) { // 英文字符
    asc = bytes[0];
    }
    if (bytes.length == 2) { // 中文字符
    int hightByte = 256 + bytes[0];
    int lowByte = 256 + bytes[1];
    asc = (256 * hightByte + lowByte) - 256 * 256;
    }
    } catch (Exception e) {
    System.out.println("ERROR:ChineseSpelling.class-getChsAscii(String chs)"+ e);
    // e.printStackTrace();
    } return asc;
    }
    public String convert(String str) {
    String result = null;
    int ascii = getChsAscii(str);
    // System.out.println(ascii);
    if (ascii > 0 && ascii < 160) {
    result = String.valueOf((char) ascii);
    } else {
    for (int i = (pyvalue.length - 1); i >= 0; i--) {
    if (pyvalue[i] <= ascii) {
    result = pystr[i];
    break;
    }
    }
    }
    return result;
    }

    public String getSelling(String chs) {
    String key, value;
    buffer = new StringBuilder();
    for (int i = 0; i < chs.length(); i++) {
    key = chs.substring(i, i + 1);
    if (key.getBytes().length == 2) {
    value = (String) convert(key);
    if (value == null) {
    value = "unknown";
    }
    } else {
    value = key;
    }
    buffer.append(value);
    }
    return buffer.toString();
    }

    public String getSpelling() {
    return this.getSelling(this.getResource());
    }

    public static void main(String[] args) {
    ChinesetoPinyin finder = ChinesetoPinyin.getInstance();
    String testStr = "韩国人是你们吗";
    System.out.println("测试中文转拼音:"+testStr+"----"
    + finder.getSelling(testStr));
    }



    }
    展开全文
  • 将文件中两个Dll文件替换,快捷方式中dll文件,即可实现微软雅黑效果 "C:\Program Files\Common Files\microsoft shared\IME14\IMESC" 原创, 好久没有传上来 CSDN首发 说明:文件默认您已经安装了微软雅黑...
  • 1、10.9.8 由于全拼输入法的拼音库太过全面,有部分多音字的第一个拼音却不是常用的拼音,导致汉字转声母有时不准确, 决定抛弃全拼输入法的拼音库,改为采用从互联网下载的较完整的汉字各种编码汇总.xls>拼音字库...
  • 1、10.9.8 由于全拼输入法的拼音库太过全面,有部分多音字的第一个拼音却不是常用的拼音,导致汉字转声母有时不准确, 决定抛弃全拼输入法的拼音库,改为采用从互联网下载的较完整的汉字各种编码汇总.xls>拼音字库...
  • 最近在学习Redis,根据《Redis设计与实现》书本来学习,当中遇到许多接触过专业名词,统一记录一下 ·字典 字典是Redis数据库底层实现,所以搞清楚字典这一含义十分有必要。 定义:字典又称符号表(symbol ...

    最近在学习Redis,根据《Redis设计与实现》书本来学习,当中遇到许多未接触过的专业名词,统一记录一下,由于只是简单解释定义,这篇文章仅作为简单参考,如果是想探究更深层次我也会提供一些参考链接

    ·字典

    字典是Redis数据库的底层实现,所以搞清楚字典这一含义十分有必要。

    1. 定义:字典又称符号表(symbol table)、关联数组(associative array),是一种保存键值对的抽象数据结构。
    2. 举个例子,在维基百科上有一段话比较通俗的解释了字典:当你需要拨打张三的电话,首先,你需要去找到Z开头的字典开始,然后再通过比对后续拼音字典序来进行查找。

    ·跳跃表

    跳跃表(skiplist)是一种没见过的数据结构,在性能上几乎能媲美红黑树,但是跳跃表实现比红黑树简单太多了。

    1. 定义:跳跃表是一种有序数据结构,支持平均O(logN),最坏O(N)复杂度的节点查找。
    2. 特性:如果把list看作一个x轴,那么skiplist是一个开通了y轴的list,他的每个节点是否向上扩展完全取决于随机(敲重点!!!),采取抛硬币方式是否向上扩展,在一定数量内可能接过不是那么准确,但是当数据量足够大时,概率时趋向于50%,不同于传统二叉树,跳跃表实现十分的简单,下面简单做一个图来表示跳跃表数据结构。
      在这里插入图片描述

    关于跳跃表详细可参考以下链接:什么是跳跃表?

    ·快速列表(quicklist)

    在3.2版之后,Redis推出了快速列表(quicklist),用于实现链表底层,它结合了ziplist和linklist两种数据结构思想实现,在ziplist结构中,


    更新于5/27

    展开全文
  • 报错显示将对象引用设置到对象实例 private void InformationSave_Load(object sender, EventArgs e) { //设置列数目 dataGridView1.ColumnCount = 11; dataGridView1.ColumnHeadersVisible = true;...
  • 位驱动程序来实现的, 并且不增加另外的文件, 仍保持了原袖珍版单文件汉 字系统这一独一无二的特色. 在袖珍版(96-12-31)中解决了在TWAY V3.1 和 PDOS 95中存在的当DOS运行了DOS4GW的应用程序时切屏的死机现象. 3. ...
  • /为班级30个人姓名设计一个哈希表,假设姓名用汉语拼音表示。要求用除留余数法 构造哈希函数,用线性探测再散列法处理冲突,平均查找长度上限为2。 编写数据结构和算法来实现。要求:将哈希函数和处理冲突方法...
  • Oracle P/L SQL实现发送Email、浏览网页等网络操作功能,以下是此过程包头部,包体经常打包处理plb,感兴趣用户可以下载下来。 --.使用聚合函数实现 多行合并 Drop Type Strcat_type; Drop Function f_StrCat; ...
  • 未实现部分 翘舌音最优 整体音节最优 使用方法 pip install -r requirements PyAudio需要下载whl文件 pynput高版本会在pyinstaller更新exe时报错此处使用1.6.8版本 生成exe文件 pyinstaller -F main.py dist文件夹...
  • 豆芽的名字取自“Douban, Yet Another”的缩写和中文词语“豆芽”的拼音正好相同的巧合。 取名之后,我才得知豆瓣的 Windows Phone 客户端的名字也叫做“豆芽”。所以相对于豆瓣官方应用“一个叫‘豆瓣’的App”,...
  • 家乡javaweb项目

    2021-06-12 16:25:34
    service实现类和dao实现每个方法需要有日志输出 五、提交时需要有sql脚本(包含建库、建表、插入数据)和项目代码,提交压缩文件,文件名称为自己学号 课程设计名称:...
  • 另有一种新概念五笔, 发明人李顺, 做得更全面, 如支持按 gbk, GB18030, unicode等在待选字框内显示*,**, ****, 还有更大字符集扩展(字海集), 但是收费和专用, 普及 输入法中帮助文件也直接使用了海峰五笔...
  • 另有一种新概念五笔, 发明人李顺, 做得更全面, 如支持按 gbk, GB18030, unicode等在待选字框内显示*,**, ****, 还有更大字符集扩展(字海集), 但是收费和专用, 普及 输入法中帮助文件也直接使用了海峰五笔...
  • 基于hhww改进版传统五笔输入法 在hhhhwwww改进版输入法(生成器)基础上,修改了背景颜色、取消了Ctrl+M换码、取消了切换码表显示颜色、修改了“\”为“、"等细节完善! 此五笔输入法是用hhhhwwww改进...
  • IME Tool 让你可以自由地设置各种热键,基本键(ctrl、alt、shift)共有六种组合,辅助键有 91 个可选,如用左 Alt+左 Window 键激活龙文五笔,shift+down 激活紫光拼音。当然,有些热键组合是不能用,如 shift+...
  • 简书: 东方曦 写在前面 本系列博客demo都上传到了github:RecyclerViewDemo 如果有帮助到你话不妨给我点个star~ 在介绍ItemDecoration之前我们不妨先看下它能实现什么功能。 这是一个国内大部分城市列表...

    我的CSDN: ListerCi
    我的简书: 东方未曦

    写在前面

    本系列博客的demo都上传到了github:RecyclerViewDemo
    如果有帮助到你的话不妨给我点个star~

    在介绍ItemDecoration之前我们不妨先看下它能实现什么功能。
    这是一个国内大部分城市的列表,通过城市拼音对其排序,通过拼音首字母对其分组。在滑动到某一组的城市时,它的Header会在顶部保持不动,下一组滑动上来时,新的Header会把上一组“顶”上去,这个效果就是ItemDecoration实现的。当然,为了功能的完整性,我还添加了侧边栏用于搜索查找。

    gif-城市列表demo.gif

    看完效果后是不是对ItemDecoration充满了兴趣?现在让我们一步一步去认识它并实现这个功能吧。

    一、ItemDecoration简介

    1.1 API介绍

    ItemDecoration是定义在RecyclerView内部的抽象类,排除过时的方法,它提供了3个可重写的方法,代码如下。

    public abstract static class ItemDecoration {
            /**
             * 绘制提供给RecyclerView的装饰
             * 任何由此方法绘制的内容都会在item绘制之前就绘制完毕,因此它是处于item下层的
             */
            public void onDraw(@NonNull Canvas c, @NonNull RecyclerView parent, @NonNull State state) {
                onDraw(c, parent);
            }
    
            /**
             * 此方法与onDraw相对,方法中的内容是在item绘制完毕后开始绘制的
             * 因此会显示在item上层
             */
            public void onDrawOver(@NonNull Canvas c, @NonNull RecyclerView parent,
                    @NonNull State state) {
                onDrawOver(c, parent);
            }
    
            /**
             * 通过outRect表示当前item距离left、top、right、bottom 4个方向的距离
             */
            public void getItemOffsets(@NonNull Rect outRect, @NonNull View view,
                    @NonNull RecyclerView parent, @NonNull State state) {
                getItemOffsets(outRect, ((LayoutParams) view.getLayoutParams()).getViewLayoutPosition(),
                        parent);
            }
        }
    

    其中onDraw(...)onDrawOver(...)方法的参数中传入了画布Canvas,通过画布我们可以在任何坐标绘制任何事物。
    getItemOffsets(...)方法用于指定每个item距离左上右下4个方向的距离,效果同margin。参数中传入的view表示当前的item,如果你想根据item的数据设置不同margin的话,可以通过RecyclerView的getChildAdapterPosition(View)得到该item在Adapter中的position。

    1.2 DividerItemDecoration分析

    ItemDecoration最简单的用法就是添加分隔线,如果使用DividerItemDecoration,之后你会发现item之间多了一根细细的分隔线。

    RecyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL));
    

    那么这个细线是怎么画出来的呢?回忆一下ItemDecoration中方法的作用,步骤应该是这样的:首先我们通过getItemOffsets()在item之间添加间隔,然后通过onDraw()或者onDrawOver()在这段间隔内绘制线段。

    为了验证我们的想法,来看一下DividerItemDecoration的源码。我们使用的时候是垂直方向,代码中水平方向的代码我就省略掉了。

    public class DividerItemDecoration extends RecyclerView.ItemDecoration {
        
        private static final int[] ATTRS = new int[]{ android.R.attr.listDivider };
        private Drawable mDivider;
        // 垂直或水平方向
        private int mOrientation;
    
        private final Rect mBounds = new Rect();
    
        public DividerItemDecoration(Context context, int orientation) {
            final TypedArray a = context.obtainStyledAttributes(ATTRS);
            mDivider = a.getDrawable(0); // 默认的分隔线
            a.recycle();
            setOrientation(orientation);
        }
    
        @Override
        public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
            if (mOrientation == VERTICAL) {
                drawVertical(c, parent);
            }
        }
    
        private void drawVertical(Canvas canvas, RecyclerView parent) {
            canvas.save();
            final int left;
            final int right;
            // 根据RecyclerView是否有padding获取线段的left和right的坐标
            if (parent.getClipToPadding()) {
                left = parent.getPaddingLeft();
                right = parent.getWidth() - parent.getPaddingRight();
                canvas.clipRect(left, parent.getPaddingTop(), right,
                        parent.getHeight() - parent.getPaddingBottom());
            } else {
                left = 0;
                right = parent.getWidth();
            }
            // 得到当前显示的每个child的线段的top和bottom坐标
            final int childCount = parent.getChildCount();
            for (int i = 0; i < childCount; i++) {
                final View child = parent.getChildAt(i);
                parent.getDecoratedBoundsWithMargins(child, mBounds);
                final int bottom = mBounds.bottom + Math.round(child.getTranslationY());
                final int top = bottom - mDivider.getIntrinsicHeight();
                mDivider.setBounds(left, top, right, bottom);
                mDivider.draw(canvas);
            }
            canvas.restore();
        }
    
        @Override
        public void getItemOffsets(Rect outRect, View view, RecyclerView parent,
                RecyclerView.State state) {
            if (mDivider == null) {
                outRect.set(0, 0, 0, 0);
                return;
            }
            if (mOrientation == VERTICAL) {
                // 设置每个item与下方的间隔为mDivider.getIntrinsicHeight()
                outRect.set(0, 0, 0, mDivider.getIntrinsicHeight());
            } else {
                outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0);
            }
        }
    }
    

    DividerItemDecoration的实现逻辑果然与我们想的一样,先在getItemOffsets()中设置每个item与下方的间隔,随后在onDraw(...)中调用drawVertical(Canvas canvas, RecyclerView parent)得到线段的边界坐标并绘制。

    二、城市列表实现

    2.1 分析实现方式

    虽然demo中的效果是下一组的Header将上一组的Header顶了上去,但实现的逻辑并非如此,如果把Header的背景色调整为半透明,效果是这样的。

    gif-半透明Header.gif

    Header半透明之后,它就露出了马脚,仔细观察后我们可以总结实现这个效果所需的步骤:
    ① 每个分组的第一个城市item的上方都有一个Header,例如“阿坝”和“白城”的上方都有一个Header
    ② 当前RecyclerView所展示的第一个item的分类会显示在RecyclerView的最上方,例如当前RecyclerView第一个item是“阿克苏”、“安庆”等城市时,RecyclerView最上方会漂浮一个"A"类Header
    ③ 当某个分组的最后一个item滑出RecyclerView时,Header会随着这个item一起滑走,这也是“顶上去”效果的由来。例如当“澳门”即将滑出RecyclerView时,"A"类Header会随着“澳门”item一起滑走,并且我们很容易得到他们坐标之间的关系:item.bottom = Header.bottom

    2.2 具体实现

    分析完步骤,即可开始实现这个效果。项目中的城市数据保存在arrays文件中,数据格式如下所示,我已经先为每个城市添加了拼音并为所有城市进行了排序,数据中还包括城市ID,完整数据请去博客开头的github下载。

    <string-array name="city">
            <item>阿坝</item>
            <item>aba</item>
            <item>101271901</item>
            <item>阿克苏</item>
            <item>akesu</item>
            <item>101130801</item>
            <item>阿勒泰</item>
            <item>aletai</item>
            <item>101131401</item>
            <item>阿里</item>
            <item>ali</item>
            <item>101140701</item>
            <item>安康</item>
            <item>ankang</item>
            <item>101110701</item>
            <item>安庆</item>
            <item>anqing</item>
            <item>101220601</item>
            <item>鞍山</item>
            <item>anshan</item>
            <item>101070301</item>
            ......
    </string-array>
    

    在绘制Header时,我们需要知道一个item是不是它分组的第一个或者是最后一个,那么需要构建这样的一个实体类:

    public class CityInfo {
    
        private String mCityName;
        private String mPinYin;
        private String mGroup;
        private String mCityID;
        private boolean mIsFirstInGroup;
        private boolean mIsLastInGroup;
    
        public CityInfo(String cityName, String pinYin, String cityID,
                        boolean isFirstInGroup, boolean isLastInGroup) {
            this.mCityName = cityName;
            this.mPinYin = pinYin;
            this.mGroup = mPinYin.substring(0, 1).toUpperCase();
            this.mCityID = cityID;
            this.mIsFirstInGroup = isFirstInGroup;
            this.mIsLastInGroup = isLastInGroup;
        }
    
        // setters and getters...
    }
    

    再来将数据都解析成实体类。由于数据是已经排好序的,那么判断一个item是不是它分组的第一个或最后一个可以用这种方式:如果第i个数据与第i-1个的group不相同,那么i就是i的分组的第一个item;而i-1就是i-1的分组的最后一个item。

        private void prepareCityInfo() {
            mCityInfoList = new ArrayList<>();
            String[] cityArray = getResources().getStringArray(R.array.city);
            String curGroup = "0";
            // 每 3 个String构成一个CityInfo
            for (int i = 0; i < cityArray.length; i += 3) {
                CityInfo cityInfo = new CityInfo(cityArray[i], cityArray[i + 1], cityArray[i + 2],
                        false, false);
                if (!cityInfo.getGroup().equals(curGroup)) {
                    // 如果当前城市的 group 信息与保存的不一致, 那么就是该 group 的第一个
                    cityInfo.setIsFirstInGroup(true);
                    // 同时将该 group 信息添加到索引中
                    indexList.add(cityInfo.getGroup());
                    // 它的上一个城市就是上一个 group 的最后一个
                    if (i > 0) {
                        mCityInfoList.get(mCityInfoList.size() - 1).setIsLastInGroup(true);
                    }
                    curGroup = cityInfo.getGroup();
                }
                mCityInfoList.add(cityInfo);
            }
        }
    

    下面重点来看下怎么自定义ItemDecoration,我们根据之前总结的步骤来,首先为每组的第一个item绘制Header,在绘制Header之前需要通过getItemOffsets()方法为Header预留空间。

        @Override
        public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent,
                                   @NonNull RecyclerView.State state) {
            super.getItemOffsets(outRect, view, parent, state);
            int position = parent.getChildAdapterPosition(view);
            CityInfo cityInfo = mCityInfoList.get(position);
            if (cityInfo.isFirstInGroup()) {
                outRect.top = GROUP_ITEM_TOP;
            }
        }
    

    再通过onDraw()绘制,这里parent.getChildCount()获取到的是RecyclerView中当前可见的所有item的数量。

        @Override
        public void onDraw(@NonNull Canvas c, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
            super.onDraw(c, parent, state);
            int childCount = parent.getChildCount();
            for (int i = 0; i < childCount; i++) {
                View view = parent.getChildAt(i);
                int position = parent.getChildAdapterPosition(view);
                CityInfo cityInfo = mCityInfoList.get(position);
                if (cityInfo.isFirstInGroup()) {
                    int left = parent.getPaddingLeft();
                    int top = view.getTop() - GROUP_ITEM_TOP;
                    int right = parent.getRight() - parent.getPaddingRight();
                    int bottom = view.getTop();
                    // 绘制背景
                    c.drawRect(left, top, right, bottom, mBackGroundPaint);
                    // 绘制文字
                    drawText(c, left, top, bottom, cityInfo.getGroup());
                }
            }
        }
    

    再来绘制固定于RecyclerView顶端的Header,这里只要得到RecyclerView所展示的第一个item的group并将其绘制即可。由于这个Header是在RecyclerView上层的,因此需要在onDrawOver()中绘制。

    public void onDrawOver(@NonNull Canvas c, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
            super.onDrawOver(c, parent, state);
            // 得到当前所展示的第一个View
            View view = parent.getChildAt(0);
            int position = parent.getChildAdapterPosition(view);
            CityInfo cityInfo = mCityInfoList.get(position);
                
            int left = parent.getPaddingLeft();
            int top = parent.getPaddingTop();
            int right = parent.getRight() - parent.getPaddingRight();
            int bottom = top + GROUP_ITEM_TOP;
            c.drawRect(left, top, right, bottom, mBackGroundPaint);
    
            drawText(c, left, top, bottom, cityInfo.getGroup());
        }
    

    最后需要实现就是Header随着当前group的最后一个item移动的效果,移动时Header的bottom与item的bottom一致即可。那什么时候开始移动呢?很显然就是当这个item的bottom与RecyclerView顶部的距离小于Header的高度时开始移动。我们修改onDrawOver()方法如下即可。

        @Override
        public void onDrawOver(@NonNull Canvas c, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
            super.onDrawOver(c, parent, state);
            View view = parent.getChildAt(0);
            int position = parent.getChildAdapterPosition(view);
            CityInfo cityInfo = mCityInfoList.get(position);
            // 当前第一个item是它group的最后一个
            // 且view的bottom距离RecyclerView顶端小于Header的高度
            if (cityInfo.isLastInGroup() && view.getBottom() < GROUP_ITEM_TOP) {
                int left = parent.getPaddingLeft();
                int top = view.getBottom() - GROUP_ITEM_TOP;
                int right = parent.getRight() - parent.getPaddingRight();
                int bottom = view.getBottom();
                c.drawRect(left, top, right, bottom, mBackGroundPaint);
    
                drawText(c, left, top, bottom, cityInfo.getGroup());
            } else {
                int left = parent.getPaddingLeft();
                int top = parent.getPaddingTop();
                int right = parent.getRight() - parent.getPaddingRight();
                int bottom = top + GROUP_ITEM_TOP;
                c.drawRect(left, top, right, bottom, mBackGroundPaint);
    
                drawText(c, left, top, bottom, cityInfo.getGroup());
            }
        }
    

    代码介绍到这里就结束了,如果你对整体的程序感兴趣,欢迎去github下载。

    三、参考

    RecyclerView探索之通过ItemDecoration实现StickyHeader效果

    展开全文
  • msods5.8 u盘上dos

    2009-03-07 12:36:46
    4.全中文操作方式,让您使用时更简单,并且支持DOS下五笔拼音输入及中文文件操作. 5.完全傻瓜化网刻模式,让没用过本软件用户也能轻松实现网刻. 6.支持引导自已制作IMG镜像,而且理论上支持引导自己制作无限...
  • 最近在做跨平台开发,用到了读取通讯录功能,但是读取到通讯录未实现分组,这个应该是H5标准问题,具体参考以下文档: https://www.html5plus.org/doc/zh_cn/contacts.html 读取成功后,需要和手机通讯录...

    最近在做跨平台开发,用到了读取通讯录的功能,但是读取到的通讯录未实现分组,这个应该是H5标准的问题,具体参考以下文档:

    https://www.html5plus.org/doc/zh_cn/contacts.html

    读取成功后,需要和手机通讯录一样,实现分组显示,即A显示一组,B显示为一组,可是我们拿到的通讯录数据并无相应的分组参考,只能我们自已处理,得到汉字的拼音后进行排序。

    以下为实现的效果图,可参考。

     

    以下JS已经针对uniapp平台进行调整,下载后可直接使用。相应的js文件下载地址:

    https://download.csdn.net/download/yunhuaikong/12850609

    实现也参考了网上的教程或者是别人的实现 ,在此表示感谢。

    使用方法:下载后,将js文件放到你的项目目录中,通过import引入使用即可。

    页面显示部分:

    因为页面的显示仍然是类似于手机通讯录的方式,即按照首字母进行分组显示!故而对于数据进行了二次封装,以type=0和type=1为区分显示是数据项还是分区标题项。注意页面代码中未使用用户头像字段icon,你自己根据实际进行使用替换即可。

    <view class="cell-view" v-for="(item,index) in dataList" :key="index" @click="didselectOneCell(index)">
    	<view :class="[item.type==0?'section-view':'content-view']">
    		<text v-if="item.type==0">{{item.name}}</text>
    		<view v-if="item.type==1" class="left-view">
    		    <image src="../../static/images/scan@2x.png" mode=""></image>
    	    </view>
    	    <view v-if="item.type==1" class="m-view">
    		    <text class="text-view">{{item.name}}</text>
    	    </view>
        </view>
    </view>

     页面CSS部分

    格式 为<style lang="less">,根据你的实际情况使用,可分解为普通的CSS格式。

    .cell-view {
    			position: relative;
    			width: 100%;
    			height: auto;
    
    			// background-color: transparent;
    			// display: flex;
    			// flex-direction: row;
    			// justify-content: flex-start;
    			// align-items: center;
    
    			background-color: white;
    
    			.section-view {
    				position: relative;
    				width: 100%;
    				height: 74upx;
    
    				background-color: rgb(245, 245, 245);
    
    				display: flex;
    				flex-direction: row;
    				justify-content: flex-start;
    				align-items: center;
    
    				text {
    					position: relative;
    					left: 50upx;
    
    					font-size: 28upx;
    					color: #333333;
    				}
    			}
    
    			.content-view {
    				position: relative;
    				left: 30upx;
    				width: calc(100% - 60upx);
    				height: 94upx;
    
    				display: flex;
    				flex-direction: row;
    				justify-content: flex-start;
    				align-items: center;
    
    				border-bottom: 1upx solid rgb(245, 245, 245);
    				background-color: white;
    
    				.left-view {
    					position: relative;
    					width: 64upx;
    					height: 64upx;
    
    					display: flex;
    					flex-direction: row;
    					justify-content: center;
    					align-items: center;
    
    					image {
    						width: 100%;
    						height: 100%;
    						border-radius: 50%;
    					}
    				}
    
    				.m-view {
    					position: relative;
    					padding-left: 34upx;
    					width: calc(100% - 64upx -44upx);
    					height: 100%;
    
    					display: flex;
    					flex-direction: row;
    					justify-content: flex-start;
    					align-items: center;
    
    					.text-view {
    						position: relative;
    						width: 100%;
    
    						font-size: 32upx;
    						color: #333333;
    					}
    				}
    
    				.r-view {
    					position: absolute;
    					right: 0upx;
    					width: 44upx;
    					height: 44upx;
    
    					display: flex;
    					flex-direction: row;
    					justify-content: center;
    					align-items: center;
    
    					image {
    						width: 100%;
    						height: 100%;
    						border-radius: 50%;
    					}
    				}
    			}
    		}

    js逻辑部分:特殊说明:此处只是针对通讯录首汉字取拼音进行字典排序,其他未进行排序,如果你有兴趣,你自己可以根据所取出来的所有用户名字母进行排序。 未取出首字母的,统一归类到#分区。

    onLoad() {
    			var self = this
    			uni.showToast({
    				icon: 'loading',
    				title: "加载中..."
    			})
    			plus.contacts.getAddressBook(plus.contacts.ADDRESSBOOK_PHONE, function(addressBook) {
    					addressBook.find(["displayName", "phoneNumbers", "photos","categories"],
    						function(contacts) {
    							//成功
    							var listObject = {}
    							contacts.forEach(function(e) {
    								var fullName = e.displayName
    								let spe = pinYin.getCamelChars(fullName);
    								let key = ""
    								if (spe == null || spe.length == 0)
    								{
    									key = "#"
    								}
    								else{
    									
    									let fstre = spe.slice(0,1)
    									key = fstre
    									key = key.toUpperCase()
    									// e.prototype.type = 1
    								}
    								var ioj = listObject[key]
    								if(ioj == null)
    								{
    									ioj = new Array()
    									listObject[key] = ioj
    								}
    								
    								let phones = []
    								e.phoneNumbers.forEach(function(a)
    								{
    									phones.push(a.value)
    								})
    								let vl = phones.join(",")
    								let ics = (e.photos && e.photos.length>0)?e.photos[0]:''
    								var dic = new Object();
    								dic.name = e.displayName
    								dic.mobile = vl
    								dic.icon = ics
    								
    								ioj.push(dic)
    							})
    							
    							var dlist = []
    							var res = Object.keys(listObject).sort();
    							for(var key in res)
    							{
    								var dic = new Object();
    								dic.name = res[key]
    								dic.type = 0
    								dlist.push(dic)
    								
    								let sarry =  listObject[res[key]]
    								sarry.forEach(function(b)
    								{
    									var dic = new Object();
    									dic.name = b.name
    									dic.mobile = b.mobile
    									dic.icon = b.icon
    									dic.type = 1
    									dlist.push(dic)
    								})
    							}
    							self.dataList = dlist
    						},
    						function() {
    							uni.showToast({
    								title: '获取联系人失败',
    								duration: 2000
    							})
    						}, {
    							multiple: true
    						})
    				},
    				function(e) {
    					uni.showToast({
    						title: e.message
    					})
    					//失败
    				})
    			uni.hideToast()
    		},

    应该能满足日常需要,后续如果有什么问题,大家提出来,进行完善。

     

     

    展开全文
  • 2.未对不规范输入做出处理,这方面还未实现 3.生成1000000个数独跑不出来 (2).代码设计是否有周全的考虑? 设计时不排除有生成重复数独的可能 (3).代码可读性如何? 可读性良好,函数命名用的拼音,虽然可以理解...
  • UniversalFrame-8.9.8.1.zip

    2019-07-20 11:59:11
    你好! 感谢您参与,有了您加入,框架可能会更加完善,感谢大家使用和支持。博主会继续持续更新保证,框架越来越完善。该框架目前适合开发项目为 C# Web MVC 等等...提及功能还有很多,暂时就不罗列了。
  • 由于时间原因,还有很多功能并没有完善,在前面两篇博文中仅仅给出了部分页面代码,服务器端代码没有粘贴出来, 还完善部分,1.过滤器:只有在用户登录完之后才显示主...真正实现拼音搜索 3.分组中删除等等
  • 逻辑数码字符键盘

    千次阅读 2008-11-12 17:46:00
     现有手机上使用很广泛的数字键盘拼音文字输入方案,是用纯数字键盘输入数字串后,再对可能对应字母字符串的猜测选择技术手段实现的。技术本质上并采用已有几十年的数字键盘升级方案——数字字符
  • 希望完成仓库中相关项目同学在参考这些代码同时尽可能自己实现一遍,已完成相关项目同学同样可以学习代码写法,如有不足也欢迎大家批评指正。本仓库欢迎大家给项目发起人发pull request贡献自己代码。同时...
  • QQ五笔吸取了QQ拼音的优点和经验,结合五笔输入特点,专注于易用性、稳定性和兼容性,实现各输入风格平滑切换,同时引入分类词库、网络同步、皮肤等个性化功能。让五笔用户在输入中不但感觉更流畅、打字效率更高...
  • 基于ringbuffer实现的队列 https://github.com/eapache/queue 拼音 https://github.com/go-ego/gpy 分词 https://github.com/go-ego/gse 搜索 https://github.com/go-ego/riot windows COM ...
  • Sqlite中文排序方法

    千次阅读 2018-05-17 11:13:00
    已经验证C#版本 可以正常按照中文的拼音进行排序 androird版本和Swift版本涉及,作者貌似已经实验成功。c#版:https://blog.csdn.net/ch_fb/article/details/6682791#commentseditandroid版...
  • 它以声母和笔画这两种最简单汉字特征实现了一种比拼音更简单、比五笔更快速无重码、动态造词、动态调整码长简单快速输入方法,引起了码界巨大震动。声笔飞码则使续码顶屏技术用到了专业盲打输入法上,大大...

空空如也

空空如也

1 2 3 4 5 ... 8
收藏数 148
精华内容 59
关键字:

未实现的拼音