【轉(zhuǎn)發(fā)】Android評(píng)論回復(fù)彈框舞萄,并稍作修改
這是一個(gè)很多app評(píng)論回復(fù)的時(shí)候 眨补, 經(jīng)常用到的彈框管削。使用Dialog的方式倒脓,不會(huì)耦合布局,使用簡(jiǎn)單含思,可在任何地方使用崎弃。可自定義樣式含潘。
進(jìn)入自動(dòng)彈出輸入法饲做,發(fā)送后自動(dòng)關(guān)閉輸入法,設(shè)置最大輸入字?jǐn)?shù)遏弱,超過字?jǐn)?shù)后盆均,字體會(huì)變紅 等功能。
下面是代碼:
InputTextMsgDialog.java
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Rect;
import android.support.annotation.NonNull;
import android.support.constraint.ConstraintLayout;
import android.support.v7.app.AppCompatDialog;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.Log;
import android.view.Display;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.View;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
public class InputTextMsgDialog extends AppCompatDialog {
private Context mContext;
private InputMethodManager imm;
private EditText messageTextView;
private TextView confirmBtn;
private int mLastDiff = 0;
private TextView tvNumber;
private int maxNumber = 200;
public interface OnTextSendListener {
void onTextSend(String msg);
}
private OnTextSendListener mOnTextSendListener;
public InputTextMsgDialog(@NonNull Context context, int theme) {
super(context, theme);
this.mContext = context;
this.getWindow().setWindowAnimations(R.style.main_menu_animstyle);
init();
setLayout();
}
/**
* 最大輸入字?jǐn)?shù) 默認(rèn)200
*/
@SuppressLint("SetTextI18n")
public void setMaxNumber(int maxNumber) {
this.maxNumber = maxNumber;
tvNumber.setText("0/" + maxNumber);
}
/**
* 設(shè)置輸入提示文字
*/
public void setHint(String text) {
messageTextView.setHint(text);
}
/**
* 設(shè)置按鈕的文字 默認(rèn)為:發(fā)送
*/
public void setBtnText(String text) {
confirmBtn.setText(text);
}
private void init() {
setContentView(R.layout.dialog_input_text_msg);
messageTextView = (EditText) findViewById(R.id.et_input_message);
tvNumber = (TextView) findViewById(R.id.tv_test);
final ConstraintLayout rldlgview = (ConstraintLayout) findViewById(R.id.constraintLayout_inputdlg_view);
messageTextView.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void afterTextChanged(Editable editable) {
tvNumber.setText(editable.length() + "/" + maxNumber);
if (editable.length() > maxNumber) {
/*dot_hong顏色值:#E73111,text_bottom_comment顏色值:#9B9B9B*/
tvNumber.setTextColor(mContext.getResources().getColor(R.color.dot_hong));
} else {
tvNumber.setTextColor(mContext.getResources().getColor(R.color.text_bottom_comment));
}
if (editable.length() == 0) {
confirmBtn.setBackgroundResource(R.drawable.btn_send_normal);
} else {
confirmBtn.setBackgroundResource(R.drawable.btn_send_pressed);
}
}
});
confirmBtn = (TextView) findViewById(R.id.confrim_btn);
imm = (InputMethodManager) mContext.getSystemService(Context.INPUT_METHOD_SERVICE);
confirmBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String msg = messageTextView.getText().toString().trim();
if (msg.length() > maxNumber) {
Toast.makeText(mContext, "超過最大字?jǐn)?shù)限制", Toast.LENGTH_LONG).show();
return;
}
if (!TextUtils.isEmpty(msg)) {
mOnTextSendListener.onTextSend(msg);
imm.showSoftInput(messageTextView, InputMethodManager.SHOW_FORCED);
imm.hideSoftInputFromWindow(messageTextView.getWindowToken(), 0);
messageTextView.setText("");
dismiss();
} else {
Toast.makeText(mContext, "請(qǐng)輸入文字", Toast.LENGTH_LONG).show();
}
messageTextView.setText(null);
}
});
messageTextView.setOnEditorActionListener(new TextView.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
switch (actionId) {
case KeyEvent.KEYCODE_ENDCALL:
case KeyEvent.KEYCODE_ENTER:
if (messageTextView.getText().length() > maxNumber) {
Toast.makeText(mContext, "超過最大字?jǐn)?shù)限制", Toast.LENGTH_LONG).show();
return true;
}
if (messageTextView.getText().length() > 0) {
imm.hideSoftInputFromWindow(messageTextView.getWindowToken(), 0);
dismiss();
} else {
Toast.makeText(mContext, "請(qǐng)輸入文字", Toast.LENGTH_LONG).show();
}
return true;
case KeyEvent.KEYCODE_BACK:
dismiss();
return false;
default:
return false;
}
}
});
messageTextView.setOnKeyListener(new View.OnKeyListener() {
@Override
public boolean onKey(View view, int i, KeyEvent keyEvent) {
Log.d("My test", "onKey " + keyEvent.getCharacters());
return false;
}
});
rldlgview.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
@Override
public void onLayoutChange(View view, int i, int i1, int i2, int i3, int i4, int i5, int i6, int i7) {
Rect r = new Rect();
//獲取當(dāng)前界面可視部分
getWindow().getDecorView().getWindowVisibleDisplayFrame(r);
//獲取屏幕的高度
int screenHeight = getWindow().getDecorView().getRootView().getHeight();
//此處就是用來(lái)獲取鍵盤的高度的漱逸, 在鍵盤沒有彈出的時(shí)候 此高度為0 鍵盤彈出的時(shí)候?yàn)橐粋€(gè)正數(shù)
int heightDifference = screenHeight - r.bottom;
if (heightDifference <= 0 && mLastDiff > 0) {
dismiss();
}
mLastDiff = heightDifference;
}
});
rldlgview.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
imm.hideSoftInputFromWindow(messageTextView.getWindowToken(), 0);
dismiss();
}
});
setOnKeyListener(new OnKeyListener() {
@Override
public boolean onKey(DialogInterface dialogInterface, int keyCode, KeyEvent keyEvent) {
if (keyCode == KeyEvent.KEYCODE_BACK && keyEvent.getRepeatCount() == 0)
dismiss();
return false;
}
});
}
private void setLayout() {
getWindow().setGravity(Gravity.BOTTOM);
WindowManager m = getWindow().getWindowManager();
Display d = m.getDefaultDisplay();
WindowManager.LayoutParams p = getWindow().getAttributes();
p.width = WindowManager.LayoutParams.MATCH_PARENT;
p.height = WindowManager.LayoutParams.WRAP_CONTENT;
getWindow().setAttributes(p);
setCancelable(true);
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
}
public void setmOnTextSendListener(OnTextSendListener onTextSendListener) {
this.mOnTextSendListener = onTextSendListener;
}
@Override
public void dismiss() {
super.dismiss();
//dismiss之前重置mLastDiff值避免下次無(wú)法打開
mLastDiff = 0;
}
@Override
public void show() {
super.show();
}
}
下面是布局文件:/layout/dialog_input_text_msg.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/constraintLayout_inputdlg_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/white">
<EditText
android:id="@+id/et_input_message"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/HomeMainBg"
android:gravity="top"
android:hint="想說點(diǎn)什么"
android:imeOptions="flagNoExtractUi"
android:lineSpacingMultiplier="1.2"
android:maxLength="2000"
android:maxLines="6"
android:minHeight="104dp"
android:paddingLeft="15dp"
android:paddingTop="10dp"
android:paddingRight="15dp"
android:paddingBottom="10dp"
android:scrollbars="vertical"
android:textColor="#FF333333"
android:textColorHint="@color/text_bottom_comment"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="InvalidImeActionId" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@color/DiscoverLine"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/et_input_message" />
<TextView
android:id="@+id/tv_test"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginStart="16dp"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:text="0/200"
android:textColor="@color/text_bottom_comment"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/et_input_message" />
<TextView
android:id="@+id/confrim_btn"
android:layout_width="50dp"
android:layout_height="28dp"
android:layout_marginTop="10dp"
android:layout_marginEnd="16dp"
android:layout_marginBottom="10dp"
android:background="@drawable/btn_send_normal"
android:gravity="center"
android:text="發(fā)送"
android:textColor="@color/white"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/et_input_message" />
</android.support.constraint.ConstraintLayout>
/drawable/btn_send_normal.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="4dp"/>
<solid android:color="#FFD2D2D2"/>
</shape>
/drawable/btn_send_pressed.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="4dp"/>
<solid android:color="#F9780D"/>
</shape>
/values/styles.xml
main_menu_animstyle
<style name="main_menu_animstyle">
<item name="android:windowEnterAnimation">@anim/anim_enter_from_bottom</item>
<item name="android:windowExitAnimation">@anim/anim_exit_from_bottom</item>
</style>
/anim/anim_enter_from_bottom.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:fromYDelta="100%"
android:toYDelta="0"
android:fillAfter="false"
android:duration="300"
/>
<alpha
android:fromAlpha="0.0"
android:toAlpha="1.0"
android:duration="300"
android:fillAfter="true"/>
</set>
/anim/anim_exit_from_bottom.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:fromYDelta="0"
android:toYDelta="100%"
android:fillAfter="false"
android:duration="300"
/>
<alpha
android:fromAlpha="1.0"
android:toAlpha="0.0"
android:duration="300"
android:fillAfter="true"/>
</set>
使用方式:
在OnCreate方法里直接new出這個(gè)Dialog即可泪姨,在需要的地方調(diào)用show方法顯示
inputTextMsgDialog = new InputTextMsgDialog(mContext, R.style.dialog_center);
inputTextMsgDialog.setmOnTextSendListener(new InputTextMsgDialog.OnTextSendListener() {
@Override
public void onTextSend(String msg) {
//點(diǎn)擊發(fā)送按鈕后,回調(diào)此方法饰抒,msg為輸入的值
}
});
下面是dialog_center的代碼肮砾,如果你需要讓這個(gè)Dialog點(diǎn)擊空白部分的activity時(shí)消失,背景變暗等功能袋坑,就加上這個(gè)style仗处。
/values/styles.xml
dialog_center
<!-- 中間彈出框 -->
<style name="dialog_center" parent="Theme.AppCompat.Dialog.Alert">
<!-- 去黑邊 -->
<item name="android:windowFrame">@null</item>
<item name="android:screenOrientation">portrait</item>
<!-- 設(shè)置是否可滑動(dòng) -->
<item name="android:windowIsFloating">true</item>
<!-- 背景 -->
<!-- 窗口背景 @color/touming的值為:#00000000 , style中不能直接引用16進(jìn)制-->
<item name="android:windowBackground">@color/transparent</item>
<!-- 是否變暗 -->
<item name="android:backgroundDimEnabled">true</item>
<!-- 點(diǎn)擊空白部分activity不消失 -->
<item name="android:windowCloseOnTouchOutside">true</item>
</style>
API:
inputTextMsgDialog.show() //顯示此dialog
inputTextMsgDialog.dismiss() //隱藏此dialog
inputTextMsgDialog.setHint() //設(shè)置輸入提示文字
inputTextMsgDialog.setBtnText() //設(shè)置按鈕的文字 默認(rèn)為:發(fā)送
inputTextMsgDialog.setMaxNumber() //最大輸入字?jǐn)?shù) 默認(rèn)200
注1:如果需要自定義樣式枣宫,請(qǐng)自己寫一個(gè)layout婆誓,替換dialog_input_text_msg。
注2:如果需要改變按鈕顏色等也颤,修改btn_send_normal和btn_send_pressed里的
<solid android:color="#FFD2D2D2"/>
其中洋幻,btn_send_normal為輸入框內(nèi)未輸入文字的顏色,btn_send_pressed為輸入后的顏色歇拆。