Jetpack 全局控制 实战自定义Toast

作者: zcwfeng | 来源:发表于2021-06-23 00:05 被阅读0次

    自定义Toast

    public class CustomToast extends Toast {
    
        TextView textView;
        /**
         * Construct an empty Toast object.  You must call {@link #setView} before you
         * can call {@link #show}.
         *
         * @param context The context to use.  Usually your {@link Application}
         *                or {@link Activity} object.
         */
        public CustomToast(Context context) {
            super(context);
            init(context);
        }
    
        private void init(Context context) {
            View view = View.inflate(context, R.layout.layout_global_toast,null);
            textView = (TextView) view.findViewById(R.id.content);
            setView(view);
        }
    
        @Override
        public void setText(CharSequence sequence){
            textView.setText(sequence);
        }
    
        @Override
        public void setText(int resId) {
            textView.setText(resId);
        }
    
    }
    

    控制Toast 的位置

    
    public class CustomToastUtil extends Toast {
        private static String oldMsg;
        protected static Toast toast = null;
        private static long oneTime = 0;
        private static long twoTime = 0;
    
        /**
         * Construct an empty Toast object.  You must call {@link #setView} before you
         * can call {@link #show}.
         *
         * @param context The context to use.  Usually your {@link Application}
         *                or {@link Activity} object.
         */
        public CustomToastUtil(Context context) {
            super(context);
        }
    
        public static void showToast(Context context, int resId) {
            showToast(context, context.getString(resId));
        }
    
        public static void showToast(Context context, int resId, int gravity) {
            showToast(context, context.getString(resId), gravity, 0, 0);
        }
    
        public static void showToast(Context context, String s, int gravity) {
            showToast(context, s, gravity, 0, 0);
        }
    
        public static void showToast(Context context, int resId, int gravity, int offX, int offY) {
            showToast(context, context.getString(resId), gravity, offX, offY);
        }
    
        public static void showToast(Context context, String s) {
            if (TextUtils.isEmpty(s)) {
                return;
            }
            if (toast == null) {
                toast = new CustomToast(context);
                toast.setText(s);
                toast.setDuration(Toast.LENGTH_SHORT);
                toast.setMargin(0, 0);
                toast.setGravity(Gravity.TOP + Gravity.FILL_HORIZONTAL, 0, 150);
                toast.show();
                oneTime = System.currentTimeMillis();
            } else {
                twoTime = System.currentTimeMillis();
                if (s.equals(oldMsg)) {
                    if (twoTime - oneTime > Toast.LENGTH_SHORT) {
                        toast.show();
                    }
                } else {
                    oldMsg = s;
                    toast.setText(s);
                    toast.show();
                }
            }
            oneTime = twoTime;
    
    
        }
    
    
        public static void showToast(Context context, String s, int gravity, int offX, int offY) {
            if (toast == null) {
                toast = new CustomToast(context);
                toast.setText(s);
                toast.setDuration(Toast.LENGTH_SHORT);
                toast.setGravity(gravity, offX, offY);
                toast.setMargin(1, 0);
                toast.show();
                oneTime = System.currentTimeMillis();
            } else {
                twoTime = System.currentTimeMillis();
                if (s.equals(oldMsg)) {
                    if (twoTime - oneTime > Toast.LENGTH_SHORT) {
                        toast.show();
                    }
                } else {
                    oldMsg = s;
                    toast.setText(s);
                    toast.show();
                }
            }
            oneTime = twoTime;
        }
    }
    

    利用LiveData 观察者模式,封装到BaseActivity观察。LiveData抽取工具类思想实现全局控制

    本来我们自定义Toast已经可以使用,但是不方便,toast也要在主线程显示,这个时候传入context需要activity,但是通过LiveData我们解决切线程传入必须Activity,有的地方又拿不到问题。

    封装Content 内容

    public class Content implements Publisher.Publishable {
    
        String content;
    
        public Content(String content) {
            this.content = content;
        }
    
        public String getContent() {
            return content;
        }
    }
    

    定义Publisher

    public class Publisher {
    
        private final List<Observer> observers;
    
        public Publisher() {
            this.observers = new ArrayList<>();
        }
    
        /**
         * 注册
         *
         * @param observer
         */
        public void register(Observer observer) {
            if (!isRegistered(observer)) {
                observers.add(observer);
            }
        }
    
        /**
         * 注销
         *
         * @param observer
         */
        public void unRegister(Observer observer) {
            if (isRegistered(observer)) {
                observers.remove(observer);
            }
        }
    
        public boolean isRegistered(Observer observer) {
            return observers.contains(observer);
        }
    
        /**
         * 获取注册听众数量
         *
         * @return
         */
        public int getObserversCount() {
            return observers.size();
        }
    
        /**
         * 通知所有听众
         */
        public void notifyObservers(Object data) {
            if (observers.size() > 0) {
                for (Observer observer : observers) {
                    if (observer != null) {
                        observer.update(data);
                    }
                }
            }
        }
    
        public interface Observer {
            void update(Object data);
        }
    
    
        public interface Publishable {
        }
    
    }
    

    PuublishHolder

    public class PublishableHolder<P extends Publisher.Publishable> {
        private final Publisher publisher;
        private P data;
    
        public PublishableHolder(Publisher publisher) {
            this.publisher = publisher;
        }
    
        public P getData() {
            return data;
        }
    
        public void setData(P data) {
            this.data = data;
            publisher.notifyObservers(this.data);
        }
    
        /**
         * 在data的引用地址不改变的情况下修改data内部的数据推荐调用此方法
         * 否则需要自行通知publisher
         *
         * @param changer
         */
        public void modifyData(DataChanger changer) {
            if (changer != null) {
                changer.doChange(data);
                publisher.notifyObservers(data);
            }
        }
    
        /**
         * 修改数据接口
         */
        public interface DataChanger<P extends Publisher.Publishable> {
            void doChange(P data);
        }
    
    }
    

    组合Publisher 和PublisherHolder

    public class ToastPublisher {
        public static final Publisher publisher = new Publisher();
        public static final PublishableHolder<Content> data = new PublishableHolder(publisher);
    }
    

    扩展Holder的使用

    public class PublishableListHolder<P extends Publisher.Publishable> {
        private final List<P> list;
        private final Publisher publisher;
    
        public PublishableListHolder(Publisher publisher) {
            list = new ArrayList<>();
            this.publisher = publisher;
        }
    
        public void setList(List<P> list) {
            this.list.clear();
            this.list.addAll(list);
            publisher.notifyObservers(this.list);
        }
    
        public List<P> getList(Publisher.Observer observer) {
            return list;
        }
    
        public void addItem(P publishable) {
            list.add(publishable);
            publisher.notifyObservers(list);
        }
    
        public void removeItem(P publishable) {
            if (list.contains(publishable)) {
                list.remove(publishable);
                publisher.notifyObservers(list);
            }
        }
    
        public void addAll(List<P> publishableList) {
            list.addAll(publishableList);
            publisher.notifyObservers(list);
        }
    
        public void removeAll(List<P> publishableList) {
            list.removeAll(publishableList);
            publisher.notifyObservers(list);
        }
    
        public void clear() {
            list.clear();
            publisher.notifyObservers(list);
        }
    }
    

    工具类调用

    public static void showToast(String message) {
            ToastPublisher.data.setData(new Content(message));
        }
    
        public static void showToast(int resid) {
            ToastPublisher.data.setData(new Content(BaseApplication.getInstance().getString(resid)));
    
        }
    
        public static void showErrorToast(ApiException e) {
            if(e != null) {
                if(e.getCode() >= 500) {
                    if(!TextUtils.isEmpty(e.getMessage())) {
                        showToast(e.getMessage());
                    } else {
                        showToast("Server Exception");
                    }
                } else {
                    showToast("Request Exception");
                }
    
            } else {
                showToast("Unknown Exception");
                KLog.e("login-exception","Unknown Exception");
    
    
            }
        }
    

    BaseActivity 中注册,解注册,统一调用

    private ToastObserver toastObserver = new ToastObserver();
        private class ToastObserver implements Publisher.Observer{
    
            @Override
            public void update(Object data) {
                final Content content = (Content) data;
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        CustomToastUtil.showToast(BaseActivity.this, content.getContent());
                    }
                });
            }
        }
    
    
    onCreate中
            ToastPublisher.publisher.register(toastObserver);
    onDestroy中
            ToastPublisher.publisher.unRegister(toastObserver);
    
    

    相关文章

      网友评论

        本文标题:Jetpack 全局控制 实战自定义Toast

        本文链接:https://www.haomeiwen.com/subject/xddmyltx.html