当前位置: 首页 > ai >正文

关于安卓dialogFragment中,EditText无法删除文字的问题

在这里插入图片描述

背景:

在安卓开发中,使用DialogFragment进行i页面开发,其中有一个EditText,发现可以输入文字,但是无法删除文字

开发环境

win11
jdk11
as

现状与思考

网上回答现状:这个几乎是有点违背常理的,从网上的已有的答案查询,无外乎就是一些说是EditText的焦点问题,一些又说是DialogFragment样式为浮窗的问题,总结一个大类,就是EditText丢失焦点,导致无法删除。

思考:那么,丢了焦点,为什么能够拉起键盘?请回答我?所以如果能拉起键盘,而且能输入,就大概率不是丢了焦点,这是常识性问题。

再延续思考,不是丢焦点,那就是“不响应删除事件”的问题了。

那么响应事件,有两种可能:
(1)父类拦截了删除事件??
(2)EditText类屏蔽了删除事件??
(3)DialogFragment屏蔽了删除事件??

对于(1)和(2),对布局文件进行检查即可。
对于(3),则检查一下DialogFragment中,Dialog有没有重写setOnKeyListener。

通过上述思路,博主是因为下面代码,导致DialogFragment无法删除EditText文字的

            mDialog.setOnKeyListener(new DialogInterface.OnKeyListener() {@Overridepublic boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {return !mCancelable;if (keyCode == KeyEvent.KEYCODE_BACK) {return !cancelable();}return false;}});

下面放出完整的基类DialogFragment/BottomSheetDialogFragment

BaseDialogFragment类


