Android Drawable 소개

원문의 출처:http://www.ccbu.cc/android/android-drawable
Android 시스템 에 서 는 그리 기 대상 을 Drawable 로 추상 화하 고, 그리 기 자원 에 따라 Drawable 형식 이 달라 집 니 다.Android FrameWork 는 자주 사용 하 는 Drawable 을 제공 합 니 다. Android 컨트롤 의 그리 기 자원 은 기본적으로 Drawable 형식 으로 이 루어 집 니 다.일반적인 상황 에서 개발 자 는 Drawable 의 구체 적 인 실현 을 직접 접 하지 않 습 니 다. Drawable 자원 은 보통 res / drawable 디 렉 터 리 에 놓 여 있 고 사용 자 는 그림, xml 형식의 Drawable 자원 을 통 해 사용 합 니 다.Android 에 내 장 된 비교적 자주 사용 되 는 Drawable 유형 은 ColorDrawable, GradientDrawable, ShapeDrawable, BitmapDrawable, NinePatchDrawable, InsetDrawable, ClipDrawable, Scale Drawable, RotateDrawable, Animation Drawable, LayerDrawable, LevelListDrawable, StateList Drawable, Transition Drawable 을 포함한다.일반적인 상황 에서 이미지 자원 을 제외 하고 res / drawable 에 직접 놓 습 니 다 (android studio 에서 그림 을 res / minmap 에 놓 습 니 다). 다른 Drawable 은 xml 형식 으로 이 루어 집 니 다. 개발 자 는 xml 에서 shape, selector, level - list 등 탭 을 사용 하여 해당 하 는 Drawable 을 실현 하여 해당 하 는 그리 기 가능 한 자원 의 정 의 를 실현 합 니 다.최종 view 는 이 Drawable 을 그 려 서 우리 가 원 하 는 디 스 플레이 효 과 를 실현 합 니 다.
Drawable 에서 xml 태그 와 Drawable 대상 의 대응 관 계 는 다음 표 와 같 습 니 다.
xml 태그
드 로 어 블 개체
StateListDrawable
LevelListDrawable
LayerDrawable
TransitionDrawable
ColorDrawable
GradientDrawable
ScaleDrawable
ScaleDrawable
ClipDrawable
RotateDrawable
AnimationDrawable
InsetDrawable
BitmapDrawable
NinePatchDrawable
다음은 Framework 의 소스 코드 를 통 해 Drawable 의 로드 과정 을 탐색 합 니 다. 일반적인 상황 에서 저 희 는 getResources (). getDrawable (int id) 을 통 해불 러 오 는 방식 입 니 다.이 선 을 따라 내 려 다 보면 getDrawable - > loadDrawable - > loadDrawable ForCookie - > Drawable. createFromXml - > createFromXmlInner, android \ graphics \ \ drawable \ \ Drawable. java 의 createFromXmlInner 함수 구현 코드 를 볼 수 있 습 니 다.
public static Drawable createFromXmlInner(Resources r, XmlPullParser parser, AttributeSet attrs,
            Theme theme) throws XmlPullParserException, IOException {
        final Drawable drawable;

        final String name = parser.getName();
        if (name.equals("selector")) {
            drawable = new StateListDrawable();
        } else if (name.equals("animated-selector")) {
            drawable = new AnimatedStateListDrawable();
        } else if (name.equals("level-list")) {
            drawable = new LevelListDrawable();
        } else if (name.equals("layer-list")) {
            drawable = new LayerDrawable();
        } else if (name.equals("transition")) {
            drawable = new TransitionDrawable();
        } else if (name.equals("ripple")) {
            drawable = new RippleDrawable();
        } else if (name.equals("color")) {
            drawable = new ColorDrawable();
        } else if (name.equals("shape")) {
            drawable = new GradientDrawable();
        } else if (name.equals("vector")) {
            drawable = new VectorDrawable();
        } else if (name.equals("animated-vector")) {
            drawable = new AnimatedVectorDrawable();
        } else if (name.equals("scale")) {
            drawable = new ScaleDrawable();
        } else if (name.equals("clip")) {
            drawable = new ClipDrawable();
        } else if (name.equals("rotate")) {
            drawable = new RotateDrawable();
        } else if (name.equals("animated-rotate")) {
            drawable = new AnimatedRotateDrawable();
        } else if (name.equals("animation-list")) {
            drawable = new AnimationDrawable();
        } else if (name.equals("inset")) {
            drawable = new InsetDrawable();
        } else if (name.equals("bitmap")) {
            //noinspection deprecation
            drawable = new BitmapDrawable(r);
            if (r != null) {
               ((BitmapDrawable) drawable).setTargetDensity(r.getDisplayMetrics());
            }
        } else if (name.equals("nine-patch")) {
            drawable = new NinePatchDrawable();
            if (r != null) {
                ((NinePatchDrawable) drawable).setTargetDensity(r.getDisplayMetrics());
             }
        } else {
            throw new XmlPullParserException(parser.getPositionDescription() +
                    ": invalid drawable tag " + name);
        }

        drawable.inflate(r, parser, attrs, theme);
        return drawable;
    }

