对于顶部消息提示功能,本文采用自定义NoticeInfo类,实现使用时只需要写一行代码,非常方便!!!
(一)效果如图所示:
(二)使用方法:
只需要加入下面这8个文件(后面附有源码),即可使用,非常方便!!
使用示例:
(三)要加入的8个文件源代码如下:
1、NoticeInfo.java
package com.example.testnotice;
import android.app.Activity;
import android.content.Context;
import android.graphics.Color;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Handler;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.animation.AnimationUtils;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.appcompat.widget.AppCompatImageView;
import java.lang.ref.WeakReference;
/**
* 提示框信息
*/
public class NoticeInfo implements View.OnClickListener {
private static final int DEFAULT_VALUE = -100000;
private WeakReference<LinearLayout> layoutWeakReference;
private WeakReference<Activity> activityWeakReference;
// 显示时长
private int duration = 3000;
// 背景颜色
private int backgroundColor = DEFAULT_VALUE;
// 提示框高度
private int height = DEFAULT_VALUE;
// 左侧图标
private int icon = DEFAULT_VALUE;
// 左侧图标
private Drawable iconDrawable = null;
// 图标颜色
private int iconColorFilterColor = DEFAULT_VALUE;
// 图标尺寸
private int iconSize = 24;
// 提示文字信息
private String message = "";
// 提示文字信息颜色
private int messageColor = DEFAULT_VALUE;
// 点击事件
private OnToastBarClickListener onToastBarClickListener = null;
private NoticeInfo(Activity activity) {
activityWeakReference = new WeakReference<>(activity);
setDefault();
}
//创建带有activity参考的通知信息
public static NoticeInfo with(Activity activity) {
return new NoticeInfo(activity);
}
//返回activity父视图
private ViewGroup getActivityDecorView() {
return (ViewGroup) ((Activity) getContext()).getWindow().getDecorView();
}
//设置默认信息
private void setDefault() {
this.duration = 3000;
this.backgroundColor = DEFAULT_VALUE;
this.height = DEFAULT_VALUE;
this.icon = DEFAULT_VALUE;
this.iconDrawable = null;
this.iconColorFilterColor = DEFAULT_VALUE;
this.iconSize = 24;
this.message = "";
this.messageColor = DEFAULT_VALUE;
this.onToastBarClickListener = null;
}
private Context getContext() {
return activityWeakReference.get();
}
private View getLayout() {
return layoutWeakReference.get();
}
//设置显示时长
public NoticeInfo setDuration(int duration) {
this.duration = duration;
return this;
}
//设置背景颜色
public NoticeInfo setBackgroundColor(int backgroundColor) {
this.backgroundColor = backgroundColor;
return this;
}
//设置提示框高度
public NoticeInfo setHeight(int height) {
this.height = height;
return this;
}
//设置左侧图标
public NoticeInfo setIcon(int icon) {
this.icon = icon;
return this;
}
//设置左侧图标
public NoticeInfo setIconDrawable(Drawable iconDrawable) {
this.iconDrawable = iconDrawable;
return this;
}
//设置图标颜色
public NoticeInfo setIconColorFilterColor(int iconColorFilterColor) {
this.iconColorFilterColor = iconColorFilterColor;
return this;
}
//设置图标尺寸
public NoticeInfo setIconSize(int iconSize) {
this.iconSize = iconSize;
return this;
}
//设置提示框文字颜色
public NoticeInfo setMessageColor(int messageColor) {
this.messageColor = messageColor;
return this;
}
//设置ToastBar点击事件
public NoticeInfo setOnToastBarClickListener(OnToastBarClickListener onToastBarClickListener) {
this.onToastBarClickListener = onToastBarClickListener;
return this;
}
//成功
public NoticeInfo success() {
this.backgroundColor = Color.parseColor("#149de5");
this.messageColor = Color.parseColor("#FFFFFF");
this.icon = R.drawable.notice_success;
this.iconColorFilterColor = Color.parseColor("#FFFFFF");
return this;
}
//警告
public NoticeInfo warning() {
this.backgroundColor = Color.parseColor("#ffc100");
this.messageColor = Color.parseColor("#000000");
this.icon = R.drawable.notice_warning;
this.iconColorFilterColor = Color.parseColor("#000000");
return this;
}
//错误
public NoticeInfo error() {
this.backgroundColor = Color.parseColor("#ff0000");
this.messageColor = Color.parseColor("#FFFFFF");
this.icon = R.drawable.notice_error;
this.iconColorFilterColor = Color.parseColor("#FFFFFF");
return this;
}
/**
* 设置提示信息文字,默认为 {@link NoticeInfo#success()} 类型
*
* @param message
* @return return NoticeInfo
* @see #success() 成功
* @see #warning() 警告
* @see #error() 错误
*/
public NoticeInfo setMessage(String message) {
this.message = message;
return success();
}
public NoticeInfo setMessageErr(String message) {
this.message = message;
return error();
}
public NoticeInfo setMessageWarning(String message) {
this.message = message;
return warning();
}
//显示提示框,请在最后调用
public NoticeInfo show() {
if (getContext() != null) {
createView();
}
return null;
}
//移除
private void hide() {
if (getLayout() != null) {
getLayout().startAnimation(AnimationUtils.loadAnimation(getContext(), R.anim.noticeinfo_hide));
getActivityDecorView().removeView(getLayout());
}
}
//创建并添加提示框
private void createView() {
LinearLayout layout = new LinearLayout(getContext());
layoutWeakReference = new WeakReference<>(layout);
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, this.height == DEFAULT_VALUE ? (getStatusBarHeight() + convertToDp(56)) : convertToDp(this.height));
layout.setLayoutParams(layoutParams);
layout.setOrientation(LinearLayout.HORIZONTAL);
layout.setGravity(Gravity.CENTER_VERTICAL);
layout.setPadding(46, getStatusBarHeight(), 46, 0);
//设置控件高度
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
layout.setElevation(6);
}
//设置背景颜色
layout.setBackgroundColor(this.backgroundColor);
//设置图标
//如果图标已经存在
if (this.icon != DEFAULT_VALUE || this.iconDrawable != null) {
AppCompatImageView ivIcon = new AppCompatImageView(getContext());
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(convertToDp(this.iconSize), convertToDp(this.iconSize));
ivIcon.setLayoutParams(lp);
if (this.icon == DEFAULT_VALUE) {
ivIcon.setImageDrawable(this.iconDrawable);
} else {
ivIcon.setImageResource(this.icon);
}
ivIcon.setClickable(false);
if (this.iconColorFilterColor != DEFAULT_VALUE) {
ivIcon.setColorFilter(this.iconColorFilterColor);
}
layout.addView(ivIcon);
}
//设置标题和描述信息
LinearLayout textLayout = new LinearLayout(getContext());
LinearLayout.LayoutParams textLayoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
textLayout.setLayoutParams(textLayoutParams);
textLayout.setOrientation(LinearLayout.VERTICAL);
LinearLayout.LayoutParams lpTv = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
if (!this.message.isEmpty()) {
TextView tvTitle = new TextView(getContext());
tvTitle.setLayoutParams(lpTv);
tvTitle.setGravity(Gravity.CENTER_VERTICAL);
tvTitle.setPadding(46, 0, 26, 0); //如果没有提示信息,则不设置padding值
if (messageColor != DEFAULT_VALUE) {
tvTitle.setTextColor(messageColor);
}
tvTitle.setTextSize(14);
tvTitle.setText(this.message);
tvTitle.setClickable(false);
textLayout.addView(tvTitle);
}
layout.addView(textLayout);
layout.setId(R.id.Notice);
ViewGroup viewGroup = getActivityDecorView();
getExistingOverlayInViewAndRemove(viewGroup);
layout.setOnClickListener(this);
viewGroup.addView(layout);
layout.startAnimation(AnimationUtils.loadAnimation(getContext(), R.anim.noticeinfo_show));
Handler handler = new Handler();
handler.removeCallbacks(null);
handler.postDelayed(new Runnable() {
@Override
public void run() {
hide();
}
}, this.duration);
}
//当新添加一个提示框的时候,需要获得当前已经存在的提示框并且将它删除
public void getExistingOverlayInViewAndRemove(ViewGroup parent) {
for (int i = 0; i < parent.getChildCount(); i++) {
View child = parent.getChildAt(i);
if (child.getId() == R.id.Notice) {
parent.removeView(child);
}
if (child instanceof ViewGroup) {
getExistingOverlayInViewAndRemove((ViewGroup) child);
}
}
}
private int getStatusBarHeight() {
Rect rectangle = new Rect();
Window window = ((Activity) getContext()).getWindow();
window.getDecorView().getWindowVisibleDisplayFrame(rectangle);
int statusBarHeight = rectangle.top;
int contentViewTop = window.findViewById(Window.ID_ANDROID_CONTENT).getTop();
int titleBarHeight = contentViewTop - statusBarHeight;
return statusBarHeight;
}
private int convertToDp(float sizeInDp) {
float scale = getContext().getResources().getDisplayMetrics().density;
return (int) (sizeInDp * scale + 0.5f);
}
//点击并移除
@Override
public void onClick(View view) {
if (onToastBarClickListener != null) {
onToastBarClickListener.onClick(view);
}
getLayout().startAnimation(AnimationUtils.loadAnimation(getContext(), R.anim.noticeinfo_hide));
getActivityDecorView().removeView(getLayout());
}
public interface OnToastBarClickListener {
void onClick(View view);
}
}
2、NoticeInfoUtil.java
package com.example.testnotice;
import android.app.Activity;
/**
* NoticeInfo的工具类,更容易使用
*/
public class NoticeInfoUtil {
//显示成功提示
public static void noticeInfoSeccess(Activity context, String msg){
if (msg == null)
msg = "";
NoticeInfo.with(context).setMessage(msg).show();
}
public static void noticeInfoSeccess(Activity context, int msg){
NoticeInfo.with(context).setMessage(context.getString(msg)).show();
}
//显示警告提示
public static void noticeInfoWarning(Activity context, String msg){
if (msg == null)
msg = "";
NoticeInfo.with(context).setMessageWarning(msg).show();
}
public static void noticeInfoWarning(Activity context, int msg){
NoticeInfo.with(context).setMessageWarning(context.getString(msg)).show();
}
//显示错误提示
public static void noticeInfoError(Activity context, String msg){
if (msg == null)
msg = "";
NoticeInfo.with(context).setMessageErr(msg).show();
}
public static void noticeInfoError(Activity context, int msg){
NoticeInfo.with(context).setMessageErr(context.getString(msg)).show();
}
}
3、anim->noticeinfo_hide.xml
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="200"
android:fromYDelta="0%"
android:toYDelta="-100%" />
</set>
4、anim->noticeinfo_show.xml
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="200"
android:fromYDelta="-100%"
android:toYDelta="0%" />
</set>
5、drawable->notice_error.xml
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
<path
android:fillColor="#FFFFFF"
android:pathData="M11,15h2v2h-2zM11,7h2v6h-2zM11.99,2C6.47,2 2,6.48 2,12s4.47,10 9.99,10C17.52,22 22,17.52 22,12S17.52,2 11.99,2zM12,20c-4.42,0 -8,-3.58 -8,-8s3.58,-8 8,-8 8,3.58 8,8 -3.58,8 -8,8z"/>
</vector>
6、drawable->notice_success.xml
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
<path
android:fillColor="#FFFFFF"
android:pathData="M9,16.2L4.8,12l-1.4,1.4L9,19 21,7l-1.4,-1.4L9,16.2z"/>
</vector>
7、drawable->notice_warning.xml
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
<path
android:fillColor="#000000"
android:pathData="M1,21h22L12,2 1,21zM13,18h-2v-2h2v2zM13,14h-2v-4h2v4z"/>
</vector>
8、values->ids.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<item name="Notice" type="id"/>
</resources>
(四)MainActivity.java和activity_main.xml源码:
MainActivity.java
package com.example.testnotice;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private Button btn_Seccess;
private Button btn_Warning;
private Button btn_Err;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn_Seccess = findViewById(R.id.btn_Seccess);
btn_Warning = findViewById(R.id.btn_Warning);
btn_Err = findViewById(R.id.btn_Err);
btn_Seccess.setOnClickListener(this);
btn_Warning.setOnClickListener(this);
btn_Err.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.btn_Seccess:
NoticeInfoUtil.noticeInfoSeccess(this,"这是一条成功信息");
break;
case R.id.btn_Warning:
NoticeInfoUtil.noticeInfoWarning(this,"这是一条警告信息");
break;
case R.id.btn_Err:
NoticeInfoUtil.noticeInfoError(this,"这是一条失败信息");
break;
}
}
}
avtivity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:id="@+id/btn_Seccess"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="显示成功"
android:layout_marginTop="60dp"/>
<Button
android:id="@+id/btn_Warning"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="显示警告"
android:layout_marginTop="30dp"/>
<Button
android:id="@+id/btn_Err"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="显示失败"
android:layout_marginTop="30dp"/>
</LinearLayout>