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. }

构建OnClickListener,并注册启用

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

onClick会启动PhotoSelectionActivity

  1. public class PhotoSelectionActivity extends Activity {
  2. ......
  3.  
  4. @Override
  5. protected void onCreate(Bundle savedInstanceState) {
  6. super.onCreate(savedInstanceState);
  7. setContentView(R.layout.photoselection_activity);
  8. ......
  9. / Wait until the layout pass to show the photo, so that the source bounds will match up.
  10. SchedulingUtils.doAfterLayout(mBackdrop, new Runnable() {
  11. @Override
  12. public void run() {
  13. displayPhoto();
  14. }
  15. });
  16. ......
  17. private void displayPhoto() {
  18. ......
  19. attachPhotoHandler();
  20. }
  21. private void attachPhotoHandler() {
  22. ......
  23. mPhotoHandler = new PhotoHandler(this, mPhotoView, mode, mState);
  24.  
  25. if (mPendingPhotoResult != null) {
  26. ......
  27. } else {
  28. SchedulingUtils.doAfterLayout(mBackdrop, new Runnable() {
  29. @Override
  30. public void run() {
  31. animatePhotoOpen();
  32. }
  33. });
  34. }
  35. }
  36.  
  37. private void animatePhotoOpen() {
  38. mAnimationListener = new AnimatorListenerAdapter() {
  39. private void capturePhotoPos() {
  40. ......
  41. }
  42.  
  43. @Override
  44. public void onAnimationEnd(Animator animation) {
  45. capturePhotoPos();
  46. if (mPhotoHandler != null) {
  47. //又一个onClick被调用
  48. mPhotoHandler.onClick(mPhotoView);
  49. }
  50. }
  51.  
  52. @Override
  53. public void onAnimationCancel(Animator animation) {
  54. capturePhotoPos();
  55. }
  56. };
  57. animatePhoto(getPhotoEndParams());
  58. }
  1. mPhotoHandler.onClick(mPhotoView)处理
  1. public abstract class PhotoSelectionHandler implements OnClickListener {
  2. ......
  3. @Override
  4. public void onClick(View v) {
  5. final PhotoActionListener listener = getListener();
  6. if (listener != null) {
  7. if (getWritableEntityIndex() != -1) {
  8. mPopup = PhotoActionPopup.createPopupMenu(
  9. mContext, mPhotoView, listener, mPhotoMode);
  10. mPopup.setOnDismissListener(new OnDismissListener() {
  11. @Override
  12. public void onDismiss() {
  13. listener.onPhotoSelectionDismissed();
  14. }
  15. });
  16. mPopup.show();//显示弹出框ListPopupWindow
  17. }
  18. }
  19. }
  20. }

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. }

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

2,联系人编辑界面

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

  1. private void bindEditors() {
  2. ......
  3. editor = (RawContactEditorView) inflater.inflate(R.layout.raw_contact_editor_view,
  4. mContent, false);
  5. editor.setState(rawContactDelta, type, mViewIdGenerator, isEditingUserProfile());
  6.  
  7. // Set up the photo handler.
  8. bindPhotoHandler(editor, type, mState);
  9. ......
  10. }

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. }

RawContactEditorView加载PhotoEditorView,PhotoEditorView注册Listener

  1. public class RawContactEditorView extends BaseRawContactEditorView {
  2. ......
  3. @Override
  4. protected void onFinishInflate() {
  5. super.onFinishInflate();
  6. ......
  7. }
  8. ......
  9. }
  10.  
  11. public abstract class BaseRawContactEditorView extends LinearLayout {
  12. ......
  13. Override
  14. protected void onFinishInflate() {
  15. super.onFinishInflate();
  16.  
  17. mBody = findViewById(R.id.body);
  18. mDivider = findViewById(R.id.divider);
  19.  
  20. mPhoto = (PhotoEditorView)findViewById(R.id.edit_photo);
  21. mPhoto.setEnabled(isEnabled());
  22. }
  23. ......
  24. }
  25.  
  26. public class PhotoEditorView extends LinearLayout implements Editor {
  27. ......
  28. @Override
  29. protected void onFinishInflate() {
  30. super.onFinishInflate();
  31. mPhotoImageView = (ImageView) findViewById(R.id.photo);
  32. mFrameView = findViewById(R.id.frame);
  33. mFrameView.setOnClickListener(new OnClickListener() {
  34. @Override//响应点击onClick
  35. public void onClick(View v) {
  36. if (mListener != null) {
                mListener.onRequest(EditorListener.REQUEST_PICK_PHOTO);
  37. }
  38. }
  39. });
  40. }
  41. ......
  42. }

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

  1. private final class PhotoHandler extends PhotoSelectionHandler { ......
  2. public PhotoHandler(Context context, BaseRawContactEditorView editor, int photoMode,
  3. RawContactDeltaList state) {
  4. super(context, editor.getPhotoEditor(), photoMode, false, state);
  5. mEditor = editor;
  6. mRawContactId = editor.getRawContactId();
  7. mPhotoEditorListener = new PhotoEditorListener();
  8. }
  9. ......
  10. private final class PhotoEditorListener extends PhotoSelectionHandler.PhotoActionListener
  11. implements EditorListener {
  12.  
  13. @Override
  14. public void onRequest(int request) {
  15. if (!hasValidState()) return;
  16.  
  17. if (request == EditorListener.REQUEST_PICK_PHOTO) {
  18. onClick(mEditor.getPhotoEditor());//调用PhotoSelectionHandler 中定义的onClick方法。
  1. } } ...... } ...... }

