欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

安卓自定义Toast的原理及实现

程序员文章站 2022-07-14 12:54:09
...

本文简要介绍安卓自定义toast的原理及实现

安卓本身自带的toast功能,简单易用,只要可以满足绝大多数的需求

Toast.makeText(this, "This is a toast!", Toast.LENGTH_SHORT).show();

若是有自定义toast的需求,可以用以下方法实现

注意:本文没有实现自定义duration,因为如果设置为任意数值,将会被系统转换成Toast.LENGTH_SHORT.

大致思路


1,为自定义toast写一个layout文件,并加载

2,创建一个Toast

3,设置toast的View

4,初始化layout中的各种组件

话不多说,用代码表示,如下

首先创建一个简单的layout文件toast_layout

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="horizontal">


    <ImageView
        android:id="@+id/toast_image"
        android:layout_width="20dp"
        android:layout_height="20dp" />


    <TextView
        android:id="@+id/toast_message"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="14sp"
        android:gravity="center_vertical"/>

</LinearLayout>

定义一个toast类MyToast2(MyToast1)我会在 之后讲,稍微麻烦一点

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

public class MyToast2 {
    
    public Toast myToast;//创建一个toast
    public View view;//用于加载toast的view
    public ImageView image;//分别是view中的两个 组件
    public TextView message;
    //初始化函数,创建toast,加载view,初始化view,image,layout
    public MyToast2(Context context) {
        myToast = new Toast(context);
        view = LayoutInflater.from(context).inflate(R.layout.toast_layout, null);
        image = (ImageView) view.findViewById(R.id.toast_image);
        message = (TextView) view.findViewById(R.id.toast_message);
    }

    //对toast的各项 进行设置
    public MyToast2 setToast(String message, int image, boolean isShown, int gravity,int duration) {
        myToast.setView(view);//设置toast的view为加载入的布局
        this.message.setText(message.isEmpty() ? "null" : message);//设置消息
        //根据是否需要显示图标(布局文件中加入了一个图标),进行对图标内容和可见性的设定
        if (isShown) {
            this.image.setVisibility(View.VISIBLE);
            this.image.setBackgroundResource(image);
        } else {
            this.image.setVisibility(View.GONE);
        }
        //设置gravity
        this.myToast.setGravity(gravity, 0, 0);
        //设置持续时间
        this.myToast.setDuration(duration);
        return this;
    }
    //显示toast
    public void show() {
        this.myToast.show();
    }
}

使用的时候初始化即可

final MyToast2 toast2 = new MyToast2(this);
        toast2.setToast
                ("这是第二个toast", R.drawable.ic_launcher_background,
                        true, Gravity.CENTER, Toast.LENGTH_SHORT);
toast.show();

效果如下(没有美工,有点丑,见谅)


安卓自定义Toast的原理及实现

接下来就要说我之前提到的第一个MyToast了,思想和上面的MyToast2完全一致,仅仅是换了一个使用方法

MyToast模仿安卓自身的通知的build方法,使用静态内部类完成这个功能,不做过多解释,有Java基础的应该能看懂

import android.content.Context;
import android.support.annotation.DrawableRes;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

public class MyToast {
    //根据xml布局中的定义,在MyToast中定义这些组件
    public Toast myToast;
    public View  myToastView;
    public TextView myToastMessage;
    public ImageView myToastImage;

    //构造函数简单地初始化这些组件
    public MyToast(Context context) {
        myToast = new Toast(context);
        myToastView = LayoutInflater.from(context).inflate(R.layout.toast_layout, null);
        myToastMessage = (TextView) myToastView.findViewById(R.id.toast_message);
        myToastImage = (ImageView) myToastView.findViewById(R.id.toast_image);
    }

    public void show() {
        this.myToast.show();
    }
    //仿照安卓通知的模式,定义一个Builder,个人觉得方便好用,方便重用
    //这里需要试用到安卓静态内部类

    //Builder类开始
    public static class Builder {
        //一下分别是toast的一些属性
        private String message;
        private int imageID;
        private int gravity = Gravity.CENTER;
        private boolean isShowIcon;
        private int duration = Toast.LENGTH_SHORT;
        //以下两个分别是构造toast的时候要用到的资源
        private Context context;
        private MyToast toast;
        //构造函数,主要功能是获取上下文
        public Builder(Context context) {
            this.context = context;
        }
        //分别是设置资源值的方法
        public Builder setMessage(String message) {
            this.message = message;
            return this;
        }



        public Builder setImage(@DrawableRes int id) {
            this.imageID = id;
            return this;
        }

        public Builder setGravity(int gravity) {
            this.gravity = gravity;
            return this;
        }

        public Builder shownAble(boolean b) {
            this.isShowIcon = b;
            return this;
        }

        public Builder setDuration(int duration) {
            this.duration = duration;
            return this;
        }

        public MyToast build() {
            if (toast == null) {
                toast = new MyToast(context);
            }
            //检查是否显示toast的图像
            if (isShowIcon) {
                toast.myToastImage.setVisibility(View.VISIBLE);
                toast.myToastImage.setBackgroundResource(imageID);
            } else {
                toast.myToastImage.setVisibility(View.GONE);
            }
            toast.myToast.setView(toast.myToastView);
            toast.myToastMessage.setText(message.isEmpty() ? "null" : message);
            toast.myToast.setDuration(duration);
            toast.myToast.setGravity(gravity, 0, 0);
            return toast;
        }

    }
    //Builder类结束

}

使用方法demo如下

final MyToast toast = new MyToast.Builder(this)
                .setDuration(Toast.LENGTH_LONG)
                .setMessage("这是第一个自定义Toast")
                .setGravity(Gravity.CENTER)
                .setImage(R.drawable.ic_launcher_background)
                .shownAble(true)
                .build();

怎么样,是不是个安卓自带的通知build方法差不多呢?写起来麻烦点,不过用起来舒服

调用toast.show()即可显示,效果如下(同样丑)

安卓自定义Toast的原理及实现

完整的mianactivity如下



import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Gravity;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    private Button button1, button2;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //用第一种方法使用toast
        final MyToast toast = new MyToast.Builder(this)
                .setDuration(Toast.LENGTH_LONG)
                .setMessage("这是第一个自定义Toast")
                .setGravity(Gravity.CENTER)
                .setImage(R.drawable.ic_launcher_background)
                .shownAble(true)
                .build();
        //用第二种方法使用toast
        final MyToast2 toast2 = new MyToast2(this);
        toast2.setToast
                ("这是第二个toast", R.drawable.ic_launcher_background,
                        true, Gravity.CENTER, Toast.LENGTH_SHORT);
        //初始化button1,
        button1 = (Button) findViewById(R.id.button1);
        button1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                toast.show();
            }
        });

        button2 = (Button) findViewById(R.id.button2);
        button2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                toast2.show();
            }
        });
    }
}

写的很粗糙,希望给和我一样的初学者一点帮助
相关标签: Android toast ui