/** * Create a key with the given top-left coordinate and extract its attributes from the XML * parser. * * @param res resources associated with the caller's context * @param parent the row that this key belongs to. The row must already be attached to a {@link * Keyboard}. * @param x the x coordinate of the top-left * @param y the y coordinate of the top-left * @param parser the XML parser containing the attributes for this key */ public Key( Context askContext, Resources res, Row parent, KeyboardDimens keyboardDimens, int x, int y, XmlResourceParser parser) { this(parent, keyboardDimens); final Resources askResources = askContext.getResources(); SparseIntArray attributeIdMap = parent.parent.attributeIdMap; this.x = x; this.y = y; // setting up some defaults width = Math.min(keyboardDimens.getKeyMaxWidth(), parent.defaultWidth); height = KeyboardSupport.getKeyHeightFromHeightCode( keyboardDimens, parent.defaultHeightCode, askResources.getConfiguration().orientation); gap = parent.defaultHorizontalGap; codes = null; iconPreview = null; popupCharacters = null; popupResId = 0; repeatable = false; showPreview = true; dynamicEmblem = KEY_EMBLEM_NONE; modifier = false; sticky = false; // loading data from XML int[] remoteKeyboardLayoutStyleable = parent.parent.remoteKeyboardLayoutStyleable; TypedArray a = res.obtainAttributes(Xml.asAttributeSet(parser), remoteKeyboardLayoutStyleable); int n = a.getIndexCount(); for (int i = 0; i < n; i++) { final int remoteIndex = a.getIndex(i); final int localAttrId = attributeIdMap.get(remoteKeyboardLayoutStyleable[remoteIndex]); setDataFromTypedArray(parent, keyboardDimens, askResources, a, remoteIndex, localAttrId); } a.recycle(); this.x += gap; int[] remoteKeyboardKeyLayoutStyleable = parent.parent.remoteKeyboardKeyLayoutStyleable; a = res.obtainAttributes(Xml.asAttributeSet(parser), remoteKeyboardKeyLayoutStyleable); n = a.getIndexCount(); for (int i = 0; i < n; i++) { final int remoteIndex = a.getIndex(i); final int localAttrId = attributeIdMap.get(remoteKeyboardKeyLayoutStyleable[remoteIndex]); setDataFromTypedArray(parent, keyboardDimens, askResources, a, remoteIndex, localAttrId); } externalResourcePopupLayout = popupResId != 0; if (codes == null && !TextUtils.isEmpty(label)) { codes = new int[] {label.charAt(0)}; } a.recycle(); }
public Row(Context askContext, Resources res, Keyboard parent, XmlResourceParser parser) { this.parent = parent; // some defaults defaultWidth = parent.mDefaultWidth; defaultHeightCode = parent.mDefaultHeightCode; defaultHorizontalGap = parent.mDefaultHorizontalGap; verticalGap = parent.getVerticalGap(); // now reading from the XML SparseIntArray attributeIdMap = parent.attributeIdMap; int[] remoteKeyboardLayoutStyleable = parent.remoteKeyboardLayoutStyleable; TypedArray a = res.obtainAttributes(Xml.asAttributeSet(parser), remoteKeyboardLayoutStyleable); int n = a.getIndexCount(); for (int i = 0; i < n; i++) { final int remoteIndex = a.getIndex(i); final int localAttrId = attributeIdMap.get(remoteKeyboardLayoutStyleable[remoteIndex]); try { switch (localAttrId) { case android.R.attr.keyWidth: defaultWidth = getDimensionOrFraction( a, remoteIndex, parent.mDisplayWidth, parent.mDefaultWidth); break; case android.R.attr.keyHeight: defaultHeightCode = getKeyHeightCode(a, remoteIndex, parent.mDefaultHeightCode); break; case android.R.attr.horizontalGap: defaultHorizontalGap = getDimensionOrFraction( a, remoteIndex, parent.mDisplayWidth, parent.mDefaultHorizontalGap); break; } } catch (Exception e) { Log.w(TAG, "Failed to set data from XML!", e); } } a.recycle(); int[] remoteKeyboardRowLayoutStyleable = parent.remoteKeyboardRowLayoutStyleable; a = res.obtainAttributes(Xml.asAttributeSet(parser), remoteKeyboardRowLayoutStyleable); n = a.getIndexCount(); for (int i = 0; i < n; i++) { final int remoteIndex = a.getIndex(i); final int localAttrId = attributeIdMap.get(remoteKeyboardRowLayoutStyleable[remoteIndex]); try { switch (localAttrId) { case android.R.attr.rowEdgeFlags: rowEdgeFlags = a.getInt(remoteIndex, 0); break; case android.R.attr.keyboardMode: mode = a.getResourceId(remoteIndex, 0); break; } } catch (Exception e) { Log.w(TAG, "Failed to set data from XML!", e); } } a.recycle(); }
@SuppressWarnings("unchecked") public synchronized T inflate(XmlPullParser parser, P root, boolean attachToRoot) { final AttributeSet attrs = Xml.asAttributeSet(parser); T result = (T) root; try { int type; while ((type = parser.next()) != XmlPullParser.START_TAG && type != XmlPullParser.END_DOCUMENT) {; } if (type != XmlPullParser.START_TAG) { throw new InflateException(parser.getPositionDescription() + ": No start tag found!"); } T xmlRoot = createItemFromTag(parser, parser.getName(), attrs); result = (T) onMergeRoots(root, attachToRoot, (P) xmlRoot); rInflate(parser, result, attrs); } catch (InflateException e) { throw e; } catch (XmlPullParserException e) { InflateException ex = new InflateException(e.getMessage()); ex.initCause(e); throw ex; } catch (IOException e) { InflateException ex = new InflateException(parser.getPositionDescription() + ": " + e.getMessage()); ex.initCause(e); throw ex; } return result; }
private void parseKeyStyle(final XmlPullParser parser, final boolean skip) throws XmlPullParserException, IOException { final AttributeSet attr = Xml.asAttributeSet(parser); final TypedArray keyStyleAttr = mResources.obtainAttributes(attr, R.styleable.Keyboard_KeyStyle); final TypedArray keyAttrs = mResources.obtainAttributes(attr, R.styleable.Keyboard_Key); try { if (!keyStyleAttr.hasValue(R.styleable.Keyboard_KeyStyle_styleName)) { throw new XmlParseUtils.ParseException( "<" + TAG_KEY_STYLE + "/> needs styleName attribute", parser); } if (DEBUG) { startEndTag( "<%s styleName=%s />%s", TAG_KEY_STYLE, keyStyleAttr.getString(R.styleable.Keyboard_KeyStyle_styleName), skip ? " skipped" : ""); } if (!skip) { mParams.mKeyStyles.parseKeyStyleAttributes(keyStyleAttr, keyAttrs, parser); } } finally { keyStyleAttr.recycle(); keyAttrs.recycle(); } XmlParseUtils.checkEndTag(TAG_KEY_STYLE, parser); }
public static AnimatedVectorDrawable create(Context c, Resources resources, int rid) { try { final XmlPullParser parser = resources.getXml(rid); final AttributeSet attrs = Xml.asAttributeSet(parser); int type; while ((type = parser.next()) != XmlPullParser.START_TAG && type != XmlPullParser.END_DOCUMENT) { // Empty loop } if (type != XmlPullParser.START_TAG) { throw new XmlPullParserException("No start tag found"); } else if (!ANIMATED_VECTOR.equals(parser.getName())) { throw new IllegalArgumentException("root node must start with: " + ANIMATED_VECTOR); } final AnimatedVectorDrawable drawable = new AnimatedVectorDrawable(); drawable.inflate(c, resources, parser, attrs, null); return drawable; } catch (XmlPullParserException e) { Log.e(LOGTAG, "parser error", e); } catch (IOException e) { Log.e(LOGTAG, "parser error", e); } return null; }
private Intent parseAlias(XmlPullParser xmlpullparser) throws XmlPullParserException, IOException { android.util.AttributeSet attributeset = Xml.asAttributeSet(xmlpullparser); Intent intent = null; int i; do i = xmlpullparser.next(); while (i != 1 && i != 2); String s = xmlpullparser.getName(); if (!"alias".equals(s)) throw new RuntimeException((new StringBuilder()).append("Alias meta-data must start with <alias> tag; found").append(s).append(" at ").append(xmlpullparser.getPositionDescription()).toString()); int j = xmlpullparser.getDepth(); do { int k; do { k = xmlpullparser.next(); if (k == 1 || k == 3 && xmlpullparser.getDepth() <= j) return intent; } while (k == 3 || k == 4); if ("intent".equals(xmlpullparser.getName())) { Intent intent1 = Intent.parseIntent(getResources(), xmlpullparser, attributeset); if (intent == null) intent = intent1; } else { XmlUtils.skipCurrentTag(xmlpullparser); } } while (true); }
private AttributeSet getAttributeSet(int resourceId) { final XmlResourceParser parser = mContext.getResources().getXml(resourceId); try { XmlUtils.beginDocument(parser, "RelativeLayout"); } catch (Exception e) { fail("Found unexpected loading process error before invoking generateLayoutParams."); } final AttributeSet attr = Xml.asAttributeSet(parser); assertNotNull(attr); return attr; }
private void loadUnreadSupportShortcuts() { long start = System.currentTimeMillis(); if (LauncherLog.DEBUG_PERFORMANCE) { LauncherLog.d(TAG, "loadUnreadSupportShortcuts begin: start = " + start); } // Clear all previous parsed unread shortcuts. UNREAD_SUPPORT_SHORTCUTS.clear(); try { XmlResourceParser parser = mContext.getResources().getXml(R.xml.unread_support_shortcuts); AttributeSet attrs = Xml.asAttributeSet(parser); XmlUtils.beginDocument(parser, TAG_UNREADSHORTCUTS); final int depth = parser.getDepth(); int type = -1; while (((type = parser.next()) != XmlPullParser.END_TAG || parser.getDepth() > depth) && type != XmlPullParser.END_DOCUMENT) { if (type != XmlPullParser.START_TAG) { continue; } TypedArray a = mContext.obtainStyledAttributes(attrs, R.styleable.UnreadShortcut); synchronized (LOG_LOCK) { UNREAD_SUPPORT_SHORTCUTS.add( new UnreadSupportShortcut( a.getString(R.styleable.UnreadShortcut_unreadPackageName), a.getString(R.styleable.UnreadShortcut_unreadClassName), a.getString(R.styleable.UnreadShortcut_unreadKey), a.getInt(R.styleable.UnreadShortcut_unreadType, 0))); } a.recycle(); } } catch (XmlPullParserException e) { LauncherLog.w(TAG, "Got XmlPullParserException while parsing unread shortcuts.", e); } catch (IOException e) { LauncherLog.w(TAG, "Got IOException while parsing unread shortcuts.", e); } sUnreadSupportShortcutsNum = UNREAD_SUPPORT_SHORTCUTS.size(); if (LauncherLog.DEBUG_PERFORMANCE) { LauncherLog.d( TAG, "loadUnreadSupportShortcuts end: time used = " + (System.currentTimeMillis() - start) + ",sUnreadSupportShortcutsNum = " + sUnreadSupportShortcutsNum + getUnreadSupportShortcutInfo()); } }
/** * Inflate a menu hierarchy from the specified XML resource. Throws {@link InflateException} if * there is an error. * * @param menuRes Resource ID for an XML layout resource to load (e.g., <code>R.menu.main_activity * </code>) * @param menu The Menu to inflate into. The items and submenus will be added to this Menu. */ public void inflate(int menuRes, Menu menu) { XmlResourceParser parser = null; try { parser = mContext.getResources().getLayout(menuRes); AttributeSet attrs = Xml.asAttributeSet(parser); parseMenu(parser, attrs, menu); } catch (XmlPullParserException e) { throw new InflateException("Error inflating menu XML", e); } catch (IOException e) { throw new InflateException("Error inflating menu XML", e); } finally { if (parser != null) parser.close(); } }
private AttributeSet getAttributeSet(int resourceId) { final XmlResourceParser parser = getContext().getResources().getXml(resourceId); try { XmlUtils.beginDocument(parser, "RelativeLayout"); } catch (XmlPullParserException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } final AttributeSet attr = Xml.asAttributeSet(parser); assertNotNull(attr); return attr; }
private KeyboardRow parseRowAttributes(final XmlPullParser parser) throws XmlPullParserException { final AttributeSet attr = Xml.asAttributeSet(parser); final TypedArray keyboardAttr = mResources.obtainAttributes(attr, R.styleable.Keyboard); try { if (keyboardAttr.hasValue(R.styleable.Keyboard_horizontalGap)) { throw new XmlParseUtils.IllegalAttribute(parser, TAG_ROW, "horizontalGap"); } if (keyboardAttr.hasValue(R.styleable.Keyboard_verticalGap)) { throw new XmlParseUtils.IllegalAttribute(parser, TAG_ROW, "verticalGap"); } return new KeyboardRow(mResources, mParams, parser, mCurrentY); } finally { keyboardAttr.recycle(); } }
private void parseIncludeInternal( final XmlPullParser parser, final KeyboardRow row, final boolean skip) throws XmlPullParserException, IOException { if (skip) { XmlParseUtils.checkEndTag(TAG_INCLUDE, parser); if (DEBUG) startEndTag("</%s> skipped", TAG_INCLUDE); return; } final AttributeSet attr = Xml.asAttributeSet(parser); final TypedArray keyboardAttr = mResources.obtainAttributes(attr, R.styleable.Keyboard_Include); final TypedArray keyAttr = mResources.obtainAttributes(attr, R.styleable.Keyboard_Key); int keyboardLayout = 0; try { XmlParseUtils.checkAttributeExists( keyboardAttr, R.styleable.Keyboard_Include_keyboardLayout, "keyboardLayout", TAG_INCLUDE, parser); keyboardLayout = keyboardAttr.getResourceId(R.styleable.Keyboard_Include_keyboardLayout, 0); if (row != null) { // Override current x coordinate. row.setXPos(row.getKeyX(keyAttr)); // Push current Row attributes and update with new attributes. row.pushRowAttributes(keyAttr); } } finally { keyboardAttr.recycle(); keyAttr.recycle(); } XmlParseUtils.checkEndTag(TAG_INCLUDE, parser); if (DEBUG) { startEndTag( "<%s keyboardLayout=%s />", TAG_INCLUDE, mResources.getResourceEntryName(keyboardLayout)); } final XmlResourceParser parserForInclude = mResources.getXml(keyboardLayout); try { parseMerge(parserForInclude, row, skip); } finally { if (row != null) { // Restore Row attributes. row.popRowAttributes(); } parserForInclude.close(); } }
@TestTargets({ @TestTargetNew( level = TestLevel.COMPLETE, notes = "Test constructor(s) of {@link ImageView}", method = "ImageView", args = {android.content.Context.class} ), @TestTargetNew( level = TestLevel.COMPLETE, notes = "Test constructor(s) of {@link ImageView}", method = "ImageView", args = {android.content.Context.class, android.util.AttributeSet.class} ), @TestTargetNew( level = TestLevel.COMPLETE, notes = "Test constructor(s) of {@link ImageView}", method = "ImageView", args = {android.content.Context.class, android.util.AttributeSet.class, int.class} ) }) @ToBeFixed(bug = "1417734", explanation = "ImageView#ImageView(Context, AttributeSet) and " + "ImageView#ImageView(Context, AttributeSet, int)" + " should check whether the input Context is null") public void testConstructor() { new ImageView(mActivity); new ImageView(mActivity, null); new ImageView(mActivity, null, 0); XmlPullParser parser = mActivity.getResources().getXml(R.layout.imageview_layout); AttributeSet attrs = Xml.asAttributeSet(parser); new ImageView(mActivity, attrs); new ImageView(mActivity, attrs, 0); try { new ImageView(null, null); fail("should throw NullPointerException."); } catch (NullPointerException e) { } try { new ImageView(null, null, 0); fail("should throw NullPointerException."); } catch (NullPointerException e) { } }
private ServiceInfo<AuthenticatorDescription> parseServiceInfo(ResolveInfo service) throws XmlPullParserException, IOException { android.content.pm.ServiceInfo si = service.serviceInfo; ComponentName componentName = new ComponentName(si.packageName, si.name); PackageManager pm = this.mContext.getPackageManager(); XmlResourceParser parser = null; try { parser = si.loadXmlMetaData(pm, this.mMetaDataName); if (parser == null) { throw new XmlPullParserException("No " + this.mMetaDataName + " meta-data"); } AttributeSet attrs = Xml.asAttributeSet(parser); int type; do { type = parser.next(); if (type == 1) { break; } } while (type != 2); if (this.mAttributesName.equals(parser.getName())) { ServiceInfo<AuthenticatorDescription> serviceInfo; AuthenticatorDescription v = parseServiceAttributes( pm.getResourcesForApplication(si.applicationInfo), si.packageName, attrs); if (v == null) { serviceInfo = null; if (parser != null) { parser.close(); } } else { serviceInfo = new ServiceInfo(v, componentName, service.serviceInfo.applicationInfo.uid); if (parser != null) { parser.close(); } } return serviceInfo; } throw new XmlPullParserException( "Meta-data does not start with " + this.mAttributesName + " tag"); } catch (NameNotFoundException e) { throw new XmlPullParserException("Unable to load resources for pacakge " + si.packageName); } catch (Throwable th) { if (parser != null) { parser.close(); } } }
public boolean onCreateActionMode(ActionMode mode, Menu menu) { mActionMode = mode; // First inflate the menu - default action mode.getMenuInflater().inflate(mMenuResId, menu); // Now, parse the menu XmlResourceParser parser = mContext.getResources().getXml(mMenuResId); try { int eventType = parser.getEventType(); while (eventType != XmlResourceParser.END_DOCUMENT) { if (eventType == XmlResourceParser.START_TAG) { int id = parser.getAttributeResourceValue(Binder.ANDROID_NAMESPACE, "id", -1); MenuItem mi = menu.findItem(id); if (mi != null) { String nodeName = parser.getName(); if (id > 0) { AttributeSet attrs = Xml.asAttributeSet(parser); AbsMenuBridge item = null; if ("item".equals(nodeName)) { item = new MenuItemBridge(id, attrs, mContext, mModel, this); } else if ("group".equals(nodeName)) { item = new MenuGroupBridge(id, attrs, mContext, mModel, this); } if (item != null) { items.put(id, item); } } } } eventType = parser.next(); } } catch (XmlPullParserException e) { e.printStackTrace(); } catch (IOException ex) { ex.printStackTrace(); } for (AbsMenuBridge item : items.values()) { item.onCreateOptionItem(menu); item.onPrepareOptionItem(menu); } return true; }
@TestTargets({ @TestTargetNew( level = TestLevel.COMPLETE, method = "getIntrinsicWidth", args = {}), @TestTargetNew( level = TestLevel.COMPLETE, method = "getIntrinsicHeight", args = {}), @TestTargetNew( level = TestLevel.COMPLETE, method = "inflate", args = { android.content.res.Resources.class, org.xmlpull.v1.XmlPullParser.class, android.util.AttributeSet.class }) }) public void testGetIntrinsicWidthAndHeight() throws XmlPullParserException, IOException { // testimage is set in res/drawable/rotatedrawable.xml Drawable drawable = mContext.getResources().getDrawable(R.drawable.testimage); assertEquals(drawable.getIntrinsicWidth(), mRotateDrawable.getIntrinsicWidth()); assertEquals(drawable.getIntrinsicHeight(), mRotateDrawable.getIntrinsicHeight()); RotateDrawable rotateDrawable = new RotateDrawable(); Resources r = mContext.getResources(); XmlPullParser parser = r.getXml(R.drawable.rotatedrawable); while (parser.next() != XmlPullParser.START_TAG) { // ignore event, just seek to first tag } AttributeSet attrs = Xml.asAttributeSet(parser); rotateDrawable.inflate(r, parser, attrs); assertEquals(drawable.getIntrinsicWidth(), rotateDrawable.getIntrinsicWidth()); assertEquals(drawable.getIntrinsicHeight(), rotateDrawable.getIntrinsicHeight()); try { mRotateDrawable.inflate(null, null, null); fail("did not throw NullPointerException when parameters are null."); } catch (NullPointerException e) { // expected, test success } }
@TestTargetNew( level = TestLevel.COMPLETE, method = "inflate", args = { android.content.res.Resources.class, org.xmlpull.v1.XmlPullParser.class, android.util.AttributeSet.class }) @ToBeFixed( bug = "1386429", explanation = "no getter can not be tested," + " and there should not be a NullPointerException thrown out.") public void testInflate() { Drawable d = mContext.getResources().getDrawable(R.drawable.pass); InsetDrawable insetDrawable = new InsetDrawable(d, 0); Resources r = mContext.getResources(); XmlPullParser parser = r.getXml(R.layout.framelayout_layout); AttributeSet attrs = Xml.asAttributeSet(parser); try { insetDrawable.inflate(r, parser, attrs); fail("There should be a XmlPullParserException thrown out."); } catch (XmlPullParserException e) { // expected, test success } catch (IOException e) { fail("There should not be an IOException thrown out."); } // input null as params try { insetDrawable.inflate(null, null, null); fail("There should be a NullPointerException thrown out."); } catch (XmlPullParserException e) { fail("There should not be a XmlPullParserException thrown out."); } catch (IOException e) { fail("There should not be an IOException thrown out."); } catch (NullPointerException e) { // expected, test success } }
/** * Inflate a new hierarchy from the specified XML node. Throws InflaterException if there is an * error. * * <p><em><strong>Important</strong></em> For performance reasons, inflation * relies heavily on pre-processing of XML files that is done at build time. Therefore, it is not * currently possible to use inflater with an XmlPullParser over a plain XML file at runtime. * * @param parser XML dom node containing the description of the hierarchy. * @param root Optional to be the parent of the generated hierarchy (if <em>attachToRoot</em> is * true), or else simply an object that provides a set of values for root of the returned * hierarchy (if <em>attachToRoot</em> is false.) * @return The root of the inflated hierarchy. If root was supplied, this is root; otherwise it is * the root of the inflated XML file. */ public Preference inflate(XmlPullParser parser, @Nullable PreferenceGroup root) { synchronized (mConstructorArgs) { final AttributeSet attrs = Xml.asAttributeSet(parser); mConstructorArgs[0] = mContext; final Preference result; try { // Look for the root node. int type; do { type = parser.next(); } while (type != XmlPullParser.START_TAG && type != XmlPullParser.END_DOCUMENT); if (type != XmlPullParser.START_TAG) { throw new InflateException(parser.getPositionDescription() + ": No start tag found!"); } // Temp is the root that was found in the xml Preference xmlRoot = createItemFromTag(parser.getName(), attrs); result = onMergeRoots(root, (PreferenceGroup) xmlRoot); // Inflate all children under temp rInflate(parser, result, attrs); } catch (InflateException e) { throw e; } catch (XmlPullParserException e) { final InflateException ex = new InflateException(e.getMessage()); ex.initCause(e); throw ex; } catch (IOException e) { final InflateException ex = new InflateException(parser.getPositionDescription() + ": " + e.getMessage()); ex.initCause(e); throw ex; } return result; } }
private void parseKeyboardAttributes( Context askContext, Resources res, XmlResourceParser parser) { TypedArray a = res.obtainAttributes(Xml.asAttributeSet(parser), remoteKeyboardLayoutStyleable); Resources askRes = askContext.getResources(); // some defaults mDefaultWidth = mDisplayWidth / 10; mDefaultHeightCode = -1; mDefaultHorizontalGap = 0; mDefaultVerticalGap = askRes.getDimensionPixelOffset(R.dimen.default_key_vertical_gap); // now reading from XML int n = a.getIndexCount(); for (int i = 0; i < n; i++) { final int remoteIndex = a.getIndex(i); final int localAttrId = attributeIdMap.get(remoteKeyboardLayoutStyleable[remoteIndex]); try { switch (localAttrId) { case android.R.attr.keyWidth: mDefaultWidth = getDimensionOrFraction(a, remoteIndex, mDisplayWidth, mDisplayWidth / 10); break; case android.R.attr.keyHeight: mDefaultHeightCode = getKeyHeightCode(a, remoteIndex, -1); break; case android.R.attr.horizontalGap: mDefaultHorizontalGap = getDimensionOrFraction(a, remoteIndex, mDisplayWidth, 0); break; case android.R.attr.verticalGap: mDefaultVerticalGap = getDimensionOrFraction(a, remoteIndex, mDisplayWidth, mDefaultVerticalGap); break; } } catch (Exception e) { Log.w(TAG, "Failed to set data from XML!", e); } } a.recycle(); mProximityThreshold = (int) (mDefaultWidth * SEARCH_DISTANCE); // Square it for comparison mProximityThreshold = mProximityThreshold * mProximityThreshold; }
public void testInflate() throws XmlPullParserException, IOException { final int width = 80; final int height = 120; final int[] COLOR = new int[width * height]; Bitmap bitmap = Bitmap.createBitmap(COLOR, width, height, Bitmap.Config.RGB_565); NinePatchDrawable ninePatchDrawable = new NinePatchDrawable(mResources, bitmap, new byte[1000], null, "TESTNAME"); assertEquals(height, ninePatchDrawable.getIntrinsicHeight()); assertEquals(width, ninePatchDrawable.getIntrinsicWidth()); XmlResourceParser parser = mResources.getXml(R.drawable.ninepatchdrawable); int type; while ((type = parser.next()) != XmlPullParser.END_DOCUMENT && type != XmlPullParser.START_TAG) {} AttributeSet attrs = Xml.asAttributeSet(parser); ninePatchDrawable.inflate(mResources, parser, attrs); assertTrue(ninePatchDrawable.getPaint().isDither()); assertTrue(height != ninePatchDrawable.getIntrinsicHeight()); assertTrue(width != ninePatchDrawable.getIntrinsicWidth()); }
public static Drawable createFromXml(Context c, Resources r, XmlPullParser parser) throws XmlPullParserException, IOException, NoSuchMethodException { AttributeSet attrs = Xml.asAttributeSet(parser); int type; while ((type = parser.next()) != XmlPullParser.START_TAG && type != XmlPullParser.END_DOCUMENT) { // Empty loop. } if (type != XmlPullParser.START_TAG) { throw new XmlPullParserException("No start tag found"); } Drawable drawable = createFromXmlInner(c, r, parser, attrs); if (drawable == null) { throw new RuntimeException("Unknown initial tag: " + parser.getName()); } return drawable; }
/** * 获取字符串id对应的url * * @param strId * @param context * @return url */ public static String getUrl(int strId, Context context) { try { XmlResourceParser parser = context.getResources().getXml(R.xml.address); AttributeSet attrs = Xml.asAttributeSet(parser); XmlUtils.beginDocument(parser, TAG_FTP); final int depth = parser.getDepth(); int type; while (((type = parser.next()) != XmlPullParser.END_TAG || parser.getDepth() > depth) && type != XmlPullParser.END_DOCUMENT) { if (type != XmlPullParser.START_TAG) { continue; } final String name = parser.getName(); TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.UrlAddress); if (TAG_URLADDRESS.equals(name)) { int id = a.getResourceId(R.styleable.UrlAddress_refId, 0); if (id == strId) { String url = a.getString(R.styleable.UrlAddress_address); a.recycle(); a = null; parser.close(); parser = null; return url; } } a.recycle(); } parser.close(); parser = null; } catch (XmlPullParserException e) { } catch (IOException e) { } return null; }
/** * 获取下载地址 配置文件在res/xml/address.xml * * @param context * @return */ public static HashMap<Integer, String> getUrlList(Context context) { try { XmlResourceParser parser = context.getResources().getXml(R.xml.address); AttributeSet attrs = Xml.asAttributeSet(parser); XmlUtils.beginDocument(parser, TAG_FTP); HashMap<Integer, String> urlMap = new HashMap<Integer, String>(8); final int depth = parser.getDepth(); int type; while (((type = parser.next()) != XmlPullParser.END_TAG || parser.getDepth() > depth) && type != XmlPullParser.END_DOCUMENT) { if (type != XmlPullParser.START_TAG) { continue; } TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.UrlAddress); final String name = parser.getName(); if (TAG_URLADDRESS.equals(name)) { UrlAddress address = getUrlAddress(a); if (address != null && address.mStringId > 0) { urlMap.put(address.mStringId, address.mUrl); } address = null; } a.recycle(); } parser.close(); parser = null; return urlMap; } catch (XmlPullParserException e) { } catch (IOException e) { } return null; }
/** * Parse the given XML file as a header description, adding each parsed Header into the target * list. * * @param resid The XML resource to load and parse. * @param target The list in which the parsed headers should be placed. */ public void loadHeadersFromResource(int resid, List<Header> target) { XmlResourceParser parser = null; try { parser = getResources().getXml(resid); AttributeSet attrs = Xml.asAttributeSet(parser); int type; while ((type = parser.next()) != XmlPullParser.END_DOCUMENT && type != XmlPullParser.START_TAG) { // Parse next until start tag is found } String nodeName = parser.getName(); if (!"preference-headers".equals(nodeName)) { throw new RuntimeException( "XML document must start with <preference-headers> tag; found" + nodeName + " at " + parser.getPositionDescription()); } Bundle curBundle = null; final int outerDepth = parser.getDepth(); while ((type = parser.next()) != XmlPullParser.END_DOCUMENT && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { continue; } nodeName = parser.getName(); if ("header".equals(nodeName)) { Header header = new Header(); TypedArray sa = getResources().obtainAttributes(attrs, R.styleable.PreferenceHeader); header.id = sa.getResourceId(R.styleable.PreferenceHeader_id, (int) HEADER_ID_UNDEFINED); TypedValue tv = sa.peekValue(R.styleable.PreferenceHeader_title); if (tv != null && tv.type == TypedValue.TYPE_STRING) { if (tv.resourceId != 0) { header.titleRes = tv.resourceId; } else { header.title = tv.string; } } tv = sa.peekValue(R.styleable.PreferenceHeader_summary); if (tv != null && tv.type == TypedValue.TYPE_STRING) { if (tv.resourceId != 0) { header.summaryRes = tv.resourceId; } else { header.summary = tv.string; } } tv = sa.peekValue(R.styleable.PreferenceHeader_breadCrumbTitle); if (tv != null && tv.type == TypedValue.TYPE_STRING) { if (tv.resourceId != 0) { header.breadCrumbTitleRes = tv.resourceId; } else { header.breadCrumbTitle = tv.string; } } tv = sa.peekValue(R.styleable.PreferenceHeader_breadCrumbShortTitle); if (tv != null && tv.type == TypedValue.TYPE_STRING) { if (tv.resourceId != 0) { header.breadCrumbShortTitleRes = tv.resourceId; } else { header.breadCrumbShortTitle = tv.string; } } header.iconRes = sa.getResourceId(R.styleable.PreferenceHeader_icon, 0); header.fragment = sa.getString(R.styleable.PreferenceHeader_fragment); sa.recycle(); if (curBundle == null) { curBundle = new Bundle(); } final int innerDepth = parser.getDepth(); while ((type = parser.next()) != XmlPullParser.END_DOCUMENT && (type != XmlPullParser.END_TAG || parser.getDepth() > innerDepth)) { if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { continue; } String innerNodeName = parser.getName(); if (innerNodeName.equals("extra")) { getResources().parseBundleExtra("extra", attrs, curBundle); XmlUtils.skipCurrentTag(parser); } else if (innerNodeName.equals("intent")) { header.intent = Intent.parseIntent(getResources(), parser, attrs); } else { XmlUtils.skipCurrentTag(parser); } } if (curBundle.size() > 0) { header.fragmentArguments = curBundle; curBundle = null; } target.add(header); } else { XmlUtils.skipCurrentTag(parser); } } } catch (XmlPullParserException e) { throw new RuntimeException("Error parsing headers", e); } catch (IOException e) { throw new RuntimeException("Error parsing headers", e); } finally { if (parser != null) parser.close(); } }
/** * Loads the default set of favorite packages from an xml file. * * @param db The database to write the values into */ private int loadFavorites(SQLiteDatabase db) { Intent intent = new Intent(Intent.ACTION_MAIN, null); intent.addCategory(Intent.CATEGORY_LAUNCHER); ContentValues values = new ContentValues(); PackageManager packageManager = mContext.getPackageManager(); int i = 0; try { String optr = SystemProperties.get("ro.operator.optr"); XmlResourceParser parser = null; if (optr.equals("OP02")) { parser = mContext.getResources().getXml(R.xml.cu_workspace); } else { parser = mContext.getResources().getXml(R.xml.default_workspace); } AttributeSet attrs = Xml.asAttributeSet(parser); XmlUtils.beginDocument(parser, TAG_FAVORITES); final int depth = parser.getDepth(); int type; while (((type = parser.next()) != XmlPullParser.END_TAG || parser.getDepth() > depth) && type != XmlPullParser.END_DOCUMENT) { if (type != XmlPullParser.START_TAG) { continue; } boolean added = false; final String name = parser.getName(); TypedArray a = mContext.obtainStyledAttributes(attrs, R.styleable.Favorite); values.clear(); values.put( LauncherSettings.Favorites.CONTAINER, LauncherSettings.Favorites.CONTAINER_DESKTOP); values.put(LauncherSettings.Favorites.SCREEN, a.getString(R.styleable.Favorite_screen)); values.put(LauncherSettings.Favorites.CELLX, a.getString(R.styleable.Favorite_x)); values.put(LauncherSettings.Favorites.CELLY, a.getString(R.styleable.Favorite_y)); if (TAG_FAVORITE.equals(name)) { added = addAppShortcut(db, values, a, packageManager, intent); } else if (TAG_SEARCH.equals(name)) { added = addSearchWidget(db, values); } else if (TAG_CLOCK.equals(name)) { added = addClockWidget(db, values); } else if (TAG_APPWIDGET.equals(name)) { added = addAppWidget(db, values, a, packageManager); } else if (TAG_SHORTCUT.equals(name)) { added = addUriShortcut(db, values, a); } if (added) i++; a.recycle(); } } catch (XmlPullParserException e) { Log.w(TAG, "Got exception parsing favorites.", e); } catch (IOException e) { Log.w(TAG, "Got exception parsing favorites.", e); } return i; }
private Drawable loadDrawableFromDelegates(Context paramContext, int paramInt) { if ((mDelegates != null) && (!mDelegates.isEmpty())) { if (mKnownDrawableIdTags != null) { localObject1 = (String) mKnownDrawableIdTags.get(paramInt); if (("appcompat_skip_skip".equals(localObject1)) || ((localObject1 != null) && (mDelegates.get(localObject1) == null))) { localObject1 = null; return (Drawable) localObject1; } } else { mKnownDrawableIdTags = new SparseArray(); } if (mTypedValue == null) { mTypedValue = new TypedValue(); } TypedValue localTypedValue = mTypedValue; Object localObject1 = paramContext.getResources(); ((Resources) localObject1).getValue(paramInt, localTypedValue, true); long l = assetCookie << 32 | data; Drawable localDrawable = getCachedDelegateDrawable(paramContext, l); if (localDrawable != null) { return localDrawable; } Object localObject2 = localDrawable; XmlResourceParser localXmlResourceParser; AttributeSet localAttributeSet; if (string != null) { localObject2 = localDrawable; if (string.toString().endsWith(".xml")) { localObject2 = localDrawable; try { localXmlResourceParser = ((Resources) localObject1).getXml(paramInt); localObject2 = localDrawable; localAttributeSet = Xml.asAttributeSet(localXmlResourceParser); int i; do { localObject2 = localDrawable; i = localXmlResourceParser.next(); } while ((i != 2) && (i != 1)); if (i != 2) { localObject2 = localDrawable; throw new XmlPullParserException("No start tag found"); } } catch (Exception paramContext) { Log.e("AppCompatDrawableManager", "Exception while inflating drawable", paramContext); } } } for (paramContext = (Context) localObject2; ; paramContext = (Context) localObject1) { localObject1 = paramContext; if (paramContext != null) { break; } mKnownDrawableIdTags.append(paramInt, "appcompat_skip_skip"); return paramContext; localObject2 = localDrawable; localObject1 = localXmlResourceParser.getName(); localObject2 = localDrawable; mKnownDrawableIdTags.append(paramInt, localObject1); localObject2 = localDrawable; AppCompatDrawableManager.InflateDelegate localInflateDelegate = (AppCompatDrawableManager.InflateDelegate) mDelegates.get(localObject1); localObject1 = localDrawable; if (localInflateDelegate != null) { localObject2 = localDrawable; localObject1 = localInflateDelegate.createFromXmlInner( paramContext, localXmlResourceParser, localAttributeSet, paramContext.getTheme()); } if (localObject1 != null) { localObject2 = localObject1; ((Drawable) localObject1).setChangingConfigurations(changingConfigurations); localObject2 = localObject1; boolean bool = addCachedDelegateDrawable(paramContext, l, (Drawable) localObject1); if (!bool) {} } } } return null; }
/** * Create a key with the given top-left coordinate and extract its attributes from the XML parser. * * @param res resources associated with the caller's context * @param params the keyboard building parameters. * @param row the row that this key belongs to. row's x-coordinate will be the right edge of this * key. * @param parser the XML parser containing the attributes for this key * @throws XmlPullParserException */ public Key(Resources res, Keyboard.Params params, Keyboard.Builder.Row row, XmlPullParser parser) throws XmlPullParserException { final float horizontalGap = isSpacer() ? 0 : params.mHorizontalGap; final int keyHeight = row.mRowHeight; mVerticalGap = params.mVerticalGap; mHeight = keyHeight - mVerticalGap; final TypedArray keyAttr = res.obtainAttributes(Xml.asAttributeSet(parser), R.styleable.Keyboard_Key); final KeyStyle style = params.mKeyStyles.getKeyStyle(keyAttr, parser); final float keyXPos = row.getKeyX(keyAttr); final float keyWidth = row.getKeyWidth(keyAttr, keyXPos); final int keyYPos = row.getKeyY(); // Horizontal gap is divided equally to both sides of the key. mX = Math.round(keyXPos + horizontalGap / 2); mY = keyYPos; mWidth = Math.round(keyWidth - horizontalGap); mHorizontalGap = Math.round(horizontalGap); mHitBox.set( Math.round(keyXPos), keyYPos, Math.round(keyXPos + keyWidth) + 1, keyYPos + keyHeight); // Update row to have current x coordinate. row.setXPos(keyXPos + keyWidth); mBackgroundType = style.getInt( keyAttr, R.styleable.Keyboard_Key_backgroundType, row.getDefaultBackgroundType()); mVisualInsetsLeft = Math.round( Keyboard.Builder.getDimensionOrFraction( keyAttr, R.styleable.Keyboard_Key_visualInsetsLeft, params.mBaseWidth, 0)); mVisualInsetsRight = Math.round( Keyboard.Builder.getDimensionOrFraction( keyAttr, R.styleable.Keyboard_Key_visualInsetsRight, params.mBaseWidth, 0)); mIconId = KeySpecParser.getIconId(style.getString(keyAttr, R.styleable.Keyboard_Key_keyIcon)); mDisabledIconId = KeySpecParser.getIconId(style.getString(keyAttr, R.styleable.Keyboard_Key_keyIconDisabled)); mPreviewIconId = KeySpecParser.getIconId(style.getString(keyAttr, R.styleable.Keyboard_Key_keyIconPreview)); mLabelFlags = style.getFlag(keyAttr, R.styleable.Keyboard_Key_keyLabelFlags) | row.getDefaultKeyLabelFlags(); final boolean needsToUpperCase = needsToUpperCase(mLabelFlags, params.mId.mElementId); final Locale locale = params.mId.mLocale; int actionFlags = style.getFlag(keyAttr, R.styleable.Keyboard_Key_keyActionFlags); String[] moreKeys = style.getStringArray(keyAttr, R.styleable.Keyboard_Key_moreKeys); int moreKeysColumn = style.getInt( keyAttr, R.styleable.Keyboard_Key_maxMoreKeysColumn, params.mMaxMoreKeysKeyboardColumn); int value; if ((value = KeySpecParser.getIntValue(moreKeys, MORE_KEYS_AUTO_COLUMN_ORDER, -1)) > 0) { moreKeysColumn = value & MORE_KEYS_COLUMN_MASK; } if ((value = KeySpecParser.getIntValue(moreKeys, MORE_KEYS_FIXED_COLUMN_ORDER, -1)) > 0) { moreKeysColumn = MORE_KEYS_FLAGS_FIXED_COLUMN_ORDER | (value & MORE_KEYS_COLUMN_MASK); } if (KeySpecParser.getBooleanValue(moreKeys, MORE_KEYS_HAS_LABELS)) { moreKeysColumn |= MORE_KEYS_FLAGS_HAS_LABELS; } if (KeySpecParser.getBooleanValue(moreKeys, MORE_KEYS_NEEDS_DIVIDERS)) { moreKeysColumn |= MORE_KEYS_FLAGS_NEEDS_DIVIDERS; } if (KeySpecParser.getBooleanValue(moreKeys, MORE_KEYS_EMBEDDED_MORE_KEY)) { moreKeysColumn |= MORE_KEYS_FLAGS_EMBEDDED_MORE_KEY; } mMoreKeysColumnAndFlags = moreKeysColumn; final String[] additionalMoreKeys; if ((mLabelFlags & LABEL_FLAGS_DISABLE_ADDITIONAL_MORE_KEYS) != 0) { additionalMoreKeys = null; } else { additionalMoreKeys = style.getStringArray(keyAttr, R.styleable.Keyboard_Key_additionalMoreKeys); } moreKeys = KeySpecParser.insertAdditionalMoreKeys(moreKeys, additionalMoreKeys); if (moreKeys != null) { actionFlags |= ACTION_FLAGS_ENABLE_LONG_PRESS; mMoreKeys = new MoreKeySpec[moreKeys.length]; for (int i = 0; i < moreKeys.length; i++) { mMoreKeys[i] = new MoreKeySpec(moreKeys[i], needsToUpperCase, locale, params.mCodesSet); } } else { mMoreKeys = null; } mActionFlags = actionFlags; if ((mLabelFlags & LABEL_FLAGS_FROM_CUSTOM_ACTION_LABEL) != 0) { mLabel = params.mId.mCustomActionLabel; } else { mLabel = KeySpecParser.toUpperCaseOfStringForLocale( style.getString(keyAttr, R.styleable.Keyboard_Key_keyLabel), needsToUpperCase, locale); } if ((mLabelFlags & LABEL_FLAGS_DISABLE_HINT_LABEL) != 0) { mHintLabel = null; } else { mHintLabel = KeySpecParser.toUpperCaseOfStringForLocale( style.getString(keyAttr, R.styleable.Keyboard_Key_keyHintLabel), needsToUpperCase, locale); } String outputText = KeySpecParser.toUpperCaseOfStringForLocale( style.getString(keyAttr, R.styleable.Keyboard_Key_keyOutputText), needsToUpperCase, locale); final int code = KeySpecParser.parseCode( style.getString(keyAttr, R.styleable.Keyboard_Key_code), params.mCodesSet, CODE_UNSPECIFIED); // Choose the first letter of the label as primary code if not specified. if (code == CODE_UNSPECIFIED && TextUtils.isEmpty(outputText) && !TextUtils.isEmpty(mLabel)) { if (StringUtils.codePointCount(mLabel) == 1) { // Use the first letter of the hint label if shiftedLetterActivated flag is // specified. if (hasShiftedLetterHint() && isShiftedLetterActivated() && !TextUtils.isEmpty(mHintLabel)) { mCode = mHintLabel.codePointAt(0); } else { mCode = mLabel.codePointAt(0); } } else { // In some locale and case, the character might be represented by multiple code // points, such as upper case Eszett of German alphabet. outputText = mLabel; mCode = CODE_OUTPUT_TEXT; } } else if (code == CODE_UNSPECIFIED && outputText != null) { if (StringUtils.codePointCount(outputText) == 1) { mCode = outputText.codePointAt(0); outputText = null; } else { mCode = CODE_OUTPUT_TEXT; } } else { mCode = KeySpecParser.toUpperCaseOfCodeForLocale(code, needsToUpperCase, locale); } mOutputText = outputText; mAltCode = KeySpecParser.toUpperCaseOfCodeForLocale( KeySpecParser.parseCode( style.getString(keyAttr, R.styleable.Keyboard_Key_altCode), params.mCodesSet, CODE_UNSPECIFIED), needsToUpperCase, locale); mHashCode = computeHashCode(this); keyAttr.recycle(); if (hasShiftedLetterHint() && TextUtils.isEmpty(mHintLabel)) { Log.w(TAG, "hasShiftedLetterHint specified without keyHintLabel: " + this); } }
private boolean parseCaseCondition(final XmlPullParser parser) { final KeyboardId id = mParams.mId; if (id == null) { return true; } final AttributeSet attr = Xml.asAttributeSet(parser); final TypedArray caseAttr = mResources.obtainAttributes(attr, R.styleable.Keyboard_Case); try { final boolean keyboardLayoutSetMatched = matchString( caseAttr, R.styleable.Keyboard_Case_keyboardLayoutSet, SubtypeLocaleUtils.getKeyboardLayoutSetName(id.mSubtype)); final boolean keyboardLayoutSetElementMatched = matchTypedValue( caseAttr, R.styleable.Keyboard_Case_keyboardLayoutSetElement, id.mElementId, KeyboardId.elementIdToName(id.mElementId)); final boolean modeMatched = matchTypedValue( caseAttr, R.styleable.Keyboard_Case_mode, id.mMode, KeyboardId.modeName(id.mMode)); final boolean navigateNextMatched = matchBoolean(caseAttr, R.styleable.Keyboard_Case_navigateNext, id.navigateNext()); final boolean navigatePreviousMatched = matchBoolean(caseAttr, R.styleable.Keyboard_Case_navigatePrevious, id.navigatePrevious()); final boolean passwordInputMatched = matchBoolean(caseAttr, R.styleable.Keyboard_Case_passwordInput, id.passwordInput()); final boolean clobberSettingsKeyMatched = matchBoolean( caseAttr, R.styleable.Keyboard_Case_clobberSettingsKey, id.mClobberSettingsKey); final boolean shortcutKeyEnabledMatched = matchBoolean( caseAttr, R.styleable.Keyboard_Case_shortcutKeyEnabled, id.mShortcutKeyEnabled); final boolean shortcutKeyOnSymbolsMatched = matchBoolean( caseAttr, R.styleable.Keyboard_Case_shortcutKeyOnSymbols, id.mShortcutKeyOnSymbols); final boolean hasShortcutKeyMatched = matchBoolean(caseAttr, R.styleable.Keyboard_Case_hasShortcutKey, id.mHasShortcutKey); final boolean languageSwitchKeyEnabledMatched = matchBoolean( caseAttr, R.styleable.Keyboard_Case_languageSwitchKeyEnabled, id.mLanguageSwitchKeyEnabled); final boolean isMultiLineMatched = matchBoolean(caseAttr, R.styleable.Keyboard_Case_isMultiLine, id.isMultiLine()); final boolean imeActionMatched = matchInteger(caseAttr, R.styleable.Keyboard_Case_imeAction, id.imeAction()); final boolean localeCodeMatched = matchString(caseAttr, R.styleable.Keyboard_Case_localeCode, id.mLocale.toString()); final boolean languageCodeMatched = matchString(caseAttr, R.styleable.Keyboard_Case_languageCode, id.mLocale.getLanguage()); final boolean countryCodeMatched = matchString(caseAttr, R.styleable.Keyboard_Case_countryCode, id.mLocale.getCountry()); final boolean selected = keyboardLayoutSetMatched && keyboardLayoutSetElementMatched && modeMatched && navigateNextMatched && navigatePreviousMatched && passwordInputMatched && clobberSettingsKeyMatched && shortcutKeyEnabledMatched && shortcutKeyOnSymbolsMatched && hasShortcutKeyMatched && languageSwitchKeyEnabledMatched && isMultiLineMatched && imeActionMatched && localeCodeMatched && languageCodeMatched && countryCodeMatched; if (DEBUG) { startTag( "<%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s>%s", TAG_CASE, textAttr( caseAttr.getString(R.styleable.Keyboard_Case_keyboardLayoutSet), "keyboardLayoutSet"), textAttr( caseAttr.getString(R.styleable.Keyboard_Case_keyboardLayoutSetElement), "keyboardLayoutSetElement"), textAttr(caseAttr.getString(R.styleable.Keyboard_Case_mode), "mode"), textAttr(caseAttr.getString(R.styleable.Keyboard_Case_imeAction), "imeAction"), booleanAttr(caseAttr, R.styleable.Keyboard_Case_navigateNext, "navigateNext"), booleanAttr(caseAttr, R.styleable.Keyboard_Case_navigatePrevious, "navigatePrevious"), booleanAttr( caseAttr, R.styleable.Keyboard_Case_clobberSettingsKey, "clobberSettingsKey"), booleanAttr(caseAttr, R.styleable.Keyboard_Case_passwordInput, "passwordInput"), booleanAttr( caseAttr, R.styleable.Keyboard_Case_shortcutKeyEnabled, "shortcutKeyEnabled"), booleanAttr( caseAttr, R.styleable.Keyboard_Case_shortcutKeyOnSymbols, "shortcutKeyOnSymbols"), booleanAttr(caseAttr, R.styleable.Keyboard_Case_hasShortcutKey, "hasShortcutKey"), booleanAttr( caseAttr, R.styleable.Keyboard_Case_languageSwitchKeyEnabled, "languageSwitchKeyEnabled"), booleanAttr(caseAttr, R.styleable.Keyboard_Case_isMultiLine, "isMultiLine"), textAttr(caseAttr.getString(R.styleable.Keyboard_Case_localeCode), "localeCode"), textAttr(caseAttr.getString(R.styleable.Keyboard_Case_languageCode), "languageCode"), textAttr(caseAttr.getString(R.styleable.Keyboard_Case_countryCode), "countryCode"), selected ? "" : " skipped"); } return selected; } finally { caseAttr.recycle(); } }
private void parseGridRows(final XmlPullParser parser, final boolean skip) throws XmlPullParserException, IOException { if (skip) { XmlParseUtils.checkEndTag(TAG_GRID_ROWS, parser); if (DEBUG) { startEndTag("<%s /> skipped", TAG_GRID_ROWS); } return; } final KeyboardRow gridRows = new KeyboardRow(mResources, mParams, parser, mCurrentY); final TypedArray gridRowAttr = mResources.obtainAttributes(Xml.asAttributeSet(parser), R.styleable.Keyboard_GridRows); final int codesArrayId = gridRowAttr.getResourceId(R.styleable.Keyboard_GridRows_codesArray, 0); final int textsArrayId = gridRowAttr.getResourceId(R.styleable.Keyboard_GridRows_textsArray, 0); gridRowAttr.recycle(); if (codesArrayId == 0 && textsArrayId == 0) { throw new XmlParseUtils.ParseException("Missing codesArray or textsArray attributes", parser); } if (codesArrayId != 0 && textsArrayId != 0) { throw new XmlParseUtils.ParseException( "Both codesArray and textsArray attributes specifed", parser); } final String[] array = mResources.getStringArray(codesArrayId != 0 ? codesArrayId : textsArrayId); final int counts = array.length; final float keyWidth = gridRows.getKeyWidth(null, 0.0f); final int numColumns = (int) (mParams.mOccupiedWidth / keyWidth); for (int index = 0; index < counts; index += numColumns) { final KeyboardRow row = new KeyboardRow(mResources, mParams, parser, mCurrentY); startRow(row); for (int c = 0; c < numColumns; c++) { final int i = index + c; if (i >= counts) { break; } final String label; final int code; final String outputText; final int supportedMinSdkVersion; if (codesArrayId != 0) { final String codeArraySpec = array[i]; label = CodesArrayParser.parseLabel(codeArraySpec); code = CodesArrayParser.parseCode(codeArraySpec); outputText = CodesArrayParser.parseOutputText(codeArraySpec); supportedMinSdkVersion = CodesArrayParser.getMinSupportSdkVersion(codeArraySpec); } else { final String textArraySpec = array[i]; // TODO: Utilize KeySpecParser or write more generic TextsArrayParser. label = textArraySpec; code = Constants.CODE_OUTPUT_TEXT; outputText = textArraySpec + (char) Constants.CODE_SPACE; supportedMinSdkVersion = 0; } if (Build.VERSION.SDK_INT < supportedMinSdkVersion) { continue; } final int x = (int) row.getKeyX(null); final int y = row.getKeyY(); final Key key = new Key( mParams, label, null /* hintLabel */, 0 /* iconId */, code, outputText, x, y, (int) keyWidth, (int) row.getRowHeight(), row.getDefaultKeyLabelFlags(), row.getDefaultBackgroundType()); endKey(key); row.advanceXPos(keyWidth); } endRow(row); } XmlParseUtils.checkEndTag(TAG_GRID_ROWS, parser); }
private void parseKeyboardAttributes(final XmlPullParser parser) { final AttributeSet attr = Xml.asAttributeSet(parser); final TypedArray keyboardAttr = mContext.obtainStyledAttributes( attr, R.styleable.Keyboard, R.attr.keyboardStyle, R.style.Keyboard); final TypedArray keyAttr = mResources.obtainAttributes(attr, R.styleable.Keyboard_Key); try { final KeyboardParams params = mParams; final int height = params.mId.mHeight; final int width = params.mId.mWidth; params.mOccupiedHeight = height; params.mOccupiedWidth = width; params.mTopPadding = (int) keyboardAttr.getFraction(R.styleable.Keyboard_keyboardTopPadding, height, height, 0); params.mBottomPadding = (int) keyboardAttr.getFraction( R.styleable.Keyboard_keyboardBottomPadding, height, height, 0); params.mLeftPadding = (int) keyboardAttr.getFraction(R.styleable.Keyboard_keyboardLeftPadding, width, width, 0); params.mRightPadding = (int) keyboardAttr.getFraction(R.styleable.Keyboard_keyboardRightPadding, width, width, 0); final int baseWidth = params.mOccupiedWidth - params.mLeftPadding - params.mRightPadding; params.mBaseWidth = baseWidth; params.mDefaultKeyWidth = (int) keyAttr.getFraction( R.styleable.Keyboard_Key_keyWidth, baseWidth, baseWidth, baseWidth / DEFAULT_KEYBOARD_COLUMNS); params.mHorizontalGap = (int) keyboardAttr.getFraction(R.styleable.Keyboard_horizontalGap, baseWidth, baseWidth, 0); // TODO: Fix keyboard geometry calculation clearer. Historically vertical gap between // rows are determined based on the entire keyboard height including top and bottom // paddings. params.mVerticalGap = (int) keyboardAttr.getFraction(R.styleable.Keyboard_verticalGap, height, height, 0); final int baseHeight = params.mOccupiedHeight - params.mTopPadding - params.mBottomPadding + params.mVerticalGap; params.mBaseHeight = baseHeight; params.mDefaultRowHeight = (int) ResourceUtils.getDimensionOrFraction( keyboardAttr, R.styleable.Keyboard_rowHeight, baseHeight, baseHeight / DEFAULT_KEYBOARD_ROWS); params.mKeyVisualAttributes = KeyVisualAttributes.newInstance(keyAttr); params.mMoreKeysTemplate = keyboardAttr.getResourceId(R.styleable.Keyboard_moreKeysTemplate, 0); params.mMaxMoreKeysKeyboardColumn = keyAttr.getInt(R.styleable.Keyboard_Key_maxMoreKeysColumn, 5); params.mThemeId = keyboardAttr.getInt(R.styleable.Keyboard_themeId, 0); params.mIconsSet.loadIcons(keyboardAttr); final String language = params.mId.mLocale.getLanguage(); params.mCodesSet.setLanguage(language); params.mTextsSet.setLanguage(language); final RunInLocale<Void> job = new RunInLocale<Void>() { @Override protected Void job(final Resources res) { params.mTextsSet.loadStringResources(mContext); return null; } }; // Null means the current system locale. final Locale locale = SubtypeLocaleUtils.isNoLanguage(params.mId.mSubtype) ? null : params.mId.mLocale; job.runInLocale(mResources, locale); final int resourceId = keyboardAttr.getResourceId(R.styleable.Keyboard_touchPositionCorrectionData, 0); if (resourceId != 0) { final String[] data = mResources.getStringArray(resourceId); params.mTouchPositionCorrection.load(data); } } finally { keyAttr.recycle(); keyboardAttr.recycle(); } }