• ContactDetail 和 ContactEditor 界面头像响应点击过程


    1,联系人详情界面

     ContactDetailFragment中处理,ViewAdapter装载数据显示头像

     1 private final class ViewAdapter extends BaseAdapter {
     2         ......
     3  
     4         public View getView(int position, View convertView, ViewGroup parent) {
     5             switch (getItemViewType(position)) {
     6                 case VIEW_TYPE_HEADER_ENTRY://获取头像,name等
     7                     return getHeaderEntryView(convertView, parent);
     8                 case VIEW_TYPE_SEPARATOR_ENTRY://同类data,多个item之间分割线
     9                     return getSeparatorEntryView(position, convertView, parent);
    10                 case VIEW_TYPE_KIND_TITLE_ENTRY://data类别标题以及下划线
    11                     return getKindTitleEntryView(position, convertView, parent);
    12                 case VIEW_TYPE_DETAIL_ENTRY://data详情
    13                     return getDetailEntryView(position, convertView, parent);
    14                 case VIEW_TYPE_NETWORK_TITLE_ENTRY:
    15                     return getNetworkTitleEntryView(position, convertView, parent);
    16                 case VIEW_TYPE_ADD_CONNECTION_ENTRY:
    17                     return getAddConnectionEntryView(position, convertView, parent);
    18                 default:
    19                     throw new IllegalStateException("Invalid view type ID " +
    20                             getItemViewType(position));
    21             }
    22         }
    View Code

    构建OnClickListener,并注册启用

     1 private View getHeaderEntryView(View convertView, ViewGroup parent) {
     2             final int desiredLayoutResourceId = R.layout.detail_header_contact_without_updates;
     3             ......
     4 
     5             // Set the photo if it should be displayed
     6             if (viewCache.photoView != null) {
     7                 final boolean expandOnClick = mContactData.getPhotoUri() != null;
     8                 //构造OnClickListener 
     9                 final OnClickListener listener = mPhotoSetter.setupContactPhotoForClick(
    10                         mContext, mContactData, viewCache.photoView, expandOnClick);
    11 
    12                 RawContact rawContact = mContactData.getRawContacts().get(0);
    13                 final String accountType = rawContact.getAccountTypeString();
    14 
    15                 if ((expandOnClick || mContactData.isWritableContact(mContext))
    16                         && !(SimAccountType.ACCOUNT_TYPE.equals(accountType))) {
    17                     ///启用OnClickListener 
    18                     viewCache.enablePhotoOverlay(listener);
    19                 }
    20             }
    View Code 
    public class ContactDetailPhotoSetter extends ImageViewDrawableSetter {
        public OnClickListener setupContactPhotoForClick(Context context, Contact contactData,
                ImageView photoView, boolean expandPhotoOnClick) {
            Bitmap bitmap = setupContactPhoto(contactData, photoView);
            return setupClickListener(context, contactData, bitmap, expandPhotoOnClick);
        }
         ......
    
    private OnClickListener setupClickListener(Context context, Contact contactData, Bitmap bitmap,
                boolean expandPhotoOnClick) {
            final ImageView target = getTarget();
            if (target == null) return null;
    
            return new PhotoClickListener(
                    context, contactData, bitmap, getCompressedImage(), expandPhotoOnClick);
        }
        ......
    
    private static final class PhotoClickListener implements OnClickListener {
            ......
            
            public PhotoClickListener(Context context, Contact contactData, Bitmap photoBitmap,
                    byte[] photoBytes, boolean expandPhotoOnClick) {
              ......
            }
    
            @Override
            public void onClick(View v) {
               ......
    
                Intent photoSelectionIntent = PhotoSelectionActivity.buildIntent(mContext,
                        photoUri, mPhotoBitmap, mPhotoBytes, rect, delta, mContactData.isUserProfile(),
                        mContactData.isDirectoryEntry(), mExpandPhotoOnClick);
                ......
                mContext.startActivity(photoSelectionIntent);
            }
        }
    }
    View Code

    onClick会启动PhotoSelectionActivity

    public class PhotoSelectionActivity extends Activity {
            ......
    
            @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.photoselection_activity);    
            ......
            / Wait until the layout pass to show the photo, so that the source bounds will match up.
            SchedulingUtils.doAfterLayout(mBackdrop, new Runnable() {
                @Override
                public void run() {
                    displayPhoto();
                }
            });
            ......
            private void displayPhoto() {
            ......
            attachPhotoHandler();
        }
    private void attachPhotoHandler() {
             ......
            mPhotoHandler = new PhotoHandler(this, mPhotoView, mode, mState);
    
            if (mPendingPhotoResult != null) {
            ......
            } else {           
                SchedulingUtils.doAfterLayout(mBackdrop, new Runnable() {
                    @Override
                    public void run() {
                        animatePhotoOpen();
                    }
                });
            }
        }
    
    private void animatePhotoOpen() {
            mAnimationListener = new AnimatorListenerAdapter() {
                private void capturePhotoPos() {
                   ......
                }
    
                @Override
                public void onAnimationEnd(Animator animation) {
                    capturePhotoPos();
                    if (mPhotoHandler != null) {
                        //又一个onClick被调用
                        mPhotoHandler.onClick(mPhotoView);
                    }
                }
    
                @Override
                public void onAnimationCancel(Animator animation) {
                    capturePhotoPos();
                }
            };
            animatePhoto(getPhotoEndParams());
        }                
    mPhotoHandler.onClick(mPhotoView)处理
    public abstract class PhotoSelectionHandler implements OnClickListener {
            ......
     @Override
        public void onClick(View v) {
            final PhotoActionListener listener = getListener();
            if (listener != null) {
                if (getWritableEntityIndex() != -1) {
                    mPopup = PhotoActionPopup.createPopupMenu(
                            mContext, mPhotoView, listener, mPhotoMode);
                    mPopup.setOnDismissListener(new OnDismissListener() {
                        @Override
                        public void onDismiss() {
                            listener.onPhotoSelectionDismissed();
                        }
                    });
                    mPopup.show();//显示弹出框ListPopupWindow
                }
            }
        }
    }

    PhotoActionPopup创建ListPopupWindow

     1 public static ListPopupWindow createPopupMenu(Context context, View anchorView,
     2             final Listener listener, int mode) {
     3         // Build choices, depending on the current mode. We assume this Dialog is never called
     4         // if there are NO choices (e.g. a read-only picture is already super-primary)
     5         final ArrayList<ChoiceListItem> choices = new ArrayList<ChoiceListItem>(4);
     6         // Use as Primary
     7         if ((mode & Flags.ALLOW_PRIMARY) > 0) {
     8             choices.add(new ChoiceListItem(ChoiceListItem.ID_USE_AS_PRIMARY,
     9                     context.getString(R.string.use_photo_as_primary)));
    10         }
    11         // Remove
    12         if ((mode & Flags.REMOVE_PHOTO) > 0) {
    13             choices.add(new ChoiceListItem(ChoiceListItem.ID_REMOVE,
    14                     context.getString(R.string.removePhoto)));
    15         }
    16         // Take photo or pick one from the gallery.  Wording differs if there is already a photo.
    17         if ((mode & Flags.TAKE_OR_PICK_PHOTO) > 0) {
    18             boolean replace = (mode & Flags.TAKE_OR_PICK_PHOTO_REPLACE_WORDING) > 0;
    19             final int takePhotoResId = replace ? R.string.take_new_photo : R.string.take_photo;
    20             final String takePhotoString = context.getString(takePhotoResId);
    21             final int pickPhotoResId = replace ? R.string.pick_new_photo : R.string.pick_photo;
    22             final String pickPhotoString = context.getString(pickPhotoResId);
    23             if (PhoneCapabilityTester.isCameraIntentRegistered(context)) {
    24                 choices.add(new ChoiceListItem(ChoiceListItem.ID_TAKE_PHOTO, takePhotoString));
    25             }
    26             choices.add(new ChoiceListItem(ChoiceListItem.ID_PICK_PHOTO, pickPhotoString));
    27         }
    28 
    29         final ListAdapter adapter = new ArrayAdapter<ChoiceListItem>(context,
    30                 R.layout.select_dialog_item, choices);
    31 
    32         final ListPopupWindow listPopupWindow = new ListPopupWindow(context);
    33         final OnItemClickListener clickListener = new OnItemClickListener() {
    34             @Override
    35             public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
    36                 final ChoiceListItem choice = choices.get(position);
    37                 switch (choice.getId()) {
    38                     case ChoiceListItem.ID_USE_AS_PRIMARY:
    39                         listener.onUseAsPrimaryChosen();
    40                         break;
    41                     case ChoiceListItem.ID_REMOVE:
    42                         listener.onRemovePictureChosen();
    43                         break;
    44                     case ChoiceListItem.ID_TAKE_PHOTO:
    45                         listener.onTakePhotoChosen();
    46                         break;
    47                     case ChoiceListItem.ID_PICK_PHOTO:
    48                         listener.onPickFromGalleryChosen();
    49                         break;
    50                 }
    51 
    52                 UiClosables.closeQuietly(listPopupWindow);
    53             }
    54         };
    55 
    56         listPopupWindow.setAnchorView(anchorView);
    57         listPopupWindow.setAdapter(adapter);
    58         listPopupWindow.setOnItemClickListener(clickListener);
    59         listPopupWindow.setModal(true);
    60         listPopupWindow.setInputMethodMode(ListPopupWindow.INPUT_METHOD_NOT_NEEDED);
    61         final int minWidth = context.getResources().getDimensionPixelSize(
    62                 R.dimen.photo_action_popup_min_width);
    63         if (anchorView.getWidth() < minWidth) {
    64             listPopupWindow.setWidth(minWidth);
    65         }
    66         return listPopupWindow;
    67     }
    View Code

    ----------------------------------------------------

    2,联系人编辑界面

    ContactEditorFragment处理, bindEditors()加载编辑界面

    private void bindEditors() {
         ......
        editor = (RawContactEditorView) inflater.inflate(R.layout.raw_contact_editor_view,
                            mContent, false);
        editor.setState(rawContactDelta, type, mViewIdGenerator, isEditingUserProfile());
    
          // Set up the photo handler.
          bindPhotoHandler(editor, type, mState);
        ......
    }

    bindPhotoHandler(...) 构建Listener

      1 private void bindPhotoHandler(BaseRawContactEditorView editor, AccountType type,
      2             RawContactDeltaList state) {
      3         ......
      4         final PhotoHandler photoHandler = new PhotoHandler(mContext, editor, mode, state);
      5         editor.getPhotoEditor().setEditorListener(
      6                 (PhotoHandler.PhotoEditorListener) photoHandler.getListener());
      7         ......
      8 }
      9 private final class PhotoHandler extends PhotoSelectionHandler {
     10 
     11         final long mRawContactId;
     12         private final BaseRawContactEditorView mEditor;
     13         private final PhotoActionListener mPhotoEditorListener;
     14 
     15         public PhotoHandler(Context context, BaseRawContactEditorView editor, int photoMode,
     16                 RawContactDeltaList state) {
     17             super(context, editor.getPhotoEditor(), photoMode, false, state);
     18             mEditor = editor;
     19             mRawContactId = editor.getRawContactId();
     20             mPhotoEditorListener = new PhotoEditorListener();
     21         }
     22 
     23         @Override
     24         public PhotoActionListener getListener() {
     25             return mPhotoEditorListener;
     26         }
     27 
     28         @Override
     29         public void startPhotoActivity(Intent intent, int requestCode, Uri photoUri) {
     30             mRawContactIdRequestingPhoto = mEditor.getRawContactId();
     31             mCurrentPhotoHandler = this;
     32             mStatus = Status.SUB_ACTIVITY;
     33             mCurrentPhotoUri = photoUri;
     34             ContactEditorFragment.this.startActivityForResult(intent, requestCode);
     35         }
     36 
     37         private final class PhotoEditorListener extends PhotoSelectionHandler.PhotoActionListener
     38                 implements EditorListener {
     39 
     40             @Override
     41             public void onRequest(int request) {
     42                 if (!hasValidState()) return;
     43 
     44                 if (request == EditorListener.REQUEST_PICK_PHOTO) {
     45                     onClick(mEditor.getPhotoEditor());
     46                 }
     47             }
     48 
     49             @Override
     50             public void onDeleteRequested(Editor removedEditor) {
     51                 // The picture cannot be deleted, it can only be removed, which is handled by
     52                 // onRemovePictureChosen()
     53             }
     54 
     55             /**
     56              * User has chosen to set the selected photo as the (super) primary photo
     57              */
     58             @Override
     59             public void onUseAsPrimaryChosen() {
     60                 // Set the IsSuperPrimary for each editor
     61                 int count = mContent.getChildCount();
     62                 for (int i = 0; i < count; i++) {
     63                     final View childView = mContent.getChildAt(i);
     64                     if (childView instanceof BaseRawContactEditorView) {
     65                         final BaseRawContactEditorView editor =
     66                                 (BaseRawContactEditorView) childView;
     67                         final PhotoEditorView photoEditor = editor.getPhotoEditor();
     68                         photoEditor.setSuperPrimary(editor == mEditor);
     69                     }
     70                 }
     71                 bindEditors();
     72             }
     73 
     74             /**
     75              * User has chosen to remove a picture
     76              */
     77             @Override
     78             public void onRemovePictureChosen() {
     79                 mEditor.setPhotoBitmap(null);
     80 
     81                 // Prevent bitmap from being restored if rotate the device.
     82                 // (only if we first chose a new photo before removing it)
     83                 mUpdatedPhotos.remove(String.valueOf(mRawContactId));
     84                 bindEditors();
     85             }
     86 
     87             @Override
     88             public void onPhotoSelected(Uri uri) throws FileNotFoundException {
     89                 final Bitmap bitmap = ContactPhotoUtils.getBitmapFromUri(mContext, uri);
     90                 setPhoto(mRawContactId, bitmap, uri);
     91                 mCurrentPhotoHandler = null;
     92                 bindEditors();
     93             }
     94 
     95             @Override
     96             public Uri getCurrentPhotoUri() {
     97                 return mCurrentPhotoUri;
     98             }
     99 
    100             @Override
    101             public void onPhotoSelectionDismissed() {
    102                 // Nothing to do.
    103             }
    104         }
    105     }
    View Code

    RawContactEditorView加载PhotoEditorView,PhotoEditorView注册Listener

    public class RawContactEditorView extends BaseRawContactEditorView {
            ......
            @Override
        protected void onFinishInflate() {
            super.onFinishInflate();
            ......
        }
           ......  
    }
    
    public abstract class BaseRawContactEditorView extends LinearLayout {
            ......
            Override
        protected void onFinishInflate() {
            super.onFinishInflate();
    
            mBody = findViewById(R.id.body);
            mDivider = findViewById(R.id.divider);
    
            mPhoto = (PhotoEditorView)findViewById(R.id.edit_photo);
            mPhoto.setEnabled(isEnabled());
        }
        ......
    }
    
    public class PhotoEditorView extends LinearLayout implements Editor {
            ......
    @Override
        protected void onFinishInflate() {
            super.onFinishInflate();            
            mPhotoImageView = (ImageView) findViewById(R.id.photo);
            mFrameView = findViewById(R.id.frame);
            mFrameView.setOnClickListener(new OnClickListener() {
                @Override//响应点击onClick   
                public void onClick(View v) {
                    if (mListener != null) { 
                mListener.onRequest(EditorListener.REQUEST_PICK_PHOTO); } } }); } ...... }

     mListener.onRequest就是ContactEditorFragment中bindPhotoHandler中定义的

    private final class PhotoHandler extends PhotoSelectionHandler {    ......
            public PhotoHandler(Context context, BaseRawContactEditorView editor, int photoMode,
                    RawContactDeltaList state) {
                super(context, editor.getPhotoEditor(), photoMode, false, state);
                mEditor = editor;
                mRawContactId = editor.getRawContactId();
                mPhotoEditorListener = new PhotoEditorListener();
            }
            ......
            private final class PhotoEditorListener extends PhotoSelectionHandler.PhotoActionListener
                    implements EditorListener {
    
                @Override
                public void onRequest(int request) {
                    if (!hasValidState()) return;
    
                    if (request == EditorListener.REQUEST_PICK_PHOTO) {
                        onClick(mEditor.getPhotoEditor());//调用PhotoSelectionHandler 中定义的onClick方法。
    } } ...... } ...... }

    PhotoSelectionHandler中的onClick

    public abstract class PhotoSelectionHandler implements OnClickListener {
    ......
        @Override
        public void onClick(View v) {
            final PhotoActionListener listener = getListener();
            if (listener != null) {
                if (getWritableEntityIndex() != -1) {
                    mPopup = PhotoActionPopup.createPopupMenu(
                            mContext, mPhotoView, listener, mPhotoMode);
                    mPopup.setOnDismissListener(new OnDismissListener() {
                        @Override
                        public void onDismiss() {
                            listener.onPhotoSelectionDismissed();
                        }
                    });
                    mPopup.show();
                }
            }
        }
    ......
    }

    然后又是PhotoActionPopup.createPopupMenu处理。

    ---------------------------------------------------------

    综上:联系人详情 and 联系人编辑界面响应头像点击过程都是:

    先构建并注册OnClickListener,——>Listener处理——>调用PhotoSelectionHandler中的onClick——>PhotoActionPopup.createPopupMenux 显示弹出框PopupWindow

    区别在于Listener的构建,和传递的参数。

  • 相关阅读:
    如何让position:fixed在IE6中工作 不抖动
    【javascript基础】之【宿主环境】
    用函数式编程技术编写优美的 JavaScript
    IE6下使用滤镜后链接不能点击的BUG
    什么是内存泄漏
    Best Practices for Speeding Up Your Web Site
    Object.prototype.toString.call()
    【前端优化】IE浏览器下同一网页多图片显示的瓶颈与优化
    get username
    open file and format readin
  • 原文地址:https://www.cnblogs.com/antoon/p/4383052.html
Copyright © 2020-2023  润新知