public abstract class BaseDialogFragment extends DialogFragment {private int DEFAULT_WIDTH = WindowManager.LayoutParams.MATCH_PARENT;//宽private int DEFAULT_HEIGHT = WindowManager.LayoutParams.MATCH_PARENT;//高private int DEFAULT_GRAVITY = Gravity.BOTTOM;//位置//外部设置能否取消点击private boolean mCancelable = true;private BaseDialogFragmentLifeListener mListener;private boolean hadShowTAG = false;public BaseDialogFragment() {}public BaseDialogFragment(BaseDialogFragmentLifeListener listener) {this.mListener = listener;}protected BaseDialogFragmentLifeListener getListener() {return mListener;}@Overridepublic void onResume() {super.onResume();if (!hadShowTAG) {hadShowTAG = true;firstShow();}}@Overridepublic void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);if (immerseStyle()) {setStyle(DialogFragment.STYLE_NORMAL, R.style.DialogFragmentImmerse);}}@Nullable@Overridepublic View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {View mView = inflater.inflate(getLayoutId(), container, false);initViews(mView);if (this.mListener != null) {this.mListener.show();}return mView;}@Overridepublic void onDestroyView() {if (this.mListener != null) {this.mListener.dismiss();}this.mListener = null;releaseResource();super.onDestroyView();}@NonNull@Overridepublic Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {mCancelable = cancelable();Dialog mDialog = super.onCreateDialog(savedInstanceState);if (null != mDialog) {//初始化mDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);mDialog.setCanceledOnTouchOutside(canceledOnTouchOutside());mDialog.setCancelable(mCancelable);Window window = mDialog.getWindow();if (null != window) {window.getDecorView().setPadding(0, 0, 0, 0);window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));window.getDecorView().clearFocus();WindowManager.LayoutParams lp = window.getAttributes();lp.width = defWidth();lp.height = defHeight();lp.gravity = DEFAULT_GRAVITY;lp.windowAnimations = android.R.style.Animation_InputMethod;window.setAttributes(lp);window.setDimAmount(dimAmount());}mDialog.setOnKeyListener(new DialogInterface.OnKeyListener() {@Overridepublic boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {if (keyCode == KeyEvent.KEYCODE_BACK) {return !cancelable();}return false;}});}return mDialog;}@Overridepublic void onStart() {super.onStart();initImmerseSystemBar();}@Overridepublic void onDismiss(@NonNull DialogInterface dialog) {super.onDismiss(dialog);dismissDialog();}protected void setCancelAble(boolean cancelAble) {mCancelable = cancelAble;Dialog dialog = getDialog();if (dialog != null) {dialog.setCancelable(mCancelable);dialog.setCanceledOnTouchOutside(mCancelable);}}/*** 主线程执行*/protected void runInUI(Runnable runnable) {if (runnable == null || getActivity() == null) {return;}getActivity().runOnUiThread(runnable);}@Overridepublic void dismiss() {super.dismiss();dismissDialog();}@Deprecatedprotected void dismissDialog() {}protected float dimAmount() {return 0.6f;}protected int defWidth() {return DEFAULT_WIDTH;}protected int defHeight() {return DEFAULT_HEIGHT;}/*** 设置位置** @param gravity*/public void setGravity(int gravity) {DEFAULT_GRAVITY = gravity;}/*** 设置宽** @param width*/public void setWidth(int width) {DEFAULT_WIDTH = width;}/*** 设置高** @param height*/public void setHeight(int height) {DEFAULT_HEIGHT = height;}/*** 设置点击返回按钮是否可取消*/public boolean cancelable() {return true;}/*** 设置点击外部是否可取消*/public boolean canceledOnTouchOutside() {return true;}/*** 设置布局** @return*/protected abstract int getLayoutId();/*** 初始化Views** @param v*/protected abstract void initViews(@NonNull View v);//全屏相关------------------------------------------------------------------/*** 沉浸样式*/protected boolean immerseStyle() {return false;}/*** 全屏状态下,底部导航栏颜色*/protected int immerseNavigationBarColor() {return Color.WHITE;}protected int immerseStatusBarColor() {return Color.WHITE;}private void initImmerseSystemBar() {if (immerseStyle()) {Window window = getDialog() != null ? getDialog().getWindow() : null;if (window != null) {// 设置导航栏颜色window.setNavigationBarColor(immerseNavigationBarColor());window.setStatusBarColor(immerseStatusBarColor());// 设置导航栏图标颜色为深色(适用于浅色背景)if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {View decorView = window.getDecorView();int flags = decorView.getSystemUiVisibility();flags |= View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR;decorView.setSystemUiVisibility(flags);}}}}//rxjava release----------------------------private CompositeDisposable mDisposables = new CompositeDisposable();private void addObserver(DisposableObserver<?> disposableObserver) {mDisposables.add(disposableObserver);}private void removeObserver(DisposableObserver<?> disposableObserver) {if (mDisposables == null || disposableObserver == null) {return;}mDisposables.remove(disposableObserver);}private void clearObserver() {if (mDisposables != null) {mDisposables.clear();}}public abstract class BaseSafeObserver<T> extends DisposableObserver<T> {@Overrideprotected void onStart() {super.onStart();addObserver(this);}@Overridepublic void onNext(@NonNull T t) {}@Overridepublic void onError(@NonNull Throwable e) {removeObserver(this);}@Overridepublic void onComplete() {removeObserver(this);}}public void releaseResource() {clearObserver();}public <T> void addRequest(Flowable<T> flowable, final OnResultListener<T> onResultListener) {Disposable disposable = flowable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Consumer<T>() {@Overridepublic void accept(T t) throws Exception {onResultListener.onResult(t);onResultListener.onFinish();}}, new Consumer<Throwable>() {@Overridepublic void accept(Throwable throwable) {throwable.printStackTrace();onResultListener.onError(throwable);onResultListener.onFinish();}});mDisposables.add(disposable);}public interface OnResultListener<T> {void onResult(T t);void onError(Throwable t);void onFinish();}//rxjava release----------------------------protected void firstShow() {}
}

BaseBottomDialogFragment类