PhotoSelectionHandler中的onClick

  1. public abstract class PhotoSelectionHandler implements OnClickListener {
  2. ......
  3. @Override
  4. public void onClick(View v) {
  5. final PhotoActionListener listener = getListener();
  6. if (listener != null) {
  7. if (getWritableEntityIndex() != -1) {
  8. mPopup = PhotoActionPopup.createPopupMenu(
  9. mContext, mPhotoView, listener, mPhotoMode);
  10. mPopup.setOnDismissListener(new OnDismissListener() {
  11. @Override
  12. public void onDismiss() {
  13. listener.onPhotoSelectionDismissed();
  14. }
  15. });
  16. mPopup.show();
  17. }
  18. }
  19. }
  20. ......
  21. }

然后又是PhotoActionPopup.createPopupMenu处理。

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

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

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

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

ContactDetail 和 ContactEditor 界面头像响应点击过程的更多相关文章

  1. QTableWidget界面有数据之后鼠标点击无响应界面无响应

    1.问题:QTableWidget上出现数据之后,界面无响应,鼠标点击没有响应,但是还是可以正常接收数据,连关闭按钮都无法关闭,必须通过杀死进程来关闭程序.有的电脑是无响应,有的电脑又可以. 2.分析 ...

  2. iOS开发-UIImageView响应点击事件

    UIImageView是不能够响应点击事件的,在开发过程中我们需要经常对头像等添加点击事件,上网搜索一番后发现有如下两个方法: 1.找到点击图片Event,添加事件处理函数 UIImageView.u ...

  3. C#解决界面不响应

    在我们的程序中,经常会有一些耗时较长的运算,为了保证用户体验,不引起界面不响应,我们一般会采用多线程操作,让耗时操作在后台完成,完成后再进行处理或给出提示,在运行中,也会时时去刷新界面上的进度条等显示 ...

  4. UIButton无法响应点击事件

    一.问题描述 因为项目需要,需要UITableView上添加固定的筛选表头,一直固定,不能随UITableView滚动.所以直接将表头与UITableView分离,将它添加到控制器的UIView上,即 ...

  5. 设置TextView下划线并响应点击事件(SpannableString)

    下面是一个20行的完整Demo代码:基本原理是使用一个SpannableString并设置其ClickableSpan来响应点击事件. TextView useInfo = (TextView) fi ...

  6. 隐藏自定义的tabbar之后,push到B视图,B视图的键盘工具条无法响应点击事件

    我的情况如下: 在TabbarViewController中隐藏了系统的tabbar,然后自定义tabbar,A B C D 4个视图都有UINavigationController,A视图 使用的是 ...

  7. Android EditText中插入图片并响应点击事件

    EditText中插入图片基本就是两种方法: ,通过Html.fromHtml(..)来实现 [mw_shl_code=java,true]eText.append(Html.fromHtml(&qu ...

  8. 每周问题系列 - JavaFX界面没响应,Maven编译自动忽略rt包

    本人博客文章网址:https://www.peretang.com/weekly-problem-session-week-31/ 前言 新开一个系列, 用来记录每周遇到的问题 JavaFX界面没响应 ...

  9. Ubuntu16.04 下的网易云出现网络异常、无法播放,界面无响应问题的统一解决

    能够在Linux系统下体验到原生界面的网易云音乐是件不错的事情,但是它总是经常性的出现网络异常,界面无响应的问题 为了听歌的体验,进行深入探究: 首先通过终端启用网易云音乐:sudo netease- ...

随机推荐

  1. HibernateDaoSupport类的使用(转)

    看到一篇很好描述HibernateDaoSupport类使用的例子,特此在这和大家分享一下 核心提示:1. 继承了HibernateDaoSupport类的类获取session时,已不可用Sessio ...

  2. hibernate 中,出现了错误 "node to traverse cannot be null!" 如何改正

    这个错误基本上是因为hql语句写错了而造成的, 返回找hql输出一下发现, hql语句中间少了几个空格, 写成了String hql = "from"+className+&quo ...

  3. SQLdeveloper换成windows主题后不显示的情况

    这几天因为换电脑需要重新安装数据库, 因为换成了64位系统, 原先的oracle数据库也换成了64位, 但是plsql还是要用32位的, 经过深思熟虑也没装, 请教了一个同学改用oracle自带的sq ...

  4. .mht文件转换为html

    用360浏览器打开文件后,Ctrl + s  保存即可

  5. helm 更改为国内源

     helm init --upgrade -i slpcat/tiller:v2.8.2 --stable-repo-url https://kubernetes.oss-cn-hangzhou.al ...

  6. DHCP server 冒充及DOS攻击处理方案

    一.DHCP服务器在运维上存在的常见问题: 1. DHCP服务器冒充 在DHCP服务器和客户端之间没有认证机制,如果在DHCP server覆盖的网络上随意接入一个DHCP server,就有可能造成 ...

  7. Android 性能测试之CPU

    接上一篇 CPU跟内存一样,存在一些测试子项,如下清单所示 1.空闲状态下的应用CPU消耗情况 2.中等规格状态下的应用CPU消耗情况 3.满规格状态下的应用CPU消耗情况 4.应用CPU峰值情况 C ...

  8. cross-env:跨平台设置和使用环境变量

    一 项目结构 二 安装依赖 npm install --save-dev cross-env 三 npm脚本 { "name": "demo", "v ...

  9. Vue Baidu Map 插件的使用

    最近在做一个项目,技术采用的是Vue.js套餐,有个百度地图的需求,当时,大脑宕机,立马去引入百度地图API,当时想到两种方法,一种是在index.html中全局引入js,此法吾不喜,就采用了第二种异 ...

  10. 微信小程序开发——开发者工具无法输入中文的处理

    问题模块 框架类型 问题类型 操作系统 工具版本 开发者工具 小程序 Bug Windows v.02.1810290 异常描述: 无法输入中文,偶现,但是概率有点高,重启,重装,更新版本等等都未解决 ...