RecipientsEditor-信息收件人输入框

首先说一下信息收件人这个类的继承关系

RecipientsEditor->EncapsulatedMTKRecipientEditTextView(这两个类都在mms目录下)

->MTKRecipientEditTextView(mediatek/frameworks-ext/ex/chips/src/com/android/ex/chips/)

->MultiAutoCompleteTextView->AutoCompleteTextView->EditText(frameworks/base/core/java/android/widget)

然后我们想要修改这个输入框的样式,包括里面的文字颜色、背景等。这个我们可以在MTKRecipientEditTextView 中进行设定,关键代码如下

 private Bitmap createUnselectedChip(RecipientEntry contact, TextPaint paint,
            boolean leaveBlankIconSpacer) {
        // Ellipsize the text so that it takes AT MOST the entire width of the
        // autocomplete text entry area. Make sure to leave space for padding
        // on the sides.
        int height = (int) mChipHeight;
        int iconWidth = height;
        float[] widths = new float[1];
        paint.getTextWidths(" ", widths);
        /// M: Limit ellipsizedText in some case (ex. moreChip)
        CharSequence ellipsizedText = ellipsizeText(createChipDisplayText(contact), paint,
                (mLimitedWidthForSpan == -1) ? (calculateAvailableWidth() - iconWidth - widths[0]) : (mLimitedWidthForSpan - iconWidth - widths[0]));
        printDebugLog(TAG,"[createUnselectedChip] start, " + ellipsizedText + ", ID: " + contact.getContactId());
        // Make sure there is a minimum chip width so the user can ALWAYS
        // tap a chip without difficulty.
        
        /// M: Only leave space if icon exists. @{
        boolean hasIcon = false;
        int ellipsizedTextWidth = (int) Math.floor(paint.measureText(ellipsizedText, 0, ellipsizedText.length()));
        int width = ellipsizedTextWidth + (mChipPadding * 2);
        /// @}

        // Create the background of the chip.
        Bitmap tmpBitmap = null;
        Drawable background = getChipBackground(contact);
        if (background != null) {
            Canvas canvas = null; /// M: Only leave space if icon exists        
            Bitmap photo = null;
            Matrix matrix = null;

            // Don't draw photos for recipients that have been typed in OR generated on the fly.
            long contactId = contact.getContactId();
            boolean drawPhotos = isPhoneQuery() ?
                    contactId != RecipientEntry.INVALID_CONTACT
                    : (contactId != RecipientEntry.INVALID_CONTACT
                            && (contactId != RecipientEntry.GENERATED_CONTACT &&
                                    !TextUtils.isEmpty(contact.getDisplayName())));
if (drawPhotos) {
                byte[] photoBytes = contact.getPhotoBytes();
                // There may not be a photo yet if anything but the first contact address
                // was selected.
                Trace.traceBegin(Trace.TRACE_TAG_VIEW, "getPhoto " + contact.getContactId());
                if (photoBytes == null && contact.getPhotoThumbnailUri() != null) {
                    // TODO: cache this in the recipient entry?
                    ((BaseRecipientAdapter) getAdapter()).fetchPhoto(contact, contact
                            .getPhotoThumbnailUri());
                    photoBytes = contact.getPhotoBytes();
                }
                Trace.traceEnd(Trace.TRACE_TAG_VIEW);
                Trace.traceBegin(Trace.TRACE_TAG_VIEW, "decodePhoto");
                 if (photoBytes != null) {
/* Vanzo:zhangshuli on: Thu, 12 Mar 2015 11:48:23 +0000
                    photo = BitmapFactory.decodeByteArray(photoBytes, 0, photoBytes.length);
 */
// End of Vanzo: zhangshuli
                } else {
                    // TODO: can the scaled down default photo be cached?
/* Vanzo:zhangshuli on: Thu, 12 Mar 2015 11:48:28 +0000
                    photo = mDefaultContactPhoto;
 */
// End of Vanzo: zhangshuli
                }
                 Trace.traceEnd(Trace.TRACE_TAG_VIEW);
                // Draw the photo on the left side.
                if (photo != null) {
                    /// M: Only leave space if icon exists. @{
                    hasIcon = true;
                    width = ellipsizedTextWidth + (mChipPadding * 2) + iconWidth; 
                    /// @}
                    RectF src = new RectF(0, 0, photo.getWidth(), photo.getHeight());
                    Rect backgroundPadding = new Rect();
                    mChipBackground.getPadding(backgroundPadding);
                    RectF dst = new RectF(width - iconWidth + backgroundPadding.left,
                            0 + backgroundPadding.top,
                            width - backgroundPadding.right,
                            height - backgroundPadding.bottom);
                    matrix = new Matrix();
                    matrix.setRectToRect(src, dst, Matrix.ScaleToFit.FILL);
}
            } else if (!leaveBlankIconSpacer || isPhoneQuery()) {
                iconWidth = 0;
            }

            tmpBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
            canvas = new Canvas(tmpBitmap);

            background.setBounds(0, 0, width, height);
            background.draw(canvas);
            if (photo != null && matrix != null) {
                canvas.drawBitmap(photo, matrix, paint);
            }
            
/* Vanzo:shangxiaopeng on: Wed, 28 May 2014 11:03:56 +0800
 * modify settings fun
            paint.setColor(getContext().getResources().getColor(android.R.color.black));
 */
            paint.setColor(getContext().getResources().getColor(android.R.color.white));
// End of Vanzo: shangxiaopeng
            // Vertically center the text in the chip.
            int xPositionOfText = hasIcon ? mChipPadding : (mChipPadding + (width - mChipPadding*2 - ellipsizedTextWidth)/2); /// M: Horizontally center the text in the chip
            canvas.drawText(ellipsizedText, 0, ellipsizedText.length(), xPositionOfText,
                    getTextYOffset((String)ellipsizedText, paint, height), paint);
        } else {
            Log.w(TAG, "Unable to draw a background for the chips as it was never set");
        }

        if (tmpBitmap == null) {
            tmpBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
        }
        printDebugLog(TAG,"[createUnselectedChip] end");
        return tmpBitmap;
    }

