ContactDetail 和 ContactEditor 界面头像响应点击过程
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 界面头像响应点击过程的更多相关文章
- QTableWidget界面有数据之后鼠标点击无响应界面无响应
1.问题:QTableWidget上出现数据之后,界面无响应,鼠标点击没有响应,但是还是可以正常接收数据,连关闭按钮都无法关闭,必须通过杀死进程来关闭程序.有的电脑是无响应,有的电脑又可以. 2.分析 ...
- iOS开发-UIImageView响应点击事件
UIImageView是不能够响应点击事件的,在开发过程中我们需要经常对头像等添加点击事件,上网搜索一番后发现有如下两个方法: 1.找到点击图片Event,添加事件处理函数 UIImageView.u ...
- C#解决界面不响应
在我们的程序中,经常会有一些耗时较长的运算,为了保证用户体验,不引起界面不响应,我们一般会采用多线程操作,让耗时操作在后台完成,完成后再进行处理或给出提示,在运行中,也会时时去刷新界面上的进度条等显示 ...
- UIButton无法响应点击事件
一.问题描述 因为项目需要,需要UITableView上添加固定的筛选表头,一直固定,不能随UITableView滚动.所以直接将表头与UITableView分离,将它添加到控制器的UIView上,即 ...
- 设置TextView下划线并响应点击事件(SpannableString)
下面是一个20行的完整Demo代码:基本原理是使用一个SpannableString并设置其ClickableSpan来响应点击事件. TextView useInfo = (TextView) fi ...
- 隐藏自定义的tabbar之后,push到B视图,B视图的键盘工具条无法响应点击事件
我的情况如下: 在TabbarViewController中隐藏了系统的tabbar,然后自定义tabbar,A B C D 4个视图都有UINavigationController,A视图 使用的是 ...
- Android EditText中插入图片并响应点击事件
EditText中插入图片基本就是两种方法: ,通过Html.fromHtml(..)来实现 [mw_shl_code=java,true]eText.append(Html.fromHtml(&qu ...
- 每周问题系列 - JavaFX界面没响应,Maven编译自动忽略rt包
本人博客文章网址:https://www.peretang.com/weekly-problem-session-week-31/ 前言 新开一个系列, 用来记录每周遇到的问题 JavaFX界面没响应 ...
- Ubuntu16.04 下的网易云出现网络异常、无法播放,界面无响应问题的统一解决
能够在Linux系统下体验到原生界面的网易云音乐是件不错的事情,但是它总是经常性的出现网络异常,界面无响应的问题 为了听歌的体验,进行深入探究: 首先通过终端启用网易云音乐:sudo netease- ...
随机推荐
- veil-catapult
veil-catapult进行payload投放,直接使payload在内存中执行. kaliIP:192.168.1.119 目标IP:192.168.1.121 1.powershell powe ...
- android显示和隐藏软键盘(转)
显示键盘: EditText editText.setFocusable(true); editText.setFocusableInTouchMode(true); editText.request ...
- 库的操作&表的操作
一 库的操作 掌握库的增删改查 一.系统数据库 执行如下命令,查看系统库 show databases; information_schema: 虚拟库,不占用磁盘空间,存储的是数据库启动后的一些参数 ...
- c++ 读入优化、输出优化模板
0. 在有些输入数据很多的变态题中,scanf会大大拖慢程序的时间,cin就更慢了,所以就出现了读入优化.其原理就是一个一个字符的读入,输出优化同理,主要使用getchar,putchar函数. 1. ...
- set<pair<int,int> >的用法
例题链接:https://vjudge.net/contest/236677#problem/D 题意:首先输入两个数字n,m.n表示有n张桌子,编号从1到n,m表示有m个操作, 然后接下来一行有n个 ...
- 发送邮件【文本-html】【图片】【邮件】【附件】
依赖 <!-- https://mvnrepository.com/artifact/javax.mail/mail --> <dependency> <groupId& ...
- 项目总结01:JSP mysql SpringMvc下中国省市县三级联动下拉框
JSP mysql SpringMvc下中国省市县三级联动下拉框 关键词 JSP mysql数据库 SpringMvc ajax Controller层 Service层 中国地区 省 ...
- bbs项目富文本编辑器实现上传文件到media目录
media目录是在project的settings中设置的,static目录是django自己使用的静态文件的上传目录,media目录是用户自定义上传文件的目录 # Django用户上传的文件都放在m ...
- JQuery UI之Autocomplete(4)多值输入、远程缓存与组合框
1.多值输入 首先加入相关的css和js文件,以及对应的HTML代码如下: <link href="../css/jquery-ui.css" rel="style ...
- MyBatis延迟加载和缓存(4)
一.项目创建 1.项目目录结构 2.数据库配置和上一篇的一样,这里不再描述.下面创建mybatis配置文件SqlMapConfig.xml <?xml version="1.0&quo ...