在开发中,经常会遇到一个界面中需求底部弹窗,输入评论后发送的需求。在实际操作中很多初学者或者中级开发人员都会出现选择
PopUpWindow这个控件来可定制化开发,这个时候辛辛苦苦开发完成后会发现几个问题:
1:一个界面中使用PopUpWindow来实现起来比较复杂,会设置各种InputMode,Location等各种属性。
2:当PopUpWindow中包含有EditText的时候大坑就来了,这个时候你会发现EditText与屏幕中软键盘的显示适配问题(软键盘会遮挡该弹窗一部分)
3:当你解决上面的问题时,会遇到终极大Boss,这个时候你细心的话会发现EditText中原有的长按复制,粘贴,全选等都没有用了(通过我查阅分析发现是Android的
一个Bug,大坑啊!!)
这个时候我们就会想着换种思维来解决这个问题。效果如下图,下面表演开始:
1:自定义一个Dialog继承DialogFragment,注释写的比较清楚
/**
* author : AndyYuan
* e-mail : 01810***@smg.cn
* date : 2021/4/22 002215:38
* desc : 自定义Dailog评论
* version: 2.0
*/
@SuppressLint("ValidFragment")
public class EditDialog extends DialogFragment {
private TextView tx_quxiao_popup;//取消按钮
private TextView tx_write_popup; //发送按钮
private TfEditView et_comment_popup;//评论内容
private LinearLayout ll_background_dialog;//容器
private boolean isCommenting = false;
private String uid;
private String id;
private String cid;
/**
* 这个构造方法实现参数的传递
*
* @param uid 测试参数1
* @param id 测试参数2
* @param cid 测试参数3
*/
public EditDialog(String uid, String id, String cid) {
this.uid = uid;
this.id = id;
this.cid = cid;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//这句代码的意思是让dialogFragment弹出时沾满全屏
setStyle(DialogFragment.STYLE_NORMAL, android.R.style.Theme_Holo_Light_DialogWhenLarge_NoActionBar);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.pop_news_content_input_test, null);
//让DialogFragment的背景为透明
getDialog().getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
initView(view);
initEvent();
return view;
}
//初始化view
private void initView(View view) {
tx_quxiao_popup = (TextView) view.findViewById(R.id.txt_cancel);
tx_write_popup = (TextView) view.findViewById(R.id.txt_send);
et_comment_popup = (TfEditView) view.findViewById(R.id.edit_input);
ll_background_dialog = (LinearLayout) view.findViewById(R.id.ll_pop_dialog);
}
private void initEvent() {
//取消
tx_quxiao_popup.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(getActivity(), "取消", Toast.LENGTH_SHORT).show();
dismiss();
}
});
//确认发送
tx_write_popup.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (et_comment_popup.getText().toString().length() > 0) {
//这里可以做我们自己想要的操作,常用的请求网络等写在这里吧
Toast.makeText(getActivity(), "评论" + et_comment_popup.getText(), Toast.LENGTH_LONG).show();
} else {
Toast.makeText(getActivity(), "内容不能为空", Toast.LENGTH_SHORT).show();
}
dismiss();
}
});
//外层Dialog
ll_background_dialog.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
dismiss();
}
});
et_comment_popup.addTextChangedListener(new TextWatcherImpl() {
@Override
public void afterTextChanged(Editable s) {
if (s == null || s.length() == 0) {
tx_write_popup.setTextColor(Color.parseColor("#a4a4a4"));
} else {
tx_write_popup.setTextColor(Color.BLACK);
if (s.length() == 140) {
ToastUtil.Infotoast(getActivity(), getResources().getString(R.string.dicuss_max_length));
}
}
}
});
}
}
2:其中布局文件比较简单如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/ll_pop_dialog"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/transpant"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:background="@color/transpant" />
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#efefef"
android:padding="8dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:text="@string/dicuss"
android:textColor="#717171"
android:textSize="18sp" />
<TextView
android:id="@+id/txt_cancel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="1dp"
android:text="@string/cancel"
android:textColor="@android:color/black"
android:textSize="16sp" />
<TextView
android:id="@+id/txt_send"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_marginTop="1dp"
android:text="@string/send"
android:textColor="#a4a4a4"
android:textSize="16sp" />
<TfEditView
android:id="@+id/edit_input"
android:layout_width="match_parent"
android:layout_height="120dp"
android:layout_below="@+id/txt_cancel"
android:layout_marginTop="16dp"
android:background="@drawable/bg_content_input_edit"
android:gravity="start"
android:imeOptions="flagNoExtractUi"
android:maxLength="140"
android:padding="8dp"
android:textColor="@android:color/black"
android:textSize="16sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/edit_input"
android:layout_alignParentRight="true"
android:layout_marginTop="8dp"
android:text="@string/dicuss_max_length"
android:textColor="#ff5722"
android:textSize="14sp" />
</RelativeLayout>
</ScrollView>
</LinearLayout>
3:里面有个自定义的EditText来实现对字数的监听,该自定义控件如下:
/**
* Created by andyyuan on 20/8/17.
*/
public class TfEditView extends EditText {
private OnFinishComposingListener mFinishComposingListener;
public TfEditView(Context context) {
super(context);
}
public TfEditView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public TfEditView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public void setOnFinishComposingListener(OnFinishComposingListener listener) {
this.mFinishComposingListener = listener;
}
@Override
public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
return new MyInputConnection(super.onCreateInputConnection(outAttrs), false);
}
/**
* 软键盘关闭监听
*/
public class MyInputConnection extends InputConnectionWrapper {
public MyInputConnection(InputConnection target, boolean mutable) {
super(target, mutable);
}
@Override
public boolean finishComposingText() {
boolean finishComposing = super.finishComposingText();
if (mFinishComposingListener != null) {
mFinishComposingListener.finishComposing();
}
return finishComposing;
}
}
/**
* Created by andyYuan on 20/8/23.
* 输入框软键盘关闭监听
*/
public interface OnFinishComposingListener {
void finishComposing();
}
}
4:使用起来很简单把需要的参数传递过去如下:
dialogButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
FragmentManager manager = getSupportFragmentManager();
EditDialog customDialog = new EditDialog(null,null,null);
customDialog.show(manager,"customer");
}
});
5:ok,打完收工~