但是,如果我们想要更改下拉框的布局,你会发现,无论你怎么在mediatek下修改都是没有效果的。后来发现要在它的父类中进行修改 AutoCompleteTextView

代码如下

 public void showDropDown() {
        buildImeCompletions();

        if (mPopup.getAnchorView() == null) {
            if (mDropDownAnchorId != View.NO_ID) {
                mPopup.setAnchorView(getRootView().findViewById(mDropDownAnchorId));
            } else {
                mPopup.setAnchorView(this);
            }    
        }    
        if (!isPopupShowing()) {
            // Make sure the list does not obscure the IME when shown for the first time.
            mPopup.setInputMethodMode(ListPopupWindow.INPUT_METHOD_NEEDED);
            mPopup.setListItemExpandMax(EXPAND_MAX);
        }    
        mPopup.show();
        mPopup.getListView().setOverScrollMode(View.OVER_SCROLL_ALWAYS);
/* Vanzo:zhangshuli on: Wed, 11 Mar 2015 20:27:52 +0000
 */
        mPopup.getListView().setPadding(0, 0, mPopupMargnRight, 0);
        if (mPopupMargnRight != 0){
            mPopup.getListView().setScrollBarStyle(ScrollView.SCROLLBARS_OUTSIDE_OVERLAY);
        }    
// End of Vanzo: zhangshuli
    }    

这个代码是修改下拉框滚动条样式跟listview中item的边距

这里面用到了关于添加自定义属性的方法,参照另一篇文章

原文地址:https://www.cnblogs.com/zhangshuli-1989/p/zhangshuli_edittext_150312132.html