18b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen/* 28b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen * Copyright (C) 2015 The Android Open Source Project 38b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen * 48b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen * Licensed under the Apache License, Version 2.0 (the "License"); 58b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen * you may not use this file except in compliance with the License. 68b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen * You may obtain a copy of the License at 78b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen * 88b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen * http://www.apache.org/licenses/LICENSE-2.0 98b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen * 108b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen * Unless required by applicable law or agreed to in writing, software 118b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen * distributed under the License is distributed on an "AS IS" BASIS, 128b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 138b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen * See the License for the specific language governing permissions and 148b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen * limitations under the License. 158b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen */ 168b7af7188228ca88838e31e070f0fca0d1f90581Yao Chenpackage android.support.car.ui; 178b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen 188b7af7188228ca88838e31e070f0fca0d1f90581Yao Chenimport android.content.res.Resources; 198b7af7188228ca88838e31e070f0fca0d1f90581Yao Chenimport android.graphics.Bitmap; 208b7af7188228ca88838e31e070f0fca0d1f90581Yao Chenimport android.graphics.Canvas; 218b7af7188228ca88838e31e070f0fca0d1f90581Yao Chenimport android.graphics.ColorFilter; 228b7af7188228ca88838e31e070f0fca0d1f90581Yao Chenimport android.graphics.PixelFormat; 238b7af7188228ca88838e31e070f0fca0d1f90581Yao Chenimport android.graphics.Rect; 248b7af7188228ca88838e31e070f0fca0d1f90581Yao Chenimport android.graphics.drawable.Drawable; 258b7af7188228ca88838e31e070f0fca0d1f90581Yao Chenimport android.support.annotation.NonNull; 268b7af7188228ca88838e31e070f0fca0d1f90581Yao Chenimport android.support.v4.graphics.drawable.RoundedBitmapDrawable; 278b7af7188228ca88838e31e070f0fca0d1f90581Yao Chenimport android.support.v4.graphics.drawable.RoundedBitmapDrawableFactory; 288b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen 298b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen 308b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen/** 318b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen * A drawable for displaying a circular bitmap. This is a wrapper over RoundedBitmapDrawable, 328b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen * since that implementation doesn't behave quite as desired. 338b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen * 348b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen * Note that not all drawable functionality is passed to the RoundedBitmapDrawable at this 358b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen * time. Feel free to add more as necessary. 3657de61296cc8f29d8740fc7e6983af9553e7a410Jason Tholstrup * @hide 378b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen */ 388b7af7188228ca88838e31e070f0fca0d1f90581Yao Chenpublic class CircleBitmapDrawable extends Drawable { 398b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen private final Resources mResources; 408b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen 418b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen private Bitmap mBitmap; 428b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen private RoundedBitmapDrawable mDrawable; 438b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen private int mAlpha = -1; 448b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen private ColorFilter mCf = null; 458b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen 468b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen public CircleBitmapDrawable(@NonNull Resources res, @NonNull Bitmap bitmap) { 478b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen mBitmap = bitmap; 488b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen mResources = res; 498b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen } 508b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen 518b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen @Override 528b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen public void onBoundsChange(Rect bounds) { 538b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen super.onBoundsChange(bounds); 548b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen int width = bounds.right - bounds.left; 558b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen int height = bounds.bottom - bounds.top; 568b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen 578b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen Bitmap processed = mBitmap; 588b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen /* if (processed.getWidth() != width || processed.getHeight() != height) { 598b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen processed = BitmapUtils.scaleBitmap(processed, width, height); 608b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen } 618b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen // RoundedBitmapDrawable is actually just a rounded rectangle. So it can't turn 628b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen // rectangular images into circles. 638b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen if (processed.getWidth() != processed.getHeight()) { 648b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen int diam = Math.min(width, height); 658b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen Bitmap cropped = BitmapUtils.cropBitmap(processed, diam, diam); 668b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen if (processed != mBitmap) { 678b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen processed.recycle(); 688b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen } 698b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen processed = cropped; 708b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen }*/ 718b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen mDrawable = RoundedBitmapDrawableFactory.create(mResources, processed); 728b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen mDrawable.setBounds(bounds); 738b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen mDrawable.setAntiAlias(true); 748b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen mDrawable.setCornerRadius(Math.min(width, height) / 2f); 758b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen if (mAlpha != -1) { 768b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen mDrawable.setAlpha(mAlpha); 778b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen } 788b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen if (mCf != null) { 798b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen mDrawable.setColorFilter(mCf); 808b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen } 818b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen invalidateSelf(); 828b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen } 838b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen 848b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen @Override 858b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen public void draw(Canvas canvas) { 868b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen if (mDrawable != null) { 878b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen mDrawable.draw(canvas); 888b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen } 898b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen } 908b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen 918b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen @Override 928b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen public int getOpacity() { 938b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen return mDrawable != null ? mDrawable.getOpacity() : PixelFormat.TRANSLUCENT; 948b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen } 958b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen 968b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen @Override 978b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen public void setAlpha(int alpha) { 988b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen mAlpha = alpha; 998b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen if (mDrawable != null) { 1008b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen mDrawable.setAlpha(alpha); 1018b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen invalidateSelf(); 1028b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen } 1038b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen } 1048b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen 1058b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen @Override 1068b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen public void setColorFilter(ColorFilter cf) { 1078b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen mCf = cf; 1088b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen if (mDrawable != null) { 1098b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen mDrawable.setColorFilter(cf); 1108b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen invalidateSelf(); 1118b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen } 1128b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen } 1138b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen 1148b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen /** 1158b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen * Convert the drawable to a bitmap. 1168b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen * @param size The target size of the bitmap in pixels. 1178b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen * @return A bitmap representation of the drawable. 1188b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen */ 1198b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen public Bitmap toBitmap(int size) { 1208b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen Bitmap largeIcon = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888); 1218b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen Canvas canvas = new Canvas(largeIcon); 1228b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen Rect bounds = getBounds(); 1238b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen setBounds(0, 0, canvas.getWidth(), canvas.getHeight()); 1248b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen draw(canvas); 1258b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen setBounds(bounds); 1268b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen return largeIcon; 1278b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen } 1288b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen} 1298b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen 130