搜索
 找回密码
 立即注册

简单一步 , 微信登陆

MPinyinIME softkeyboard

作者:liuwei | 时间:2016-5-28 10:23:11 | 阅读:5697| 只看该作者
系统拼音输入法的键盘绘制通过在XmlKeyboardLoader.java解析skb_template1.xml skb_xxx.xml等文件,获取键盘和各按键的属性,
softKeyboard.addSoftKey(softKey);将按键包装在softkey类,并添加到键盘softkeyboard类中,在SoftKeyboardView.java中绘制键盘。

skb_template1.xml    设置了全局属性要读懂xml文件,需要配合解析方法一起看。
<skb_template
  skb_bg="@drawable/skb_container_bg"       // 键盘背景
  key_xmargin="0%p"                    //按键间距
  key_ymargin="0%p"
  balloon_bg="@drawable/key_balloon_bg"
  popup_bg="@drawable/miniskb_bg"
  color="@color/label_color"    //lable颜色
  color_highlight="@color/label_color"  //press lable颜色
  color_balloon="@color/balloon_color"> //气泡颜色

  <key_type              //背景图
    id="0"
    bg="@drawable/normal_key_bg"    //normal状态背景
    hlbg="@drawable/normal_key_hl_bg" //press状态背景
    color_highlight="@color/label_color_hl0"/>  //press lable颜色

  <!-- Default ic** for enter key --> //图标
  <key_icon code="66" icon="@drawable/enter_icon"
    icon_popup="@drawable/enter_popup_icon"/>


  <!-- Default key definition -->  //默认按键
  <!-- Enter key for QWERTY-like keyboards.-->
  <key id="1" start_pos_x="83.5%p" start_pos_y="80%p"
    width="10%p" height="20%p" code="66" key_type="1">
    <toggle_state state_id="@string/toggle_enter_go" label="去往" code="66"/>
    <toggle_state state_id="@string/toggle_enter_search" code="66"
      icon="@drawable/search_icon" icon_popup="@drawable/search_popup_icon"/>
    <toggle_state state_id="@string/toggle_enter_send" label="发送" code="66"/>
    <toggle_state state_id="@string/toggle_enter_next" label="下一个" code="66"/>
    <toggle_state state_id="@string/toggle_enter_done" label="完成" code="66"/>
  </key>
</skb_template>

XmlKeyboardLoader.java中
    private int mSkbTemplateId;
    private Drawable mSkbBg;
    private Drawable mBalloonBg;
    private Drawable mPopupBg;
    private float mXMargin = 0;
    private float mYMargin = 0;    //分别保存全局的样式
    private Vector<SoftKeyType> mKeyTypeList = new Vector<SoftKeyType>();     //背景图 通过key_type索引
    private Vector<KeyIconRecord> mKeyIconRecords = new Vector<KeyIconRecord>();     //功能键图标 通过code索引
    private Vector<KeyRecord> mKeyRecords = new Vector<KeyRecord>();    //功能键 通过id索引
分别保存了 key_type key_icon key 3中标签的数据

SoftKey.java中
softkey的属性
    protected SoftKeyType mKeyType;   //key_type
    protected Drawable mKeyIcon;    //key_icon
    protected Drawable mKeyIconPopup;     //气泡图
    protected String mKeyLabel;     //lable
    protected int mKeyCode;      //code
    protected  boolean mKeySelected;
    public int mPopupSkbId;
    public float mLeftF;
    public float mRightF;
    public float mTopF;
    public float mBottomF; //相对尺寸
    public int mLeft;
    public int mRight;
    public int mTop;
    public int mBottom; //绝对尺寸

Environment.java
onConfigurationChanged 配置了键盘大小,lable字体大小,气泡大小 ,等。
    private static final float NORMAL_KEY_TEXT_SIZE_RATIO = 0.075f;
    private static final float FUNCTION_KEY_TEXT_SIZE_RATIO =0.055f;
两种大小由key_type








XmlKeyboeardLoarder

skb_template2
key属性
id ;默认值-1 ,用于中定义defaultkey  defaultkey可以制定更多属性 而qwerty里面的key继承属性width height type repeat balloon