public abstract class BaseBottomDialogFragment extends BottomSheetDialogFragment {private int DEFAULT_WIDTH = WindowManager.LayoutParams.MATCH_PARENT;//宽private int DEFAULT_HEIGHT = WindowManager.LayoutParams.MATCH_PARENT;//高private int DEFAULT_GRAVITY = Gravity.BOTTOM;//位置private boolean hadShowTAG = false;private BottomSheetBehavior<FrameLayout> bottomSheetBehavior;private BaseDialogFragmentLifeListener mListener;public BaseBottomDialogFragment() {}public BaseBottomDialogFragment(BaseDialogFragmentLifeListener listener) {this.mListener = listener;}@Overridepublic void onResume() {super.onResume();if (!hadShowTAG) {hadShowTAG = true;firstShow();}}protected BaseDialogFragmentLifeListener getListener() {return mListener;}@Overridepublic void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);if (fullScreenStyle()) {setStyle(DialogFragment.STYLE_NORMAL, R.style.DialogFragmentImmerse);}}@Nullable@Overridepublic View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {View mView = inflater.inflate(getLayoutId(), container, false);if (getDialog() != null && getDialog().getWindow() != null) {getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING);}initViews(mView);if (this.mListener != null) {this.mListener.show();}return mView;}@Overridepublic void onDestroyView() {if (this.mListener != null) {this.mListener.dismiss();}this.mListener = null;releaseResource();super.onDestroyView();}@NonNull@Overridepublic Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {BottomSheetDialog mDialog = (BottomSheetDialog) super.onCreateDialog(savedInstanceState);if (null != mDialog) {//初始化mDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);mDialog.setCanceledOnTouchOutside(canceledOnTouchOutside());mDialog.setCancelable(cancelable());Window window = mDialog.getWindow();if (null != window) {window.getDecorView().setPadding(0, 0, 0, 0);window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));WindowManager.LayoutParams lp = window.getAttributes();lp.width = defWidth();lp.height = defHeight();lp.gravity = DEFAULT_GRAVITY;lp.windowAnimations = android.R.style.Animation_InputMethod;window.setAttributes(lp);window.setDimAmount(dimAmount());}mDialog.setOnKeyListener(new DialogInterface.OnKeyListener() {@Overridepublic boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {if (keyCode == KeyEvent.KEYCODE_BACK) {return !cancelable();}return false;}});}return mDialog;}@Overridepublic void onStart() {super.onStart();initSlide();initImmerseSystemBar();}@Overridepublic void onDismiss(@NonNull DialogInterface dialog) {super.onDismiss(dialog);dismissDialog();LogUtils.d("bottom sheet dialog fragment: onDismiss");}/*** 主线程执行*/protected void runInUI(Runnable runnable) {if (runnable == null || getActivity() == null) {return;}getActivity().runOnUiThread(runnable);}/*** 初始化滑动交互*/private void initSlide() {try {if (getDialog() != null && getDialog() instanceof BottomSheetDialog) {int peekHeight = getPeekHeight();BottomSheetDialog dialog = (BottomSheetDialog) getDialog();//把windows的默认背景颜色去掉,不然圆角显示不见dialog.getWindow().findViewById(R.id.design_bottom_sheet).setBackground(new ColorDrawable(Color.TRANSPARENT));//获取dialog的根部局FrameLayout bottomSheet = dialog.getDelegate().findViewById(R.id.design_bottom_sheet);//获取根部局的LayoutParams对象CoordinatorLayout.LayoutParams layoutParams = (CoordinatorLayout.LayoutParams) bottomSheet.getLayoutParams();layoutParams.height = peekHeight;//修改弹窗的最大高度,不允许上滑(默认可以上滑)bottomSheet.setLayoutParams(layoutParams);bottomSheetBehavior = BottomSheetBehavior.from(bottomSheet);//peekHeight即弹窗的最大高度bottomSheetBehavior.setPeekHeight(peekHeight);//初始为展开状态bottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);//能否滑动的时候隐藏bottomSheetBehavior.setHideable(hideAble());}} catch (Exception e) {e.printStackTrace();}}@Overridepublic void dismiss() {super.dismiss();dismissDialog();LogUtils.d("bottom sheet dialog fragment: dismiss");}@Deprecatedprotected void dismissDialog() {}@Overridepublic void show(@NonNull FragmentManager manager, @Nullable String tag) {super.show(manager, tag);}/*** 弹窗高度* 子类可重写该方法返回peekHeight** @return height*/protected int getPeekHeight() {return getResources().getDisplayMetrics().heightPixels;}protected float dimAmount() {return 0.6f;}protected int defWidth() {return DEFAULT_WIDTH;}protected int defHeight() {return DEFAULT_HEIGHT;}/*** 设置位置** @param gravity*/public void setGravity(int gravity) {DEFAULT_GRAVITY = gravity;}/*** 设置宽** @param width*/public void setWidth(int width) {DEFAULT_WIDTH = width;}/*** 设置高** @param height*/public void setHeight(int height) {DEFAULT_HEIGHT = height;}/*** 设置点击返回按钮是否可取消*/public boolean cancelable() {return true;}/*** 设置点击外部是否可取消*/public boolean canceledOnTouchOutside() {return true;}public boolean hideAble() {return true;}/*** 设置布局** @return*/protected abstract int getLayoutId();/*** 初始化Views** @param v*/protected abstract void initViews(@NonNull View v);//全屏相关------------------------------------------------------------------/*** 全屏开光*/protected boolean fullScreenStyle() {return false;}/*** 全屏状态下,底部导航栏颜色*/protected int immerseNavigationBarColor() {return Color.WHITE;}protected int immerseStatusBarColor() {return Color.WHITE;}private void initImmerseSystemBar() {if (fullScreenStyle()) {Window window = getDialog() != null ? getDialog().getWindow() : null;if (window != null) {// 设置导航栏颜色window.setNavigationBarColor(immerseNavigationBarColor());window.setStatusBarColor(immerseStatusBarColor());// 设置导航栏图标颜色为深色(适用于浅色背景)if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {View decorView = window.getDecorView();int flags = decorView.getSystemUiVisibility();flags |= View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR;decorView.setSystemUiVisibility(flags);}}}}//rxjava release----------------------------private CompositeDisposable mDisposables = new CompositeDisposable();private void addObserver(DisposableObserver<?> disposableObserver) {mDisposables.add(disposableObserver);}private void removeObserver(DisposableObserver<?> disposableObserver) {if (mDisposables == null || disposableObserver == null) {return;}mDisposables.remove(disposableObserver);}private void clearObserver() {if (mDisposables != null) {mDisposables.clear();}}public abstract class BaseSafeObserver<T> extends DisposableObserver<T> {@Overrideprotected void onStart() {super.onStart();addObserver(this);}@Overridepublic void onNext(@NonNull T t) {}@Overridepublic void onError(@NonNull Throwable e) {removeObserver(this);}@Overridepublic void onComplete() {removeObserver(this);}}public void releaseResource() {clearObserver();}public <T> void addRequest(Flowable<T> flowable, final OnResultListener<T> onResultListener) {Disposable disposable = flowable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Consumer<T>() {@Overridepublic void accept(T t) throws Exception {onResultListener.onResult(t);onResultListener.onFinish();}}, new Consumer<Throwable>() {@Overridepublic void accept(Throwable throwable) {throwable.printStackTrace();onResultListener.onError(throwable);onResultListener.onFinish();}});mDisposables.add(disposable);}public interface OnResultListener<T> {void onResult(T t);void onError(Throwable t);void onFinish();}//rxjava release----------------------------protected void firstShow() {}}

相关的样式:

