Android开源框架CommentBottomBar底部评论弹
前言
通常在社交类型的APP上都会有这么一个需求,就是评论的时候通常要带有文字或者是文字+图片。针对这一需求设计了一款相关的控件CommentBottomBar。项目已发布Github,欢迎Star!
Github地址:https://github.com/EverZc/CommentBottomBar
目录
- 效果图
- 使用步骤
- 常用方法
- 实现原理
1.效果图
效果示例2.使用步骤
Step 1.添加依赖CommentBottomBar
首先要在项目的根build.gradle
下添加:
allprojects {
repositories {
maven { url "https://jitpack.io" }
}
}
然后要在要依赖的module中添加
dependencies {
implementation 'com.github.EverZc:CommentBottomBar:latest.release.here'
}
Step 2.使用流程
CommentBottomBar使用起来非常简单
//第一步:在需要评论的地方初始化控件
ZBottomSheetPictureBar commentZBSP = ZBottomSheetPictureBar.delegation(MainActivity.this);
//第二步:弹出底部评论栏,并设置EditText的hint
commentZBSP.show("期待您的神回复");
//第三步:设置控件内的点击回调(添加图片以及提交按钮)
commentZBSP.setOnSeetBarOnClickListener(new ZBottomSheetPictureBar.OnSheetBarOnClickListener() {
@Override
public void onAddClick() {
Intent intent = new Intent(MainActivity.this, ImagePickActivityPicker.class);
intent.putExtra(IS_NEED_CAMERA, true);
int maxNumber = commentZBSP.getAdapterData().isEmpty() ?
ZBottomConstant.ARTICLE_IMAGE_MAX : ZBottomConstant.ARTICLE_IMAGE_MAX - commentZBSP.getAdapterData().size();
intent.putExtra(FilePicker.MAX_NUMBER, maxNumber);
startActivityForResult(intent, ZBottomConstant.REQUEST_CODE_PICK_IMAGE);
}
@Override
public void onCommitClick(ArrayList<ImageFile> images, EditText editText) {
//此处是点击按钮,具体处理提交评论的文字以及图片
}
});
//第四步:处理选择的图片,设置到弹窗控件中。
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case ZBottomConstant.REQUEST_CODE_PICK_IMAGE:
//获取选择的图片
if (resultCode == RESULT_OK) {
ArrayList<ImageFile> imageList = data.getParcelableArrayListExtra(FilePicker.RESULT_PICK_IMAGE);
commentZBSP.setImages(imageList);
}
break;
}
}
3.常用方法
方法名 | 描述 |
---|---|
delegation(Context context) | 创建方法 |
show(String hint) | 弹出评论框并填写评论的hint |
dismiss() | 隐藏评论弹出框,并隐藏软键盘 |
setImages(ArrayList<ImageFile> images) | 添加图片 |
getAdapterData() | 获取当前评论框内的图片 |
getAdapter() | 获取弹出框图片的adapter |
getCommentText() | 获取评论的内容 |
clear() | 清理评论文本内容以及评论的图片内容 |
4.实现原理
ZBottomDialog说明
本底部评论弹窗自定义的ZBottomDialog采用Material Design的BottomSheetBehavior作为底部弹出框
首先简单了解一下使用到的相关内容。
对于BottomSheetBehavior弹出包含五种状态:
- STATE_COLLAPSED:折叠状态,bottom sheets只在底部显示一部分布局。显示高度可以通过 app:behavior_peekHeight 设置(本框架未设置);
- STATE_DRAGGING:过渡状态,此时用户正在向上或者向下拖动bottom sheet;
- STATE_SETTLING: 视图从脱离手指自由滑动到最终停下的这一小段时间
- STATE_EXPANDED: 完全展开的状态
- STATE_HIDDEN: 隐藏状态。默认是false,可通过app:behavior_hideable属性设置是否能隐藏
为什么要重写BottomSheetDialog相关方法?
如果直接使用BottomSheetDialog会出现2个问题
- 初始化BottomSheetDialog后,在界面上只显示了评论文字,而评论下边的图片内容的RecyclerView部分需要单独上拉才能出现
- 在下滑了评论以及评论图片后,控件的view隐藏了,但是软键盘没有隐藏,整个dialog没有关闭。
问题1解决:需要设置当前dialog的style如下:
android:windowIsFloating必须为false
android:windowSoftInputMode为adjustResize
否则会导致显示不全
<style name="bottomSheetEdit" parent="Theme.Design.Light.BottomSheetDialog"> <item name="android:windowIsFloating">false</item> <item name="android:statusBarColor">@android:color/transparent</item> <item name="android:windowSoftInputMode">adjustResize</item></style>
问题2解决:
首先需要获取到BottomSheetBehavior然后设置对BottomSheetBehavior.BottomSheetCallback()中的onStateChanged方法进行单独操作,当此时状态newState未BottomSheetBehavior.STATE_HIDDEN时,也就是进入了隐藏状态,执行BottomSheetDialog的dismiss()方法即可。
完整代码如下
public class ZBottomDialog extends BottomSheetDialog {
private BottomSheetBehavior behavior;
public ZBottomDialog(@NonNull Context context) {
super(context, R.style.bottomSheetEdit);
}
@Override
public void setContentView(View view) {
super.setContentView(view);
initialize(view);
}
private void initialize(final View view) {
ViewGroup parent = (ViewGroup) view.getParent();
CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) parent.getLayoutParams();
behavior = (BottomSheetBehavior) params.getBehavior();
behavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
@Override
public void onStateChanged(@NonNull View bottomSheet, int newState) {
if (newState == BottomSheetBehavior.STATE_HIDDEN) {
dismiss();
}
}
@Override
public void onSlide(@NonNull View bottomSheet, float slideOffset) {
}
});
}
}
ZBottomSheetAdapter解释说明
本适配器的主要功能是用于底部评论弹窗的图片recyclerview的adapter
该adapter有两种ItemViewType(0:添加图片,1:查看图片)
//对外暴露的监听方法,具体方法见adapter的holder
public void setOnReleaseImageListener(ZBottomSheetHolder.OnReleaseImageListener onReleaseImageListener) {
this.onReleaseImageListener = onReleaseImageListener;
}
public interface OnReleaseImageListener {
//添加图片的点击事件
void onAddClick();
//删除图片的点击事件
void onDelClick(ImageFile imageFile, int position);
//已经添加的图片点击事件(常用语在底部评论框中点击已经添加的图片大图显示)
void onClick(int positon);
}
ZBottomSheetAdapter Holder说明
本控件设计之初adapter使用GridLayoutManager spanCount=3,并且具体某个item采用正方形的设计,故需要在holder中进行特殊处理
处理方式:
构造函数中获取到当前item的宽,在加载图片时使用glide对当前图片加载的宽高进行处理
//获取到当前item的宽,用于将该item设置为正方形
private int getItemWidth(){
WindowManager windowManager = (WindowManager) mContext
.getSystemService(Context.WINDOW_SERVICE);
return windowManager.getDefaultDisplay().getWidth();
}
该holder中的监听方法接口内容:
public interface OnReleaseImageListener {
//添加图片的点击事件
void onAddClick();
//删除图片的点击事件
void onDelClick(ImageFile imageFile, int position);
//已经添加的图片点击事件(常用语在底部评论框中点击已经添加的图片大图显示)
void onClick(int positon);
}
//当前item加载数据,并且glide对图片样式进行处理
public void setData(ImageFile imageFile) {
mImageFile = imageFile;
Glide.with(mContext)
.load(imageFile.getPath())
.diskCacheStrategy(DiskCacheStrategy.RESULT)
.override(mWidth, mWidth)//这里的单位是px
.into(mCoverView);
}
总结
在开发过程中很多开源的东西有时候不一定满足我们当前的业务,本控件部分内容前参考了很多人的实现方法然后进行的自定义。
在开源的过程中尽量保证代码的规范以及可读性,便于读者理解。
欢迎大家指点批评~