start_pos_x  x位置
start_pos_y y位置
code
lable
                 

with 宽  
height 高     
key_type  type里面定义了背景
repeat
balloon


  key_xmargin 这两个属性并不是按键之间的间距
  key_ymargin


    private void drawSoftKey(Canvas canvas, SoftKey softKey, int keyXMargin,
            int keyYMargin) {
        Drawable bg;
        int textColor;
        if (mKeyPressed && softKey == mSoftKeyDown) {
            bg = softKey.getKeyHlBg();
            textColor = Color.BLACK;
        } else {
            bg = softKey.getKeyBg();
            bg = r.getDrawable(R.drawable.softkey_bg_unselect);
            textColor = Color.BLACK;
        }

        if (null != bg) {
            if (softKey.isKeySelected()) {
                if (isSkbOnFocus) {
                  mActiveCellDrawable.setBounds(softKey.mLeft + keyXMargin+1, softKey.mTop + keyYMargin+1,
                                                  softKey.mRight - keyXMargin-1, softKey.mBottom - keyYMargin-1);
                    mActiveCellDrawable.draw(canvas);
                } else {
                    mActiveCellNoFocusDrawable.setBounds(softKey.mLeft + keyXMargin+1, softKey.mTop + keyYMargin+1,
                                                         softKey.mRight - keyXMargin-1, softKey.mBottom - keyYMargin-1);
                    mActiveCellNoFocusDrawable.draw(canvas);
                }
            } else {
                bg.setBounds(softKey.mLeft + keyXMargin+1, softKey.mTop + keyYMargin+1,
                             softKey.mRight - keyXMargin-1, softKey.mBottom - keyYMargin-1);
                bg.draw(canvas);
            }
        }

        String keyLabel = softKey.getKeyLabel();
        Drawable keyIcon = softKey.getKeyIcon();
        if (null != keyIcon) {
            Drawable icon = keyIcon;
            int marginLeft = (softKey.width() - icon.getIntrinsicWidth()) / 2;
            int marginRight = softKey.width() - icon.getIntrinsicWidth()
                    - marginLeft;
            int marginTop = (softKey.height() - icon.getIntrinsicHeight()) / 2;
            int marginBottom = softKey.height() - icon.getIntrinsicHeight()
                    - marginTop;
            icon.setBounds(softKey.mLeft + marginLeft,
                    softKey.mTop + marginTop, softKey.mRight - marginRight,
                    softKey.mBottom - marginBottom);
            icon.draw(canvas);
        } else if (null != keyLabel) {
            mPaint.setColor(textColor);
            float x = softKey.mLeft
                    + (softKey.width() - mPaint.measureText(keyLabel)) / 2.0f;
            int fontHeight = mFmi.bottom - mFmi.top;
            float marginY = (softKey.height() - fontHeight) / 2.0f;
            float y = softKey.mTop + marginY - mFmi.top + mFmi.bottom / 1.5f;
            canvas.drawText(keyLabel, x, y + 1, mPaint);
        }
    }