상부 의 대응 관 계 는 여기에서 왔 는데, 지금 은 단번에 밝 아 지지 않 았 습 니까?함수 끝 에 Drawable 은 바 를 통 해 inflate 함수 로 AttributeSet 의 속성 정 보 를 분석 하고 Drawable 에 해당 하 는 속성 을 설정 합 니 다.비트 맵 드 라 와 블 한번 볼 까요?
public void inflate(Resources r, XmlPullParser parser, AttributeSet attrs, Theme theme)
            throws XmlPullParserException, IOException {
        super.inflate(r, parser, attrs, theme);

        final TypedArray a = obtainAttributes(r, theme, attrs, R.styleable.BitmapDrawable);
        updateStateFromTypedArray(a);
        verifyState(a);
        a.recycle();
    }

updateStateFromTypedArray 계속 보기
private void updateStateFromTypedArray(TypedArray a) throws XmlPullParserException {
        final Resources r = a.getResources();
        final BitmapState state = mBitmapState;

        // Account for any configuration changes.
        state.mChangingConfigurations |= a.getChangingConfigurations();

        // Extract the theme attributes, if any.
        state.mThemeAttrs = a.extractThemeAttrs();

        final int srcResId = a.getResourceId(R.styleable.BitmapDrawable_src, 0);
        if (srcResId != 0) {
            final Bitmap bitmap = BitmapFactory.decodeResource(r, srcResId);
            if (bitmap == null) {
                throw new XmlPullParserException(a.getPositionDescription() +
                        ":  requires a valid src attribute");
            }

            state.mBitmap = bitmap;
        }

        state.mTargetDensity = r.getDisplayMetrics().densityDpi;

        final boolean defMipMap = state.mBitmap != null ? state.mBitmap.hasMipMap() : false;
        setMipMap(a.getBoolean(R.styleable.BitmapDrawable_mipMap, defMipMap));

        state.mAutoMirrored = a.getBoolean(
                R.styleable.BitmapDrawable_autoMirrored, state.mAutoMirrored);
        state.mBaseAlpha = a.getFloat(R.styleable.BitmapDrawable_alpha, state.mBaseAlpha);

        final int tintMode = a.getInt(R.styleable.BitmapDrawable_tintMode, -1);
        if (tintMode != -1) {
            state.mTintMode = Drawable.parseTintMode(tintMode, Mode.SRC_IN);
        }

        final ColorStateList tint = a.getColorStateList(R.styleable.BitmapDrawable_tint);
        if (tint != null) {
            state.mTint = tint;
        }

        final Paint paint = mBitmapState.mPaint;
        paint.setAntiAlias(a.getBoolean(
                R.styleable.BitmapDrawable_antialias, paint.isAntiAlias()));
        paint.setFilterBitmap(a.getBoolean(
                R.styleable.BitmapDrawable_filter, paint.isFilterBitmap()));
        paint.setDither(a.getBoolean(R.styleable.BitmapDrawable_dither, paint.isDither()));

        setGravity(a.getInt(R.styleable.BitmapDrawable_gravity, state.mGravity));

        final int tileMode = a.getInt(R.styleable.BitmapDrawable_tileMode, TILE_MODE_UNDEFINED);
        if (tileMode != TILE_MODE_UNDEFINED) {
            final Shader.TileMode mode = parseTileMode(tileMode);
            setTileModeXY(mode, mode);
        }

        final int tileModeX = a.getInt(R.styleable.BitmapDrawable_tileModeX, TILE_MODE_UNDEFINED);
        if (tileModeX != TILE_MODE_UNDEFINED) {
            setTileModeX(parseTileMode(tileModeX));
        }

        final int tileModeY = a.getInt(R.styleable.BitmapDrawable_tileModeY, TILE_MODE_UNDEFINED);
        if (tileModeY != TILE_MODE_UNDEFINED) {
            setTileModeY(parseTileMode(tileModeY));
        }

        // Update local properties.
        initializeWithState(state, r);
    }

updateStateFromTypedArray 함수 에서 BitmapDrawable 이 src 속성 을 가 져 온 후 BitmapFactory 를 통 해 이미지 파일 을 불 러 오고 사용자 설정 의 속성 을 읽 으 며 BitmapDrawable 의 다른 속성 을 설정 합 니 다.다른 Drawable 의 실현 방식 은 유사 합 니 다.

좋은 웹페이지 즐겨찾기