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. Java8中的[方法引用]“双冒号”——走进Java Lambda(四)

    前面的章节我们提及到过双冒号运算符,双冒号运算就是Java中的[方法引用],[方法引用]的格式是 类名::方法名 注意是方法名哦,后面没有括号“()”哒.为啥不要括号,因为这样的是式子并不代表一定会调 ...

  2. Linux下鼠标滚轮速度调整

    安装imwheel 于home下创建.imwheelrc gedit ~/.imwheelrc 在.imwheelrc中粘贴以下内容 ".*" None, Up, Button4, ...

  3. SpringBoot @Value读取properties文件的属性

    SpringBoot在application.properties文件中,可以自定义属性. 在properties文件中如下示: #自定义属性 mail.fromMail.addr=lgr@163.c ...

  4. LibreOJ 6277. 数列分块入门 2

    题目链接:https://loj.ac/problem/6278 参考博客:https://blog.csdn.net/qq_36038511/article/details/79725027 这题我 ...

  5. Mac Sublime Text3 如何安装插件

    1.打开sublime text3后按快捷键control+`后下面会出来东西,然后输入如下命令. import urllib.request,os; pf = 'Package Control.su ...

  6. Python: print stdout同行输出

    项目中发现,PyCharm运行youtube_dl下载,其进度在同行显示,即替换上行输出. 稍做研究,记录下来: #coding=utf-8 from __future__ import print_ ...

  7. php中时间转换函数

    date("Y-m-d H:i",$unixtime)  1.php中获得今天零点的时间戳 要获得零点的unix时间戳,可以使用 $todaytime=strtotime(“tod ...

  8. stark组件开发之URL分发和默认Handler

    为register 函数添加一个,prev参数,默认None ,用于可以让用户自己指定前缀. def register(self, model_class, handler_class=None, p ...

  9. Solidity通过合约转ERC20代币

    ERC20代币并不能像Ether一样使用sendTo.transfer(amt)来转账,ERC20代币只能通过token中定义的transfer方法来转账,每个账户的余额信息也只保存在token合约的 ...

  10. shell 脚本编写基础

    在进行Linux测试时编写脚本是必不可少的,Shell脚本的名称可以随便定义,也不要什么后缀名,例如可以写abc,smartzip这类名称,运行时只要键入 ./smartzip就能运行脚本了.. 每行 ...