1,联系人详情界面

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

 private final class ViewAdapter extends BaseAdapter {
...... public View getView(int position, View convertView, ViewGroup parent) {
switch (getItemViewType(position)) {
case VIEW_TYPE_HEADER_ENTRY://获取头像,name等
return getHeaderEntryView(convertView, parent);
case VIEW_TYPE_SEPARATOR_ENTRY://同类data,多个item之间分割线
return getSeparatorEntryView(position, convertView, parent);
case VIEW_TYPE_KIND_TITLE_ENTRY://data类别标题以及下划线
return getKindTitleEntryView(position, convertView, parent);
case VIEW_TYPE_DETAIL_ENTRY://data详情
return getDetailEntryView(position, convertView, parent);
case VIEW_TYPE_NETWORK_TITLE_ENTRY:
return getNetworkTitleEntryView(position, convertView, parent);
case VIEW_TYPE_ADD_CONNECTION_ENTRY:
return getAddConnectionEntryView(position, convertView, parent);
default:
throw new IllegalStateException("Invalid view type ID " +
getItemViewType(position));
}
}

构建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 }
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);
}
}
}

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

 public static ListPopupWindow createPopupMenu(Context context, View anchorView,
final Listener listener, int mode) {
// Build choices, depending on the current mode. We assume this Dialog is never called
// if there are NO choices (e.g. a read-only picture is already super-primary)
final ArrayList<ChoiceListItem> choices = new ArrayList<ChoiceListItem>(4);
// Use as Primary
if ((mode & Flags.ALLOW_PRIMARY) > 0) {
choices.add(new ChoiceListItem(ChoiceListItem.ID_USE_AS_PRIMARY,
context.getString(R.string.use_photo_as_primary)));
}
// Remove
if ((mode & Flags.REMOVE_PHOTO) > 0) {
choices.add(new ChoiceListItem(ChoiceListItem.ID_REMOVE,
context.getString(R.string.removePhoto)));
}
// Take photo or pick one from the gallery. Wording differs if there is already a photo.
if ((mode & Flags.TAKE_OR_PICK_PHOTO) > 0) {
boolean replace = (mode & Flags.TAKE_OR_PICK_PHOTO_REPLACE_WORDING) > 0;
final int takePhotoResId = replace ? R.string.take_new_photo : R.string.take_photo;
final String takePhotoString = context.getString(takePhotoResId);
final int pickPhotoResId = replace ? R.string.pick_new_photo : R.string.pick_photo;
final String pickPhotoString = context.getString(pickPhotoResId);
if (PhoneCapabilityTester.isCameraIntentRegistered(context)) {
choices.add(new ChoiceListItem(ChoiceListItem.ID_TAKE_PHOTO, takePhotoString));
}
choices.add(new ChoiceListItem(ChoiceListItem.ID_PICK_PHOTO, pickPhotoString));
} final ListAdapter adapter = new ArrayAdapter<ChoiceListItem>(context,
R.layout.select_dialog_item, choices); final ListPopupWindow listPopupWindow = new ListPopupWindow(context);
final OnItemClickListener clickListener = new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
final ChoiceListItem choice = choices.get(position);
switch (choice.getId()) {
case ChoiceListItem.ID_USE_AS_PRIMARY:
listener.onUseAsPrimaryChosen();
break;
case ChoiceListItem.ID_REMOVE:
listener.onRemovePictureChosen();
break;
case ChoiceListItem.ID_TAKE_PHOTO:
listener.onTakePhotoChosen();
break;
case ChoiceListItem.ID_PICK_PHOTO:
listener.onPickFromGalleryChosen();
break;
} UiClosables.closeQuietly(listPopupWindow);
}
}; listPopupWindow.setAnchorView(anchorView);
listPopupWindow.setAdapter(adapter);
listPopupWindow.setOnItemClickListener(clickListener);
listPopupWindow.setModal(true);
listPopupWindow.setInputMethodMode(ListPopupWindow.INPUT_METHOD_NOT_NEEDED);
final int minWidth = context.getResources().getDimensionPixelSize(
R.dimen.photo_action_popup_min_width);
if (anchorView.getWidth() < minWidth) {
listPopupWindow.setWidth(minWidth);
}
return listPopupWindow;
}

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

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

 private void bindPhotoHandler(BaseRawContactEditorView editor, AccountType type,
RawContactDeltaList state) {
......
final PhotoHandler photoHandler = new PhotoHandler(mContext, editor, mode, state);
editor.getPhotoEditor().setEditorListener(
(PhotoHandler.PhotoEditorListener) photoHandler.getListener());
......
}
private final class PhotoHandler extends PhotoSelectionHandler { final long mRawContactId;
private final BaseRawContactEditorView mEditor;
private final PhotoActionListener mPhotoEditorListener; 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();
} @Override
public PhotoActionListener getListener() {
return mPhotoEditorListener;
} @Override
public void startPhotoActivity(Intent intent, int requestCode, Uri photoUri) {
mRawContactIdRequestingPhoto = mEditor.getRawContactId();
mCurrentPhotoHandler = this;
mStatus = Status.SUB_ACTIVITY;
mCurrentPhotoUri = photoUri;
ContactEditorFragment.this.startActivityForResult(intent, requestCode);
} 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());
}
} @Override
public void onDeleteRequested(Editor removedEditor) {
// The picture cannot be deleted, it can only be removed, which is handled by
// onRemovePictureChosen()
} /**
* User has chosen to set the selected photo as the (super) primary photo
*/
@Override
public void onUseAsPrimaryChosen() {
// Set the IsSuperPrimary for each editor
int count = mContent.getChildCount();
for (int i = 0; i < count; i++) {
final View childView = mContent.getChildAt(i);
if (childView instanceof BaseRawContactEditorView) {
final BaseRawContactEditorView editor =
(BaseRawContactEditorView) childView;
final PhotoEditorView photoEditor = editor.getPhotoEditor();
photoEditor.setSuperPrimary(editor == mEditor);
}
}
bindEditors();
} /**
* User has chosen to remove a picture
*/
@Override
public void onRemovePictureChosen() {
mEditor.setPhotoBitmap(null); // Prevent bitmap from being restored if rotate the device.
// (only if we first chose a new photo before removing it)
mUpdatedPhotos.remove(String.valueOf(mRawContactId));
bindEditors();
} @Override
public void onPhotoSelected(Uri uri) throws FileNotFoundException {
final Bitmap bitmap = ContactPhotoUtils.getBitmapFromUri(mContext, uri);
setPhoto(mRawContactId, bitmap, uri);
mCurrentPhotoHandler = null;
bindEditors();
} @Override
public Uri getCurrentPhotoUri() {
return mCurrentPhotoUri;
} @Override
public void onPhotoSelectionDismissed() {
// Nothing to do.
}
}
}

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的构建,和传递的参数。

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. Python 多继承与MRO-C3算法

    继承关系图:树结构 广度优先遍历:先找A,再找B.C,最后找D.E.(顺序:A.B.C) 深度优先遍历:先找A,再找B,接着找D.E(把B里面找完):然后找C.(顺序:A.B.D.E.C) MRO-C ...

  2. IDEA中配置JUnit单元测试

    参考安装教程:https://www.jianshu.com/p/c37753b6dbd6 如果想用junit4的话,需要在pom.xml中配置. 需要安装JUnitGenerator V2.0插件, ...

  3. poj1942(求组合数)

    题目链接:http://poj.org/problem?id=1942 题意:实际上这道题就是求C(n+m,n). 思路:n.m的范围在unsigned中,所以不能递推计算组合数,可以采用公式C(a, ...

  4. cf-Global Round2-E. Pavel and Triangles

    题目链接:http://codeforces.com/contest/1119/problem/E 题意:给定n个数a[i],分别表示长度为2i-1的木条的数量,问使用这些木条最多能构成多少三角形. ...

  5. cisco 3850 GBIC报错处理

    今天有用户cisco 3850插入多模千兆光模块后报错日志如下: *Oct 18 13:48:54: %PLATFORM_PM-6-MODULE_ERRDISABLE:The inserted SFP ...

  6. stm32初做项目心得

    在导师的带领下,基本了解了嵌入式的开发的基本流程: 1.首先从厂家拿到样板之后,首先进行检测,检测什么呢,先检测电源系统,看你的电源系统是否能够正常工作,就是各个管脚是否短路,断路. 2.检测完之后, ...

  7. 100-days: Five

    Title: Feel better now ? The rise and rise of the anxiety economy(焦虑经济) rise and rise 一直上升 anxiety n ...

  8. 从零开始写一个npm包及上传

    最近刚好自己需要写公有npm包及上传,虽然百度上资料都能找到,但是都是比较零零碎碎的,个人就来整理下,如何从零开始写一个npm包及上传. 该篇文件只记录一个大概的流程,一些细节没有记录. tips:  ...

  9. HandlerMapping和HandlerAdapter配置须知

    ---------------------siwuxie095                                 HandlerMapping 和 HandlerAdapter 配置须知 ...

  10. 【Linux 进程】fork函数详解

    一.fork入门知识 一个进程,包括代码.数据和分配给进程的资源.fork()函数通过系统调用创建一个与原来进程几乎完全相同的进程,也就是两个进程可以做完全相同的事,但如果初始参数或者传入的变量不同, ...