    <style name="DialogFragmentImmerse" parent="Theme.AppCompat.Light.NoActionBar"><item name="android:windowIsFloating">false</item> <!-- 核心:非浮动窗口 -->
<!--        <item name="android:windowFullscreen">true</item>--><item name="android:windowDrawsSystemBarBackgrounds">true</item><item name="android:windowTranslucentNavigation">false</item><item name="android:windowTranslucentStatus">false</item><item name="android:windowBackground">@android:color/transparent</item><item name="android:backgroundDimEnabled">true</item></style>



代码说明

上述代码中,有这样一个函数
在这里插入图片描述
这个方法,是用来实现DialogFragment的沉浸样式的,对于DialogFragment的全屏样式,非常简单,这里不再一一叙述,重点是沉浸样式。
普通的DialogFragment实现,状态栏和内容区域有明显的色差,这个时候就需要设置沉浸状态栏,让色差过度更加自然,这里的

                    View decorView = window.getDecorView();int flags = decorView.getSystemUiVisibility();flags |= View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR;decorView.setSystemUiVisibility(flags);

就是核心代码。而对于

                window.setNavigationBarColor(immerseNavigationBarColor());window.setStatusBarColor(immerseStatusBarColor());

则是设置底部导航栏和顶部状态栏的两个系统API,没什么好说的。

简单用法

通过字类继承这两个基类实现即可。若需要自定义沉浸状态栏,则重写这几个代码即可:

