BottomSheetDialogFragment仿制抖音评论框

没有效果图的示例简直就是扯淡

在这里插入图片描述

BottomSheetDialogFragment

BottomSheetDialogFragment 继承自 AppCompatDialogFragment,官方解释为模态底部表,是 DialogFragment 的一个版本,它使用的是 BottomSheetDialog,而不是浮动对话框。BottomSheetDialogFragment 相对于其它对话框有着以下的优势:

  1. 拥有自己的生命周期;
  2. 可对整个页面进行折叠、展开和销毁;
  3. 可灵活使用自定义样式。

直接上代码吧

CommentBottomSheetDialogFragment.java

/**
 * 评论框
 */
public class CommentBottomSheetDialogFragment extends BottomSheetDialogFragment implements View.OnClickListener {

    //数据
    private List<CommentsInfo> commentsInfos = new ArrayList<>();

    //adapter
    private VideoShowCommentAdapter commentAdapter;

    //recyclerView
    RecyclerView mLvComment;

    //总评论数
    TextView mTvDialogCommentCount;

    //行为组件BottomSheetBehavior
    BottomSheetBehavior<ViewGroup> behavior;

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //禁止dialog不被软键盘弹起来
        setStyle(DialogFragment.STYLE_NORMAL, android.R.style.Theme_Black_NoTitleBar_Fullscreen);
    }

    @NonNull
    @Override
    public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
        //因为BottomSheetDialog默认的样式背景带阴影的,如果需要定制的话,第一步如下
        //设置BottomSheetDialog整体样式为透明的
        setStyle(BottomSheetDialogFragment.STYLE_NORMAL, R.style.TransBottomSheetDialogStyle);
        //创建布局
        Dialog dialog = super.onCreateDialog(savedInstanceState);
        View view = LayoutInflater.from(getContext()).inflate(R.layout.video_show_comment_layout, null, false);
        mLvComment = view.findViewById(R.id.lv_video_show_comment);
        mTvDialogCommentCount = view.findViewById(R.id.tv_video_show_comment_dialog_comment);

        //点击事件
        view.findViewById(R.id.tv_close_comment_dialog).setOnClickListener(v -> dismiss());
        view.findViewById(R.id.txt_video_comment).setOnClickListener(this);

        //点击外部可以关闭
        dialog.setCanceledOnTouchOutside(true);
        dialog.setContentView(view);
        //BottomSheetDialog的背景是白色的。如果需要修改,setContentView之后,设置view布局的样式为透明,然后在布局中设置背景就好
        ((View) view.getParent()).setBackgroundColor(getResources().getColor(android.R.color.transparent));

        //设置宽度为屏幕的一半
        ViewGroup parent = (ViewGroup) view.getParent();
        behavior = BottomSheetBehavior.from(parent);
        behavior.setPeekHeight(getScreenHeight(getActivity()) / 3 * 2);

        //向下滑动可隐藏
        behavior.setHideable(true);

        //这里设置宽度最高为屏幕的一半,如果不设置下面代码,上滑会直接充满全屏幕
        ViewGroup.LayoutParams layoutParams = parent.getLayoutParams();
        layoutParams.height = getScreenHeight(getActivity()) / 3 * 2;
        parent.setLayoutParams(layoutParams);

        //初始化数据
        initData();

        //返回界面
        return dialog;
    }

    /**
     * 加载逻辑处理
     */
    private void initData() {
        //构建评论适配器
        commentAdapter = new VideoShowCommentAdapter(getContext());
        mLvComment.setLayoutManager(new LinearLayoutManager(getContext()));
        mLvComment.setAdapter(commentAdapter);
        //评论item的点击事件
        commentAdapter.setListener(position -> Toast.makeText(getActivity(), "点击了", Toast.LENGTH_SHORT).show());

        //如果数据不是空
        if (commentsInfos != null && commentsInfos.size() > 0) {
            mTvDialogCommentCount.setText(new StringBuilder().append(commentsInfos.size()).append(" ").append(getActivity().getString(R.string.string_comment)));
        } else {
            mTvDialogCommentCount.setText(new StringBuilder("0 ").append(getString(R.string.string_comment)));
        }
        //赋值给adapter
        commentAdapter.setCommentsInfos(commentsInfos);
    }

    /**
     * 接收接口传递过来的数据
     * @param infos
     */
    public void setDatas(List<CommentsInfo> infos) {
        commentsInfos = infos;
        //刷新
        if(null != commentAdapter){
            //数据给到适配器那边,刷新显示
            commentAdapter.setCommentsInfos(commentsInfos);
            commentAdapter.notifyDataSetChanged();
        }
    }
    
    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.txt_video_comment:
                OtherDialog.showVideoCommentDialog(getActivity(), text -> {
                    //手动处理数据长度+1。达到静默加载效果
                    setCount(true);
                    //拿到评论的内容,返回给activity处理
                    onGetContentListener.onGetContent(text);
                });
                break;
        }
    }

    /**
     * 设置具体有多少数据
     * @param isChange  如果为true,说明评论了,直接+1    如果为false时,说明新发的评论调用接口失败了(请调用此接口,传false),还是使用原数据源
     */
    public void setCount(boolean isChange) {
        mTvDialogCommentCount.setText(isChange ?
                new StringBuilder().append(commentsInfos.size() + 1)
                        .append(" ")
                        .append(getActivity().getString(R.string.string_comment))
                :
                new StringBuilder().append(commentsInfos.size())
                        .append(" ")
                        .append(getActivity().getString(R.string.string_comment))
        );
    }

    /**
     * 获取屏幕高度
     * @param activity
     * @return
     */
    public int getScreenHeight(Context activity) {
        return getScreenSize(activity).y;
    }

    /**
     * 获取屏幕高度
     * @param activity
     * @return
     */
    private Point getScreenSize(Context activity) {
        Display display = ((Activity)activity).getWindowManager().getDefaultDisplay();
        Point size = new Point();
        display.getSize(size);
        return size;
    }

    //点击事件
    public interface OnGetContentListener {
        void onGetContent(String content);
    }
    private OnGetContentListener onGetContentListener;
    public void setGetContentListener(OnGetContentListener onGetContentListener) {
        this.onGetContentListener = onGetContentListener;
    }

}
注:这个是评论框的显示的界面

