前言
通常在社交類型的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 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 imageList = data.getParcelableArrayListExtra(FilePicker.RESULT_PICK_IMAGE);
commentZBSP.setImages(imageList);
}
break;
}
}
3.常用方法
方法名
描述
delegation(Context context)
建立方法
show(String hint)
彈出評論框并填寫評論的hint
dismiss()
隐藏評論彈出框,并隐藏軟鍵盤
setImages(ArrayList 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
否則會導緻顯示不全
問題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);
}
總結
在開發過程中很多開源的東西有時候不一定滿足我們目前的業務,本控件部分内容前參考了很多人的實作方法然後進行的自定義。
在開源的過程中盡量保證代碼的規範以及可讀性,便于讀者了解。
歡迎大家指點批評~