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. msf客户端渗透(十):社会工程学

    启动社会工程学攻击组件 生成二维码攻击模块 输入你想生成二维码的url,这里做演示用www.baidu.com 二维码生成后,在这个路径下 生成u盘,DVD的多媒体攻击载荷 通过修改autorun.i ...

  2. Removing Docker Containers and Images

    Removing Docker Containers and Images In a recent post aboutDocker, we looked into some things that ...

  3. 百度浏览器 UserAgent

    Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.122 BIDUBrowser ...

  4. 东方超环(EAST)世界纪录

    2017年7月3日夜晚,国家大科学装置——世界上第一个全超导托卡马克(EAST)东方超环再传捷报:实现了稳定的101.2秒稳态长脉冲高约束等离子体运行,创造了新的世界纪录.这标志着EAST成为了世界上 ...

  5. c++ - Linking problems due to symbols with abi::cxx11?

    看错误内容: /data/projects/LipReadingSDKGPU/lib/cwlibs/libLipReading.so: undefined reference to `tensorfl ...

  6. C/C++ typedef用法详解(真的很详细)

    第一.四个用途 用途一: 定义一种类型的别名,而不只是简单的宏替换.可以用作同时声明指针型的多个对象.比如:char* pa, pb; // 这多数不符合我们的意图,它只声明了一个指向字符变量的指针, ...

  7. 像素 转换 px dp

    public static int dip2px(Context context, float dpValue){ final float scale = context.getResources() ...

  8. oracle中获取当前整点和上一个小时整点,日期类型

    select to_date(to_char(sysdate,'yyyy-mm-dd hh'),'yyyy-mm-dd hh:mi:ss') from dual;select to_date(to_c ...

  9. [Unity3D]降低向Shader中传值的开销

    Unity3D中提供了很多API用于向shader传值,这篇文章对比测试了两类不同的使用方法的性能. 正文 Unity3D中,通过C#代码向shader传值有两种方式. 一种是面向具体的materia ...

  10. Codeforces Beta Round #69 (Div. 2 Only)

    Codeforces Beta Round #69 (Div. 2 Only) http://codeforces.com/contest/80 A #include<bits/stdc++.h ...