OtherDialog.java

public class OtherDialog {

    /**
     * 视频秀评论弹框
     * @param context 上下文
     */
    public static void showVideoCommentDialog(Context context, OnGetContentListener listener){
        Dialog dialog = new Dialog(context, R.style.video_comment_style);
        //对话框的布局
        View view = LayoutInflater.from(context)
                .inflate(R.layout.dialog_video_comment_layout, null);
        //评论输入框
        PPEditTextView mInputContent = view.findViewById(R.id.et_input_comment);
        //键盘销毁时,dialog关闭
        mInputContent.setOnBackKeyEventListener(() -> {
            new Handler().postDelayed(() -> dialog.dismiss(), 200);
            return true;
        });
        //发送事件
        view.findViewById(R.id.tv_send_comment).setOnClickListener(v -> {
            String commentContent = mInputContent.getText().toString().trim();
            if(TextUtils.isEmpty(commentContent)){
                Toast.makeText(context, "评论内容不能为空", Toast.LENGTH_SHORT).show();
            }else{
                if(listener != null){
                    listener.onText(commentContent);
                }
                dialog.dismiss();
                //输入框置空
                mInputContent.setText("");
            }
        });

        //获取焦点
        mInputContent.setFocusable(true);
        mInputContent.setFocusableInTouchMode(true);
        mInputContent.requestFocus();

        //将布局设置给dialog
        dialog.setContentView(view);
        dialog.setCanceledOnTouchOutside(true);

        //获取当前Activity所在的窗体
        Window dialogWindow = dialog.getWindow();
        //设置窗体的属性
        WindowManager.LayoutParams lp = dialogWindow.getAttributes();
        lp.width = WindowManager.LayoutParams.MATCH_PARENT;
        //设置dialog从中间弹出
        dialogWindow.setGravity(Gravity.BOTTOM);
        //将属性给窗体
        dialogWindow.setAttributes(lp);
        //返回对话框
        dialog.show();
    }

}
注:这个是发表评论的dialog框,里面用到了自定义的EditText。用来监听软键盘的显示隐藏

附上demo源码。

源码:源码请点这里

如果下不了源码,可以加微信,手机号在下面。


Q:486789970(QQ现在很少用)
V:18588400509(如果着急,可以直接加微信)
email:mr.cai_cai@foxmail.com

如果有什么问题,欢迎大家指导。并相互联系,希望能够通过文章互相学习。

											                               	---财财亲笔
  • 2
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

谁抢我的小口口

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值