    @Overrideprotected boolean immerseStyle() {return true;}@Overridepublic boolean cancelable() {return false;}@Overrideprotected float dimAmount() {return 0f;}@Overrideprotected int immerseStatusBarColor() {return Color.parseColor("#80060606");}@Overrideprotected int immerseNavigationBarColor() {return Color.parseColor("#80060606");}

若是想基于上述基类,扩展DataBinding,则重写方法onCreateView即可

通过DataBindingUtil.inflate创建一个databinding对象,然后api调用getRoot()即可返回上级一个View。这样就能实现了,核心截图和代码如下:
在这里插入图片描述

public abstract class BaseDBDialogFragment<D extends ViewDataBinding> extends BaseDialogFragment {protected D binding;public D getBinding() {return binding;}public BaseDBDialogFragment() {}public BaseDBDialogFragment(BaseDialogFragmentLifeListener listener) {super(listener);}@Nullable@Overridepublic View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {binding = DataBindingUtil.inflate(inflater, getLayoutId(), container, false);binding.setLifecycleOwner(this);initViews(binding.getRoot());if (getListener() != null) {getListener().show();}return binding.getRoot();}
}

更多日常信息,可focus我gzh。 老李up野

that’s all-------------------------------------------------------------------------------------------------------------

http://www.xdnf.cn/news/13719.html

相关文章:

  • 103. Java 继承 - 状态、实现和类型的多重继承
  • 全球/中国降水量数据集(1940-2024年)
  • 图像解码失败检测
  • 健康管理实训室建设方案:构建智慧康养人才培养生态体系
  • PERST#、Hot Reset、Link Disable
  • React16,17,18,19更新对比
  • slam--高斯分布
  • 《树状数组》
  • 消除信息屏障推动系统联动,IBMS系统成为建筑智能控制核心枢纽
  • EtherCAT转Modbus TCP网关实现倍福CX9020与科尔摩根NDC8AGV控制器设备之间的通讯案例
  • C语言入门教程
  • 2.4 创建视图
  • python爬虫ip封禁应对办法
  • Word 文件转md文件 在 Word 中没有直接将文档另存为 Markdown(.md)格式的选项,但你可以使用一些工具或手动转换来实现
  • spring系列---拦截器
  • NLP基础与词嵌入:让AI理解文字(superior哥深度学习系列第13期)
  • 计算机组成原理-主存储器
  • RedHat主机配置日志留存策略:从4周延长至6个月
  • 预训练模型适应下游任务?模型参数Freezing 与 微调 !
  • 基于Jenkins与Kubernetes的系统化变更管理实践
  • 《前端面试题:call、apply、bind 区别》
  • 1.sql连接语句
  • 软件测试相关问题
  • 柑橘检测模型
  • 直白话 OAuth 2 流程
  • langchain runnables 概念指南
  • 2025年硬件实习/秋招面试准备
  • 小熊派开发板显示图片
  • 机器人导航中的高程图 vs 高度筛选障碍物点云投影 —— 如何高效处理避障问题?
  • Oracle 条件索引 case when 报错解决方案(APP)