XmlResourceParser   xml资源文件解析demo
public SkbTemplate loadSkbTemplate(int resourceId) {
        if (null == mContext || 0 == resourceId) {
            return null;
        }
        Resources r = mResources;
        XmlResourceParser xrp = r.getXml(resourceId);

        KeyCommonAttributes attrDef = new KeyCommonAttributes(xrp);
        KeyCommonAttributes attrKey = new KeyCommonAttributes(xrp);

        mSkbTemplate = new SkbTemplate(resourceId);
        int lastKeyTypeId = KEYTYPE_ID_LAST;
        int globalColor = 0;
        int globalColorHl = 0;
        int globalColorBalloon = 0;
        try {
            mXmlEventType = xrp.next();
            while (mXmlEventType != XmlResourceParser.END_DOCUMENT) {
                mNextEventFetched = false;
                if (mXmlEventType == XmlResourceParser.START_TAG) {
                    String attribute = xrp.getName();
                    if (XMLTAG_SKB_TEMPLATE.compareTo(attribute) == 0) {
                        Drawable skbBg = getDrawable(xrp, XMLATTR_SKB_BG, null);
                        Drawable balloonBg = getDrawable(xrp,
                                XMLATTR_BALLOON_BG, null);
                        Drawable popupBg = getDrawable(xrp, XMLATTR_POPUP_BG,
                                null);
                        if (null == skbBg || null == balloonBg
                                || null == popupBg) {
                            return null;
                        }
                        mSkbTemplate.setBackgrounds(skbBg, balloonBg, popupBg);

                        float xMargin = getFloat(xrp, XMLATTR_KEY_XMARGIN, 0);
                        float yMargin = getFloat(xrp, XMLATTR_KEY_YMARGIN, 0);
                        mSkbTemplate.setMargins(xMargin, yMargin);

                        // Get default global colors.
                        globalColor = getColor(xrp, XMLATTR_COLOR, 0);
                        globalColorHl = getColor(xrp, XMLATTR_COLOR_HIGHLIGHT,
                                0xffffffff);
                        globalColorBalloon = getColor(xrp,
                                XMLATTR_COLOR_BALLOON, 0xffffffff);
                    } else if (XMLTAG_KEYTYPE.compareTo(attribute) == 0) {
                        int id = getInteger(xrp, XMLATTR_ID, KEYTYPE_ID_LAST);
                        Drawable bg = getDrawable(xrp, XMLATTR_KEYTYPE_BG, null);
                        Drawable hlBg = getDrawable(xrp, XMLATTR_KEYTYPE_HLBG,
                                null);
                        int color = getColor(xrp, XMLATTR_COLOR, globalColor);
                        int colorHl = getColor(xrp, XMLATTR_COLOR_HIGHLIGHT,
                                globalColorHl);
                        int colorBalloon = getColor(xrp, XMLATTR_COLOR_BALLOON,
                                globalColorBalloon);
                        if (id != lastKeyTypeId + 1) {
                            return null;
                        }
                        SoftKeyType keyType = mSkbTemplate.createKeyType(id,
                                bg, hlBg);
                        keyType.setColors(color, colorHl, colorBalloon);
                        if (!mSkbTemplate.addKeyType(keyType)) {
                            return null;
                        }
                        lastKeyTypeId = id;
                    } else if (XMLTAG_KEYICON.compareTo(attribute) == 0) {
                        int keyCode = getInteger(xrp, XMLATTR_KEY_CODE, 0);
                        Drawable icon = getDrawable(xrp, XMLATTR_KEY_ICON, null);
                        Drawable iconPopup = getDrawable(xrp,
                                XMLATTR_KEY_ICON_POPUP, null);
                        if (null != icon && null != iconPopup) {
                            mSkbTemplate.addDefaultKeyIc**(keyCode, icon,
                                    iconPopup);
                        }
                    } else if (XMLTAG_KEY.compareTo(attribute) == 0) {
                        int keyId = this.getInteger(xrp, XMLATTR_ID, -1);
                        if (-1 == keyId) return null;

                        if (!attrKey.getAttributes(attrDef)) {
                            return null;
                        }

                        // Update the key position for the key.
                        mKeyXPos = getFloat(xrp, XMLATTR_START_POS_X, 0);
                        mKeyYPos = getFloat(xrp, XMLATTR_START_POS_Y, 0);

                        SoftKey softKey = getSoftKey(xrp, attrKey);
                        if (null == softKey) return null;
                        mSkbTemplate.addDefaultKey(keyId, softKey);
                    }
                }
                // Get the next tag.
                if (!mNextEventFetched) mXmlEventType = xrp.next();
            }
            xrp.close();
            return mSkbTemplate;
        } catch (XmlPullParserException e) {
            // Log.e(TAG, "Ill-formatted keyboard template resource file");
        } catch (IOException e) {
            // Log.e(TAG, "Unable to keyboard template resource file");
        }
        return null;
    }


收藏
收藏0
分享
分享
点赞
点赞0
反对
反对0
回复

使用道具 举报

大神点评1

沙发#
麦克斯韦方程组 发表于:2016-5-28 10:49:19
好东西,多谢分享!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册
手机版