首先看一下实现的效果图:
实现思路,首先要对Dialog进行自定义,使用我们自己的布局,其次我们发现Dialog中展示的数据类型、展示的样式也是略有不同的,这就需要我们在数据格式方法进行一些设置,以实现在同一个Dialog去展示不同的效果。
public class CommonShareToDialog extends Dialog {
public CommonShareToDialog(Context context) {
super(context);
}
public CommonShareToDialog(Context context, int theme) {
super(context, theme);
}
public static class Builder {
private Context context;
private boolean noTitle = true;
private String title;
private String message;
private ImageView ivShowDetail;
private List<GroupMemberEntity> mGroupMemberEntities;
private DialogGroupMemberAdapter mGroupMemberAdapter;
private ShareContent shareContent;
private boolean isShow;
private Animation mRotateAnimation;
private OnSendClickListener mOnSendClickListener;
private OnCancleClickListener mOnCancleClickListener;
private OnContentClickListener mOnContentClickListener;
private Handler mHandler = new Handler() {
public void handleMessage(android.os.Message msg) {
switch (msg.what) {
case 0:
// 执行动画
mRotateAnimation = AnimationUtils.loadAnimation(context, R.anim.imageviwe_rotate);
// 动画执行完后停留在执行完的状态
mRotateAnimation.setFillAfter(true);
ivShowDetail.startAnimation(mRotateAnimation);
break;
case 1:
// 执行动画
mRotateAnimation = AnimationUtils.loadAnimation(context, R.anim.imageviwe_rotate_normal);
// 动画执行完后停留在执行完的状态
mRotateAnimation.setFillAfter(true);
ivShowDetail.startAnimation(mRotateAnimation);
break;
default:
break;
}
}
;
};
public Builder(Context context) {
this.context = context;
}
public Builder setTitle(String title) {
this.title = message;
return this;
}
public Builder setNoTitle(boolean noTitle) {
this.noTitle = noTitle;
return this;
}
/**
* Set the Dialog title from resource
*
* @param resId
* @return
*/
public Builder setTitle(int resId) {
this.title = (String) context.getText(resId);
return this;
}
public Builder setMessage(String message) {
this.message = message;
return this;
}
/**
* Set the Dialog message from resource
*
* @param resId
* @return
*/
public Builder setMessage(int resId) {
this.message = (String) context.getText(resId);
return this;
}
public Builder setGroupMemberEntities(List<GroupMemberEntity> groupMemberEntities) {
mGroupMemberEntities = groupMemberEntities;
return this;
}
public Builder setShareContent(ShareContent shareContent) {
this.shareContent = shareContent;
return this;
}
public Builder setOnSendClickListener(OnSendClickListener onSendClickListener) {
mOnSendClickListener = onSendClickListener;
return this;
}
public Builder setOnCancleClickListener(OnCancleClickListener onCancleClickListener) {
mOnCancleClickListener = onCancleClickListener;
return this;
}
public Builder setOnContentClickListener(OnContentClickListener onContentClickListener) {
mOnContentClickListener = onContentClickListener;
return this;
}
public interface OnSendClickListener {
void onSendClick(CommonShareToDialog dialog, String editContent);
}
public interface OnCancleClickListener {
void OnCancleClick(CommonShareToDialog dialog);
}
public interface OnContentClickListener {
void OnContentClick(CommonShareToDialog dialog);
}
public CommonShareToDialog create() {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
final CommonShareToDialog dialog = new CommonShareToDialog(context, R.style.common_dialog);
final View layoutContainer = inflater.inflate(R.layout.dialog_common_share_to, null);
// 标题
TextView tvTitle = (TextView) layoutContainer.findViewById(R.id.textview_title);
// 单个群组成员的详细列表
final RelativeLayout layoutGroupDetail = (RelativeLayout) layoutContainer.findViewById(R.id.layout_group_detail);
final RecyclerView rvGroupDetail = (RecyclerView) layoutContainer.findViewById(R.id.recyclerview_group_detail);
GridLayoutManager GroupDetailManager = new GridLayoutManager(context, 4, GridLayoutManager.VERTICAL, false);
rvGroupDetail.setLayoutManager(GroupDetailManager);
int space = context.getResources().getDimensionPixelSize(R.dimen.seven);
rvGroupDetail.addItemDecoration(new SpaceItemDecoration(space, space));
// 点击展开群成员图标
ivShowDetail = (ImageView) layoutContainer.findViewById(R.id.imageview_arrow_down);
// 头像显示的RecyclerView
RecyclerView rvMemberMultiple = (RecyclerView) layoutContainer.findViewById(R.id.recyclerview_member_multiple);
// 分享内容的布局
final LinearLayout layoutShareContent = (LinearLayout) layoutContainer.findViewById(R.id.layout_share_content);
ImageView ivShareIcon = (ImageView) layoutContainer.findViewById(R.id.imageview_share_icon);
TextView tvShareContent = (TextView) layoutContainer.findViewById(R.id.textview_share_content);
// 编辑输入框
final BottomLineEditText etShareText = (BottomLineEditText) layoutContainer.findViewById(R.id.edittext_share_text);
etShareText.requestFocus(); //获取焦点 光标出现
final TextView tvInputLabel = (TextView) layoutContainer.findViewById(R.id.textview_input_label);
tvInputLabel.setVisibility(View.GONE);
// 操作按钮
TextView tvConfirm = (TextView) layoutContainer.findViewById(R.id.textview_send);
TextView tvCancle = (TextView) layoutContainer.findViewById(R.id.textview_cancel);
if (noTitle) {
if (title != null) {
tvTitle.setText(title);
}
} else {
tvTitle.setVisibility(View.GONE);
}
ivShowDetail.setOnClickListener(new View.OnClickListener() {
DialogGroupMemberAdapter groupAdapter;
@Override
public void onClick(View view) {
ivShowDetail.setFocusable(true);
ivShowDetail.setFocusableInTouchMode(true);
ivShowDetail.requestFocus();
hideSoftKeyboard(etShareText);
isShow = !isShow;
if (isShow) {
mHandler.sendEmptyMessage(0);
layoutGroupDetail.setVisibility(View.VISIBLE);
layoutShareContent.setVisibility(View.GONE);
if (groupAdapter == null) {
groupAdapter = new DialogGroupMemberAdapter(context);
} else {
runLayoutAnimation(rvGroupDetail);
}
List<GroupMemberEntity> entities = new ArrayList<>();
List<String> urlStrs = mGroupMemberEntities.get(0).getImageUrls();
for (String url : urlStrs) {
List<String> strs = new ArrayList<>();
strs.add(url);
GroupMemberEntity entity = new GroupMemberEntity(2, "", strs);
entities.add(entity);
}
groupAdapter.setGroupMemberEntities(entities);
rvGroupDetail.setAdapter(groupAdapter);
} else {
mHandler.sendEmptyMessage(1);
if (groupAdapter != null) {
groupAdapter.setGroupMemberEntities(null);
groupAdapter.notifyDataSetChanged();
}
layoutGroupDetail.setVisibility(View.GONE);
layoutShareContent.setVisibility(View.VISIBLE);
}
}
});
if (mGroupMemberEntities != null) {
ivShowDetail.setVisibility(View.GONE);
layoutGroupDetail.setVisibility(View.GONE);
GridLayoutManager gridLayoutManager;
if (mGroupMemberEntities.size() == 1) {
gridLayoutManager = new GridLayoutManager(context, 1, GridLayoutManager.VERTICAL, false);
GroupMemberEntity groupMemberEntity = mGroupMemberEntities.get(0);
if (groupMemberEntity.getMemeberType() == 3) {// 如果是一个单个的群组,则显示展示图标
ivShowDetail.setVisibility(View.VISIBLE);
}
} else {
gridLayoutManager = new GridLayoutManager(context, 4, GridLayoutManager.VERTICAL, false);
}
if (mGroupMemberAdapter == null) {
mGroupMemberAdapter = new DialogGroupMemberAdapter(context);
}
mGroupMemberAdapter.setGroupMemberEntities(mGroupMemberEntities);
rvMemberMultiple.setLayoutManager(gridLayoutManager);
// int spacing = context.getResources().getDimensionPixelSize(R.dimen.seven_dp);
// rvMemberMultiple.addItemDecoration(new SpaceItemDecoration(spacing, spacing));
rvMemberMultiple.setAdapter(mGroupMemberAdapter);
}
if (shareContent != null) {
tvShareContent.setText(shareContent.getDesc());
ImageLoader.getInstance().displayImage(shareContent.getIconUrl(), ivShareIcon);
}
layoutContainer.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
layoutContainer.setFocusable(true);
layoutContainer.setFocusableInTouchMode(true);
layoutContainer.requestFocus();
hideSoftKeyboard(etShareText);
return false;
}
});
etShareText.setFilters(new InputFilter[]{new InputFilter.LengthFilter(150)});// 在代码里设置输入字数的上限,也可以在xml文件里设置
etShareText.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (TextUtils.isEmpty(s)) {
tvInputLabel.setVisibility(View.GONE);
} else {
if (s.toString().length() >= 150) {
tvInputLabel.setVisibility(View.VISIBLE);
tvInputLabel.setText("最多输入150个字");
}
}
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
// TODO Auto-generated method stub
}
@Override
public void afterTextChanged(Editable s) {
}
});
tvConfirm.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (mOnSendClickListener != null) {
mOnSendClickListener.onSendClick(dialog, etShareText.getText().toString());
}
}
});
tvCancle.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (mOnCancleClickListener != null) {
mOnCancleClickListener.OnCancleClick(dialog);
}
}
});
layoutShareContent.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
layoutShareContent.setFocusable(true);
layoutShareContent.setFocusableInTouchMode(true);
layoutShareContent.requestFocus();
hideSoftKeyboard(etShareText);
if (mOnContentClickListener != null) {
mOnContentClickListener.OnContentClick(dialog);
}
}
});
dialog.setContentView(layoutContainer);
return dialog;
}
/**
* @Author: lzsheng
* @Description: 数据变化的时候触发动画
* @Params: [recyclerView]
* @Return: void
*/
private void runLayoutAnimation(final RecyclerView recyclerView) {
final Context context = recyclerView.getContext();
final LayoutAnimationController controller =
AnimationUtils.loadLayoutAnimation(context, R.anim.layout_animation_fall_down);
recyclerView.setLayoutAnimation(controller);
recyclerView.getAdapter().notifyDataSetChanged();
recyclerView.scheduleLayoutAnimation();
}
private void hideSoftKeyboard(EditText editText) {
InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
boolean isOpen = imm.isActive();
if (isOpen) {
imm.hideSoftInputFromWindow(editText.getWindowToken(), 0);
}
}
}
}
这个自定义对话框类中可能进行更多扩展,视自己的功能需求而定,
与这个Dialog类紧密相关的是DialogGroupMemberAdapter类,那么这个类是用来做什么呢?
public class DialogGroupMemberAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private Context mContext;
private List<GroupMemberEntity> mGroupMemberEntities;
private OnRecyclerViewItemClick onRecyclerViewItemClick;
private NineGridImageViewAdapter<String> mGridImageAdapter;
private final int TYPE_MEMEBER_SINGLE = 1; // 单个成员,显示头像、左边显示名字
private final int TYPE_MEMEBER_MULTIPLE = 2; // 多个成员,只显示头像
private final int TYPE_GROUP_SINGLE = 3; // 单个群组,显示头像、左边显示名字
private final int TYPE_GROUP_MULTIPLE = 4; // 多个群组,只显示头像
private final int TYPE_MEMBER_MULTIPLE_FULL = 5; // 多个成员,显示头像、下边显示名字
public DialogGroupMemberAdapter(Context context) {
this.mContext = context;
mGridImageAdapter = new NineGridImageViewAdapter<String>() {
@Override
protected void onDisplayImage(Context context, ImageView imageView, String s) {
ImageLoader.getInstance().displayImage(s, imageView);
}
@Override
protected ImageView generateImageView(Context context) {
return super.generateImageView(context);
}
};
}
public void setGroupMemberEntities(List<GroupMemberEntity> groupMemberEntities) {
mGroupMemberEntities = groupMemberEntities;
}
public void setOnRecyclerViewItemClick(OnRecyclerViewItemClick onRecyclerViewItemClick) {
this.onRecyclerViewItemClick = onRecyclerViewItemClick;
}
//根据数据的类型memeberType,返回不同的ItemViewType
@Override
public int getItemViewType(int position) {
if (mGroupMemberEntities != null && mGroupMemberEntities.size() > 0) {
int memberType = mGroupMemberEntities.get(position).getMemeberType();
if (memberType == TYPE_MEMEBER_SINGLE) {
return TYPE_MEMEBER_SINGLE;
} else if (memberType == TYPE_MEMEBER_MULTIPLE) {
return TYPE_MEMEBER_MULTIPLE;
} else if (memberType == TYPE_GROUP_SINGLE) {
return TYPE_GROUP_SINGLE;
} else if (memberType == TYPE_GROUP_MULTIPLE) {
return TYPE_GROUP_MULTIPLE;
} else if (memberType == TYPE_MEMBER_MULTIPLE_FULL) {
return TYPE_MEMBER_MULTIPLE_FULL;
}
}
return 0;
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
switch (viewType) {
case TYPE_MEMEBER_SINGLE:
HolderMemeberSingle holderMemeberSingle = new HolderMemeberSingle(
LayoutInflater.from(mContext).inflate(R.layout.item_member_single, parent, false));
return holderMemeberSingle;
case TYPE_MEMEBER_MULTIPLE:
HolderMemeberMultiple holderMemeberMultiple = new HolderMemeberMultiple(
LayoutInflater.from(mContext).inflate(R.layout.item_member_multiple, parent, false));
return holderMemeberMultiple;
case TYPE_GROUP_SINGLE:
HolderGroupSingle holderGroupSingle = new HolderGroupSingle(
LayoutInflater.from(mContext).inflate(R.layout.item_group_single, parent, false));
return holderGroupSingle;
case TYPE_GROUP_MULTIPLE:
HolderGroupMultiple holderGroupMultiple = new HolderGroupMultiple(
LayoutInflater.from(mContext).inflate(R.layout.item_group_multiple, parent, false));
return holderGroupMultiple;
case TYPE_MEMBER_MULTIPLE_FULL:
HolderMemberMultipleFull holderMemberMultipleFull = new HolderMemberMultipleFull(
LayoutInflater.from(mContext).inflate(R.layout.item_member_multiple_full, parent, false));
return holderMemberMultipleFull;
default:
return null;
}
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
if (mGroupMemberEntities != null) {
GroupMemberEntity groupMemberEntity = mGroupMemberEntities.get(position);
int memberType = groupMemberEntity.getMemeberType();
switch (memberType) {
case TYPE_MEMEBER_SINGLE:
ImageLoader.getInstance().displayImage(groupMemberEntity.getImageUrls().get(0), ((HolderMemeberSingle) holder).ivMemberPic);
((HolderMemeberSingle) holder).tvName.setText(groupMemberEntity.getName());
break;
case TYPE_MEMEBER_MULTIPLE:
ImageLoader.getInstance().displayImage(groupMemberEntity.getImageUrls().get(0), ((HolderMemeberMultiple) holder).ivMemberPic);
break;
case TYPE_GROUP_SINGLE:
((HolderGroupSingle) holder).ivMemberPic.setAdapter(mGridImageAdapter);
((HolderGroupSingle) holder).ivMemberPic.setImagesData(groupMemberEntity.getImageUrls());
((HolderGroupSingle) holder).tvName.setText(groupMemberEntity.getName());
break;
case TYPE_GROUP_MULTIPLE:
((HolderGroupMultiple) holder).ivMemberPic.setAdapter(mGridImageAdapter);
((HolderGroupMultiple) holder).ivMemberPic.setImagesData(groupMemberEntity.getImageUrls());
break;
case TYPE_MEMBER_MULTIPLE_FULL:
ImageLoader.getInstance().displayImage(groupMemberEntity.getImageUrls().get(0), ((HolderMemberMultipleFull) holder).ivMemberPic);
((HolderMemberMultipleFull) holder).tvName.setText(groupMemberEntity.getName());
break;
default:
break;
}
}
}
@Override
public int getItemCount() {
if (mGroupMemberEntities != null && mGroupMemberEntities.size() > 0) {
return mGroupMemberEntities.size();
}
return 0;
}
class HolderMemeberSingle extends RecyclerView.ViewHolder implements View.OnClickListener {
ImageView ivMemberPic;
TextView tvName;
public HolderMemeberSingle(View itemView) {
super(itemView);
ivMemberPic = (ImageView) itemView.findViewById(R.id.imageview_pic_member_single);
tvName = (TextView) itemView.findViewById(R.id.textview_name_single);
itemView.setOnClickListener(this);
}
@Override
public void onClick(View view) {
if (onRecyclerViewItemClick != null) {
onRecyclerViewItemClick.onItemClick(view, getAdapterPosition());
}
}
}
class HolderMemeberMultiple extends RecyclerView.ViewHolder implements View.OnClickListener {
ImageView ivMemberPic;
public HolderMemeberMultiple(View itemView) {
super(itemView);
ivMemberPic = (ImageView) itemView.findViewById(R.id.imageview_pic_member_multiple);
itemView.setOnClickListener(this);
}
@Override
public void onClick(View view) {
if (onRecyclerViewItemClick != null) {
onRecyclerViewItemClick.onItemClick(view, getAdapterPosition());
}
}
}
class HolderGroupSingle extends RecyclerView.ViewHolder implements View.OnClickListener {
NineGridImageView ivMemberPic;
TextView tvName;
public HolderGroupSingle(View itemView) {
super(itemView);
ivMemberPic = (NineGridImageView) itemView.findViewById(R.id.imageview_pic_group_single);
tvName = (TextView) itemView.findViewById(R.id.textview_name_group_single);
itemView.setOnClickListener(this);
}
@Override
public void onClick(View view) {
if (onRecyclerViewItemClick != null) {
onRecyclerViewItemClick.onItemClick(view, getAdapterPosition());
}
}
}
class HolderGroupMultiple extends RecyclerView.ViewHolder implements View.OnClickListener {
NineGridImageView ivMemberPic;
public HolderGroupMultiple(View itemView) {
super(itemView);
ivMemberPic = (NineGridImageView) itemView.findViewById(R.id.imageview_pic_group_multiple);
itemView.setOnClickListener(this);
}
@Override
public void onClick(View view) {
if (onRecyclerViewItemClick != null) {
onRecyclerViewItemClick.onItemClick(view, getAdapterPosition());
}
}
}
class HolderMemberMultipleFull extends RecyclerView.ViewHolder implements View.OnClickListener {
ImageView ivMemberPic;
TextView tvName;
public HolderMemberMultipleFull(View itemView) {
super(itemView);
ivMemberPic = (ImageView) itemView.findViewById(R.id.imageview_pic_member_full);
tvName = (TextView) itemView.findViewById(R.id.textview_name_full);
itemView.setOnClickListener(this);
}
@Override
public void onClick(View view) {
if (onRecyclerViewItemClick != null) {
onRecyclerViewItemClick.onItemClick(view, getAdapterPosition());
}
}
}
/**
* item点击接口
*/
public interface OnRecyclerViewItemClick {
void onItemClick(View view, int position);
}
}
这个代码逻辑还是比较清晰的,我们能看到这个类就是用来展示不同的群组或者个人的布局样式的。
这个Dioalog类中有一个重要的实体类(GroupMemberEntity)集合, 所有的群组和成员的数据都由外部通过这个集合注入
public class GroupMemberEntity implements Serializable {
private int memeberType;
/**
*
*/
private String name;
/**
*
*/
private List<String> imageUrls;
public GroupMemberEntity(int memeberType, String name, List<String> imageUrls) {
this.memeberType = memeberType;
this.name = name;
this.imageUrls = imageUrls;
}
public int getMemeberType() {
return memeberType;
}
public void setMemeberType(int memeberType) {
this.memeberType = memeberType;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<String> getImageUrls() {
return imageUrls;
}
public void setImageUrls(List<String> imageUrls) {
this.imageUrls = imageUrls;
}
@Override
public String toString() {
return "GroupMemberEntity{" +
"memeberType=" + memeberType +
", name='" + name + '\'' +
", imageUrls=" + imageUrls +
'}';
}
}
这个类中的 memeberType 属性用来区分不同的数据格式,这个和 DialogGroupMemberAdapter 类中的 ItemViewType 类型是一致的,不同的数据设置不同的格式,在适配器中进行区分并展示,这样不管外部是什么样的数据需要展示,只需要将它们转换成我们定义的这个类型数据,就可以轻松展示出来我们想要的效果。
使用简单示例:展示单个群组的情况:
mBtnShareSingleGroup.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
List<GroupMemberEntity> groupMemberEntities = new ArrayList<>();
List<String> picUrls = new ArrayList<>();
for (int i = 0; i < 8; i++) {
picUrls.add("drawable://" + R.drawable.icon_user);
}
GroupMemberEntity memberEntity = new GroupMemberEntity(3, "幸福一家人", picUrls);
groupMemberEntities.add(memberEntity);
ShareContent shareContent = new ShareContent("百万英雄赢百万,终极一问,脱离贫困,快来参与答题吧!", "http://app.toutiao.com/news_article/#news_article", "drawable://" + R.drawable.icon_share);
if (mShareDialogSingleGroup == null) {
mShareDialogSingleGroup = new CommonShareToDialog.Builder(MainActivity.this)
.setTitle("发送给:")
.setGroupMemberEntities(groupMemberEntities)
.setShareContent(shareContent)
.setOnSendClickListener(new CommonShareToDialog.Builder.OnSendClickListener() {
@Override
public void onSendClick(CommonShareToDialog dialog, String editContent) {
Toast.makeText(MainActivity.this, "已分享", Toast.LENGTH_SHORT).show();
dialog.dismiss();
}
})
.setOnContentClickListener(new CommonShareToDialog.Builder.OnContentClickListener() {
@Override
public void OnContentClick(CommonShareToDialog dialog) {
// todo startActivity(intent);跳转页面
}
})
.setOnCancleClickListener(new CommonShareToDialog.Builder.OnCancleClickListener() {
@Override
public void OnCancleClick(CommonShareToDialog dialog) {
dialog.dismiss();
}
}).create();
Window window = mShareDialogSingleGroup.getWindow();
window.setGravity(Gravity.CENTER);
window.setWindowAnimations(R.style.CenterDialog_Animation);
window.getDecorView().setPadding(0, 0, 0, 0);
WindowManager.LayoutParams lp = window.getAttributes();
// lp.width = WindowManager.LayoutParams.MATCH_PARENT;// 设置宽度为全屏
lp.width = (int) (getResources().getDisplayMetrics().widthPixels * 0.75);
lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
window.setAttributes(lp);
mShareDialogSingleGroup.setCanceledOnTouchOutside(true);
}
if (mShareDialogSingleGroup != null && !mShareDialogSingleGroup.isShowing()) {
mShareDialogSingleGroup.show();
}
}
});
由于作者水平有限,语言描述及代码实现中难免有纰漏,望各位看官多提宝贵意见!
Hello , World !
感谢所有!