Jetpack 全局控制 实战自定义Toast
2021-06-23 本文已影响0人
zcwfeng
自定义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);