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- ...
随机推荐
- Linux 设置Redis开机启动
Debian 也就是Ubun16.04 亲测可用 http://www.tuicool.com/articles/UR73ieq Centos7.0 http://blog.csdn.net/alex ...
- Linux服务器安装配置Nginx服务器
Nginx("engine x")是一款是由俄罗斯的程序设计师Igor Sysoev所开发高性能的 Web和 反向代理 服务器,也是一个 IMAP/POP3/SMTP 代理服务 ...
- springboot找不到主类
在学习springboot的时候,前几天写了一个demo,正常运行,一点问题也没有.今天运行不起来了. 报错:找不到主类 解决方案: Project->Clean->选中项目,点击Clea ...
- php项目执行composer install时报错
报错信息: Loading composer repositories with package informationInstalling dependencies (including requi ...
- oracle中获取当前整点和上一个小时整点,日期类型
select to_date(to_char(sysdate,'yyyy-mm-dd hh'),'yyyy-mm-dd hh:mi:ss') from dual;select to_date(to_c ...
- 公告栏添加时钟——利用canvas画出一个时钟
前言 最近在学习HTML5标签,学到Canvas,觉得很有趣.便在慕课网找了个demo练手.就是Canvas时钟. 对于canvas,w3shcool上是这么描述的: HTML5 <canvas ...
- vue 引用公共方法(例子:截取字符串固定字数,其余显示...)
1.写公共js 2.main.js引入公共js 3.在组件中用this.common.方法名 引用
- TZOJ 1221 Tempter of the Bone(回溯+剪枝)
描述 The doggie found a bone in an ancient maze, which fascinated him a lot. However, when he picked i ...
- POJ 3169 Layout(差分约束+链式前向星+SPFA)
描述 Like everyone else, cows like to stand close to their friends when queuing for feed. FJ has N (2 ...
- rbac集成 权限分配。之角色管理
权限分配功能拆分: a. 角色管理 b. 用户管理 c. 菜单和权限的管理 d. 批量的权限操作 e. 分配权限 先实现 角色管理: 无非也就是,增删改查: 定义路由, 编写视图. 1.查看角色页面: ...