| /* |
| * Copyright (C) 2015 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package android.graphics.drawable; |
| |
| import com.android.tools.layoutlib.annotations.LayoutlibDelegate; |
| |
| import android.graphics.Path; |
| import android.graphics.drawable.GradientDrawable.GradientState; |
| |
| import java.lang.reflect.Field; |
| |
| /** |
| * Delegate implementing the native methods of {@link GradientDrawable} |
| * |
| * Through the layoutlib_create tool, the original native methods of GradientDrawable have been |
| * replaced by calls to methods of the same name in this delegate class. |
| */ |
| public class GradientDrawable_Delegate { |
| |
| /** |
| * The ring can be built either by drawing full circles, or by drawing arcs in case the |
| * circle isn't complete. LayoutLib cannot handle drawing full circles (requires path |
| * subtraction). So, if we need to draw full circles, we switch to drawing 99% circle. |
| */ |
| @LayoutlibDelegate |
| /*package*/ static Path buildRing(GradientDrawable thisDrawable, GradientState st) { |
| boolean useLevel = st.mUseLevelForShape; |
| int level = thisDrawable.getLevel(); |
| // 10000 is the max level. See android.graphics.drawable.Drawable#getLevel() |
| float sweep = useLevel ? (360.0f * level / 10000.0f) : 360f; |
| Field mLevel = null; |
| if (sweep >= 360 || sweep <= -360) { |
| st.mUseLevelForShape = true; |
| // Use reflection to set the value of the field to prevent setting the drawable to |
| // dirty again. |
| try { |
| mLevel = Drawable.class.getDeclaredField("mLevel"); |
| mLevel.setAccessible(true); |
| mLevel.setInt(thisDrawable, 9999); // set to one less than max. |
| } catch (NoSuchFieldException e) { |
| // The field has been removed in a recent framework change. Fall back to old |
| // buggy behaviour. |
| } catch (IllegalAccessException e) { |
| // We've already set the field to be accessible. |
| assert false; |
| } |
| } |
| Path path = thisDrawable.buildRing_Original(st); |
| st.mUseLevelForShape = useLevel; |
| if (mLevel != null) { |
| try { |
| mLevel.setInt(thisDrawable, level); |
| } catch (IllegalAccessException e) { |
| assert false; |
| } |
| } |
| return path; |
| } |
| } |