Android自定义NoticeInfo实现顶部消息提示

对于顶部消息提示功能,本文采用自定义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>

猜你喜欢

转载自blog.csdn.net/weixin_46211609/article/details/129729438