/*
* Copyright (C) 2006 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 android.annotation.NonNull;
import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.content.res.Resources.Theme;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.Insets;
import android.graphics.NinePatch;
import android.graphics.Outline;
import android.graphics.PixelFormat;
import android.graphics.PorterDuff;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffColorFilter;
import android.graphics.Rect;
import android.graphics.Region;
import android.graphics.Xfermode;
import android.os.Trace;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.StateSet;
import android.util.TypedValue;
import android.util.Xml;
import android.view.View;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.WeakReference;
import java.util.Arrays;
import java.util.Collection;
/**
* A Drawable is a general abstraction for "something that can be drawn." Most
* often you will deal with Drawable as the type of resource retrieved for
* drawing things to the screen; the Drawable class provides a generic API for
* dealing with an underlying visual resource that may take a variety of forms.
* Unlike a {@link android.view.View}, a Drawable does not have any facility to
* receive events or otherwise interact with the user.
* Drawable是一个常见的抽象类,意味着可以被绘制的东西。你处理Drawable的大多数情况是把它当
* 做绘制在屏幕上的一种资源。Drawable通过了一些API用于处理不同类型的视觉资源,而不像View。
* Drawable没有任何的接收事件或者和用户交互的特性。
* <p>In addition to simple drawing, Drawable provides a number of generic
* mechanisms for its client to interact with what is being drawn:
* 除了简单的绘制,Drawable通过了一系列机制为客户端和被绘制的对象进行交互。
* <ul>
* <li> The {@link #setBounds} method <var>must</var> be called to tell the
* Drawable where it is drawn and how large it should be. All Drawables
* should respect the requested size, often simply by scaling their
* imagery. A client can find the preferred size for some Drawables with
* the {@link #getIntrinsicHeight} and {@link #getIntrinsicWidth} methods.
*
* <li> The {@link #getPadding} method can return from some Drawables
* information about how to frame content that is placed inside of them.
* For example, a Drawable that is intended to be the frame for a button
* widget would need to return padding that correctly places the label
* inside of itself.
*
* <li> The {@link #setState} method allows the client to tell the Drawable
* in which state it is to be drawn, such as "focused", "selected", etc.
* Some drawables may modify their imagery based on the selected state.
*
* <li> The {@link #setLevel} method allows the client to supply a single
* continuous controller that can modify the Drawable is displayed, such as
* a battery level or progress level. Some drawables may modify their
* imagery based on the current level.
*
* <li> A Drawable can perform animations by calling back to its client
* through the {@link Callback} interface. All clients should support this
* interface (via {@link #setCallback}) so that animations will work. A
* simple way to do this is through the system facilities such as
* {@link android.view.View#setBackground(Drawable)} and
* {@link android.widget.ImageView}.
* </ul>
*
* Though usually not visible to the application, Drawables may take a variety
* of forms:
*
* <ul>
* <li> <b>Bitmap</b>: the simplest Drawable, a PNG or JPEG image.
* <li> <b>Nine Patch</b>: an extension to the PNG format allows it to
* specify information about how to stretch it and place things inside of
* it.
* <li> <b>Shape</b>: contains simple drawing commands instead of a raw
* bitmap, allowing it to resize better in some cases.
* <li> <b>Layers</b>: a compound drawable, which draws multiple underlying
* drawables on top of each other.
* <li> <b>States</b>: a compound drawable that selects one of a set of
* drawables based on its state.
* <li> <b>Levels</b>: a compound drawable that selects one of a set of
* drawables based on its level.
* <li> <b>Scale</b>: a compound drawable with a single child drawable,
* whose overall size is modified based on the current level.
* </ul>
*
* <div class="special reference">
* <h3>Developer Guides</h3>
* <p>For more information about how to use drawables, read the
* <a href="{@docRoot}guide/topics/graphics/2d-graphics.html">Canvas and Drawables</a> developer
* guide. For information and examples of creating drawable resources (XML or bitmap files that
* can be loaded in code), read the
* <a href="{@docRoot}guide/topics/resources/drawable-resource.html">Drawable Resources</a>
* document.</p></div>
*/
public abstract class Drawable {
private static final Rect ZERO_BOUNDS_RECT = new Rect();
static final PorterDuff.Mode DEFAULT_TINT_MODE = PorterDuff.Mode.SRC_IN;
private int[] mStateSet = StateSet.WILD_CARD;
private int mLevel = 0;
private int mChangingConfigurations = 0;
private Rect mBounds = ZERO_BOUNDS_RECT; // lazily becomes a new Rect()
private WeakReference<Callback> mCallback = null;
private boolean mVisible = true;
private int mLayoutDirection;
/**
* Draw in its bounds (set via setBounds) respecting optional effects such
* as alpha (set via setAlpha) and color filter (set via setColorFilter).
* 在它的边界内绘制一些相关可选的效果,例如透明度,颜色过滤
* @param canvas The canvas to draw into
*/
public abstract void draw(Canvas canvas);
/**
* Specify a bounding rectangle for the Drawable. This is where the drawable
* will draw when its draw() method is called.
* 为Drawable设置一个边界矩形。当draw()方法被调用,这个矩形是drawable会被绘制到的地方。
*/
public void setBounds(int left, int top, int right, int bottom) {
Rect oldBounds = mBounds;
if (oldBounds == ZERO_BOUNDS_RECT) {
oldBounds = mBounds = new Rect();
}
if (oldBounds.left != left || oldBounds.top != top ||
oldBounds.right != right || oldBounds.bottom != bottom) {
if (!oldBounds.isEmpty()) {
// first invalidate the previous bounds
invalidateSelf();
}
mBounds.set(left, top, right, bottom);
onBoundsChange(mBounds);
}
}
/**
* Specify a bounding rectangle for the Drawable. This is where the drawable
* will draw when its draw() method is called.
* 为Drawable设置一个边界矩形。当draw()方法被调用,这个矩形是drawable会被绘制到的地方。
*/
public void setBounds(Rect bounds) {
setBounds(bounds.left, bounds.top, bounds.right, bounds.bottom);
}
/**
* Return a copy of the drawable's bounds in the specified Rect (allocated
* by the caller). The bounds specify where this will draw when its draw()
* method is called.
* 返回Drawable的bounds的复制
* @param bounds Rect to receive the drawable's bounds (allocated by the
* caller).
*/
public final void copyBounds(Rect bounds) {
bounds.set(mBounds);
}
/**
* Return a copy of the drawable's bounds in a new Rect. This returns the
* same values as getBounds(), but the returned object is guaranteed to not
* be changed later by the drawable (i.e. it retains no reference to this
* rect). If the caller already has a Rect allocated, call copyBounds(rect).
* 返回Drawable的bounds的复制。这个和getBounds()返回一样的值,不过返回的是拷贝,保证
* 这个对象不会被drawabel修改.
* @return A copy of the drawable's bounds
*/
public final Rect copyBounds() {
return new Rect(mBounds);
}
/**
* Return the drawable's bounds Rect. Note: for efficiency, the returned
* object may be the same object stored in the drawable (though this is not
* guaranteed), so if a persistent copy of the bounds is needed, call
* copyBounds(rect) instead.
* You should also not change the object returned by this method as it may
* be the same object stored in the drawable.
* 返回drawable的边界矩形。你不应该修改返回的对象,因为它可能和drawable里面的是同一个
* 引用。
* @return The bounds of the drawable (which may change later, so caller
* beware). DO NOT ALTER the returned object as it may change the
* stored bounds of this drawable.
*
* @see #copyBounds()
* @see #copyBounds(android.graphics.Rect)
*/
public final Rect getBounds() {
if (mBounds == ZERO_BOUNDS_RECT) {
mBounds = new Rect();
}
return mBounds;
}
/**
* Return the drawable's dirty bounds Rect. Note: for efficiency, the
* returned object may be the same object stored in the drawable (though
* this is not guaranteed).
* 获取脏的边界矩形。
* <p>
* By default, this returns the full drawable bounds. Custom drawables may
* override this method to perform more precise invalidation.
* 默认返回整个矩形。常见的drawable可能会重载这个方法来实现更精确的失效。
* @return The dirty bounds of this drawable
*/
public Rect getDirtyBounds() {
return getBounds();
}
/**
* Set a mask of the configuration parameters for which this drawable
* may change, requiring that it be re-created.
*
* @param configs A mask of the changing configuration parameters, as
* defined by {@link android.content.pm.ActivityInfo}.
*
* @see android.content.pm.ActivityInfo
*/
public void setChangingConfigurations(int configs) {
mChangingConfigurations = configs;
}
/**
* Return a mask of the configuration parameters for which this drawable
* may change, requiring that it be re-created. The default implementation
* returns whatever was provided through
Android - Drawable 源码学习
最新推荐文章于 2022-12-06 15:34:00 发布