public class

TintContextWrapper

extends ContextWrapper

 java.lang.Object

↳ContextWrapper

↳androidx.appcompat.widget.TintContextWrapper

Gradle dependencies

compile group: 'androidx.appcompat', name: 'appcompat-resources', version: '1.7.0'

  • groupId: androidx.appcompat
  • artifactId: appcompat-resources
  • version: 1.7.0

Artifact androidx.appcompat:appcompat-resources:1.7.0 it located at Google repository (https://maven.google.com/)

Androidx class mapping:

androidx.appcompat.widget.TintContextWrapper android.support.v7.widget.TintContextWrapper

Overview

A which returns a tint-aware android.content.res.Resources instance from TintContextWrapper.getResources().

Summary

Methods
public AssetManagergetAssets()

public ResourcesgetResources()

public Resources.ThemegetTheme()

public voidsetTheme(int resid)

public static Contextwrap(Context context)

from java.lang.Objectclone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait

Methods

public static Context wrap(Context context)

public Resources.Theme getTheme()

public void setTheme(int resid)

public Resources getResources()

public AssetManager getAssets()

Source

/*
 * 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 androidx.appcompat.widget;

import static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX;

import android.content.Context;
import android.content.ContextWrapper;
import android.content.res.AssetManager;
import android.content.res.Resources;
import android.os.Build;

import androidx.annotation.NonNull;
import androidx.annotation.RestrictTo;

import java.lang.ref.WeakReference;
import java.util.ArrayList;

/**
 * A {@link android.content.ContextWrapper} which returns a tint-aware
 * {@link android.content.res.Resources} instance from {@link #getResources()}.
 *
 */
@RestrictTo(LIBRARY_GROUP_PREFIX)
public class TintContextWrapper extends ContextWrapper {

    private static final Object CACHE_LOCK = new Object();
    private static ArrayList<WeakReference<TintContextWrapper>> sCache;

    public static Context wrap(@NonNull final Context context) {
        if (shouldWrap(context)) {
            synchronized (CACHE_LOCK) {
                if (sCache == null) {
                    sCache = new ArrayList<>();
                } else {
                    // This is a convenient place to prune any dead reference entries
                    for (int i = sCache.size() - 1; i >= 0; i--) {
                        final WeakReference<TintContextWrapper> ref = sCache.get(i);
                        if (ref == null || ref.get() == null) {
                            sCache.remove(i);
                        }
                    }
                    // Now check our instance cache
                    for (int i = sCache.size() - 1; i >= 0; i--) {
                        final WeakReference<TintContextWrapper> ref = sCache.get(i);
                        final TintContextWrapper wrapper = ref != null ? ref.get() : null;
                        if (wrapper != null && wrapper.getBaseContext() == context) {
                            return wrapper;
                        }
                    }
                }
                // If we reach here then the cache didn't have a hit, so create a new instance
                // and add it to the cache
                final TintContextWrapper wrapper = new TintContextWrapper(context);
                sCache.add(new WeakReference<>(wrapper));
                return wrapper;
            }
        }
        return context;
    }

    private static boolean shouldWrap(@NonNull final Context context) {
        if (context instanceof TintContextWrapper
                || context.getResources() instanceof TintResources
                || context.getResources() instanceof VectorEnabledTintResources) {
            // If the Context already has a TintResources[Experimental] impl, no need to wrap again
            // If the Context is already a TintContextWrapper, no need to wrap again
            return false;
        }
        return Build.VERSION.SDK_INT < 21 || VectorEnabledTintResources.shouldBeUsed();
    }

    private final Resources mResources;
    private final Resources.Theme mTheme;

    private TintContextWrapper(@NonNull final Context base) {
        super(base);

        if (VectorEnabledTintResources.shouldBeUsed()) {
            // We need to create a copy of the Theme so that the Theme references our
            // new Resources instance
            mResources = new VectorEnabledTintResources(this, base.getResources());
            mTheme = mResources.newTheme();
            mTheme.setTo(base.getTheme());
        } else {
            mResources = new TintResources(this, base.getResources());
            mTheme = null;
        }
    }

    @Override
    public Resources.Theme getTheme() {
        return mTheme == null ? super.getTheme() : mTheme;
    }

    @Override
    public void setTheme(int resid) {
        if (mTheme == null) {
            super.setTheme(resid);
        } else {
            mTheme.applyStyle(resid, true);
        }
    }

    @Override
    public Resources getResources() {
        return mResources;
    }

    @Override
    public AssetManager getAssets() {
        // Ensure we're returning assets with the correct configuration.
        return mResources.getAssets();
    }
}