先查找到显示联系人的界面Activity为
adb shell "dumpsys window|grep mCurrentFocus
mCurrentFocus=Window{afeec10 u0 com.android.contacts/com.android.contacts.quickcontact.QuickContactActivity}
故可以知道该界面为:QuickContactActivity.java
根据布局可以很快找到对应的PhotoView属性
mPhotoView = (QuickContactImageView) findViewById(R.id.photo);
final View transparentView = findViewById(R.id.transparent_view);
if (mScroller != null) {
transparentView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
mScroller.scrollOffBottom();
}
});
}
进而判断出该图片是在QuickContactImageView.java 中编辑的,该函数比较简短:
public void setTint(int color) {
if (mBitmapDrawable == null || mBitmapDrawable.getBitmap() == null
|| mBitmapDrawable.getBitmap().hasAlpha()) {
setBackgroundColor(color);
} else {
setBackground(null);
}
mTintColor = color;
postInvalidate();
}
public boolean isBasedOffLetterTile() {
return mOriginalDrawable instanceof LetterTileDrawable;
}
public void setIsBusiness(boolean isBusiness) {
mIsBusiness = isBusiness;
}
@Override
public void setImageDrawable(Drawable drawable) {
// There is no way to avoid all this casting. Blending modes aren't equally
// supported for all drawable types.
final BitmapDrawable bitmapDrawable;
if (drawable == null || drawable instanceof BitmapDrawable) {
bitmapDrawable = (BitmapDrawable) drawable;
} else if (drawable instanceof LetterTileDrawable) {
if (!mIsBusiness) {
bitmapDrawable = (BitmapDrawable) getResources().getDrawable(
R.drawable.person_white_540dp);
} else {
bitmapDrawable = (BitmapDrawable) getResources().getDrawable(
R.drawable.generic_business_white_540dp);
}
} else {
throw new IllegalArgumentException("Does not support this type of drawable");
}
mOriginalDrawable = drawable;
mBitmapDrawable = bitmapDrawable;
setTint(mTintColor);
super.setImageDrawable(bitmapDrawable);
}
根据问题描述主要是:Color相关的问题。故我们查找Color相关的函数,细化一些则为:
public void setTint(int color) {
if (mBitmapDrawable == null || mBitmapDrawable.getBitmap() == null
|| mBitmapDrawable.getBitmap().hasAlpha()) {
setBackgroundColor(color);
} else {
setBackground(null);
}
mTintColor = color;
postInvalidate();
}
在仔细观察颜色变化主要是在点击编辑保存后的变化。故我们需要进一步跟踪
adb shell "dumpsys window|grep mCurrentFocus
mCurrentFocus=Window{7362203 u0 com.android.contacts/com.android.contacts.activities.ContactEditorActivity}
找到ContactEditorActivity.java文件中的保存按钮事件,对应可以查看到ContactEditorFragment.java文件
protected boolean doSaveAction(int saveMode, Long joinContactId) {
final Intent intent = ContactSaveService.createSaveContactIntent(mContext, mState,
SAVE_MODE_EXTRA_KEY, saveMode, isEditingUserProfile(),
((Activity) mContext).getClass(),
ContactEditorActivity.ACTION_SAVE_COMPLETED, mUpdatedPhotos,
JOIN_CONTACT_ID_EXTRA_KEY, joinContactId);
return startSaveService(mContext, intent, saveMode);
}
在QuickContactActivity.java文件中,有对于PhotoView 的设置
/**
* Asynchronously extract the most vibrant color from the PhotoView. Once extracted,
* apply this tint to {@link MultiShrinkScroller}. This operation takes about 20-30ms
* on a Nexus 5.
*/
private void extractAndApplyTintFromPhotoViewAsynchronously() {
if (mScroller == null) {
return;
}
final Drawable imageViewDrawable = mPhotoView.getDrawable();
new AsyncTask<Void, Void, MaterialPalette>() {
@Override
protected MaterialPalette doInBackground(Void... params) {
if (imageViewDrawable instanceof BitmapDrawable && mContactData != null
&& mContactData.getThumbnailPhotoBinaryData() != null
&& mContactData.getThumbnailPhotoBinaryData().length > 0) {
// Perform the color analysis on the thumbnail instead of the full sized
// image, so that our results will be as similar as possible to the Bugle
// app.
final Bitmap bitmap = BitmapFactory.decodeByteArray(
mContactData.getThumbnailPhotoBinaryData(), 0,
mContactData.getThumbnailPhotoBinaryData().length);
try {
final int primaryColor = 0;//colorFromBitmap(bitmap);
Log.d(TAG, "doInBackground: primaryColor = " + primaryColor);
if (primaryColor != 0) {
return mMaterialColorMapUtils.calculatePrimaryAndSecondaryColor(
primaryColor);
}
} finally {
bitmap.recycle();
}
}
if (imageViewDrawable instanceof LetterTileDrawable) {
final int primaryColor = ((LetterTileDrawable) imageViewDrawable).getColor();
Log.d(TAG, "LetterTileDrawable doInBackground: primaryColor = " + primaryColor);
return mMaterialColorMapUtils.calculatePrimaryAndSecondaryColor(primaryColor);
}
Log.d(TAG, "doInBackground: MaterialColorMapUtils.getDefaultPrimaryAndSecondaryColors");
return MaterialColorMapUtils.getDefaultPrimaryAndSecondaryColors(getResources());
}
@Override
protected void onPostExecute(MaterialPalette palette) {
super.onPostExecute(palette);
Log.d(TAG, "onPostExecute: mHasComputedThemeColor = " + mHasComputedThemeColor + " , imageViewDrawable = " + imageViewDrawable);
if (mHasComputedThemeColor) {
// If we had previously computed a theme color from the contact photo,
// then do not update the theme color. Changing the theme color several
// seconds after QC has started, as a result of an updated/upgraded photo,
// is a jarring experience. On the other hand, changing the theme color after
// a rotation or onNewIntent() is perfectly fine.
return;
}
// Check that the Photo has not changed. If it has changed, the new tint
// color needs to be extracted
if (imageViewDrawable == mPhotoView.getDrawable()) {
mHasComputedThemeColor = true;
setThemeColor(palette);
}
}
}.execute();
}
private void setThemeColor(MaterialPalette palette) {
// If the color is invalid, use the predefined default
mColorFilterColor = palette.mPrimaryColor;
Log.d(TAG, "setThemeColor: mColorFilterColor = " + mColorFilterColor);
mScroller.setHeaderTintColor(mColorFilterColor);
mStatusBarColor = palette.mSecondaryColor;
updateStatusBarColor();
mColorFilter =
new PorterDuffColorFilter(mColorFilterColor, PorterDuff.Mode.SRC_ATOP);
mContactCard.setColorAndFilter(mColorFilterColor, mColorFilter);
mRecentCard.setColorAndFilter(mColorFilterColor, mColorFilter);
mAboutCard.setColorAndFilter(mColorFilterColor, mColorFilter);
}
抓取log信息知道;当设置图片时候,该函数执行到了mHasComputedThemeColor = true;
跟进一步:
public void setHeaderTintColor(int color) {
mHeaderTintColor = color;
updatePhotoTintAndDropShadow();
if (CompatUtils.isLollipopCompatible()) {
// Use the same amount of alpha on the new tint color as the previous tint color.
final int edgeEffectAlpha = Color.alpha(mEdgeGlowBottom.getColor());
mEdgeGlowBottom.setColor((color & 0xffffff) | Color.argb(edgeEffectAlpha, 0, 0, 0));
mEdgeGlowTop.setColor(mEdgeGlowBottom.getColor());
}
}
继续抓取log查看到对Tint Color或者其他颜色的设置处, MultiShrinkScroller.java
private void updatePhotoTintAndDropShadow() {
// Let's keep an eye on how long this method takes to complete.
Trace.beginSection("updatePhotoTintAndDropShadow");
// Tell the photo view what tint we are trying to achieve. Depending on the type of
// drawable used, the photo view may or may not use this tint.
mPhotoView.setTint(mHeaderTintColor);
if (mIsTwoPanel && !mPhotoView.isBasedOffLetterTile()) {
// When in two panel mode, UX considers photo tinting unnecessary for non letter
// tile photos.
//此处即是表示清除Filter层的函数
**mPhotoView.clearColorFilter();**
mTitleGradientDrawable.setAlpha(0xFF);
mActionBarGradientDrawable.setAlpha(0xFF);
return;
}
此时即可将FIlter的颜色去除。