由于项目的需要,要求做一个提示框,这个提示框需要在某个控件的下方做出一个提示,并具有动画特效。

实现

  • 功能定位:

本功能需要实现的是,每一个提示都需要加入队列中。

  • 类图:

image

1. ToastManager:用于管理Member类,里面有个队列。用于有提示请求的时候,添加到队列中,以先到先提示的原则进行提示。

2. ToastRunable:用于执行Member的方法。该方法从队列中读取Member,并执行show方法,读完为止。

3. Member:显示提示。使用PopWindows实现。

  • 实现

(似乎实现有点不一样)

public class PdToast {

public static final int ID = 10256;
private PopupWindow mWin;
private View mAnchor;
private View mRootView;
private Context mContext;
private long mDuration = 1000 * 3;
private Queue<Member> mQueue;
private boolean mIsStart = false;
private boolean mStop = false;
private Handler mHandler = new Handler();

private boolean DEBUG = false;

private PdToast(Context context) {
this.mWin = new PopupWindow(context.getApplicationContext());
this.mQueue = new LinkedList<Member>();
}

public void show(String text, View anchor) {
this.mAnchor = anchor;
Member m
= new Member(text);
this.mQueue.offer(m);
start();
}

private void start() {
if (!mIsStart) {
mIsStart
= true;
mStop
= false;
new Thread(mShowQueueRunable).start();
}
}

private Runnable mShowQueueRunable = new Runnable() {
public void run() {
while (!mStop) {
try {
Member m
= mQueue.poll();
if (null == m) {
break;
}
if (DEBUG)
Log.v(
"PDTOAST", "GET MEMEBER");

m.doShow();
Thread.sleep(mDuration);
m.doHide();
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
if (DEBUG)
Log.v(
"PDTOAST", "STOP");
mIsStart
= false;
}
};

public void setAnimationStyle(int animationStyle) {
this.mWin.setAnimationStyle(animationStyle);
}

public void setContentView(int layoutId) {
LayoutInflater inflator
= (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

setContentView(inflator.inflate(layoutId,
null));
}

public void setAnchor(View view) {
this.mAnchor = view;
}

public void setContentView(View root) {
mRootView
= root;
mWin.setContentView(root);
}

public static PdToast make(Context context, View root, int animationStyle) {
PdToast pd
= new PdToast(context);
pd.setAnimationStyle(animationStyle);
pd.setContentView(root);
return pd;
}

private void preShow(String text) {

mWin.setWidth(WindowManager.LayoutParams.WRAP_CONTENT);
mWin.setHeight(WindowManager.LayoutParams.WRAP_CONTENT);

TextView tv
= (TextView) this.mRootView.findViewById(ID);
tv.setText(text);
}

private void show() {
mWin.showAsDropDown(mAnchor);
}

public void cancel() {
mWin.dismiss();
mStop
= true;
}

private class Member {
private String mContent;

private final Runnable mShowR = new Runnable() {
public void run() {
if (mAnchor == null)
return;

Log.v(
"PDTOAST", "SHOW MEMEBER");

preShow(mContent);

show();
}
};

private final Runnable mHideR = new Runnable() {
public void run() {
mWin.dismiss();
}
};

public Member(String text) {
this.mContent = text;
}

public void doShow() {
mHandler.post(mShowR);
}

public void doHide() {
mHandler.post(mHideR);
}
}

}



  • 使用
private PdToast mToast;

TextView mAnchorView
=new TextView(this);

mAnchorView.setId(PdToast.Id);

// 该方法会实例化一个Member对象,添加到队列中。
//必须确保Activity的存在。建议在onPause()中执行mToast.cancel();方法。
mToast.show(content, mAnchorView);



关于参数的几个问题:

1. 该类有两个耦合的对象,一个是Context,一个是View.当这两个数据有问题是都会引起他的执行失败。例如Activity被销毁,和View值变为空。

2. Context参数必须是依赖于Activity而不是Application.所以传进去的是Context一般为Activity。如果不是,可能会引起bad window token errors错误。

3. 如上所说,PdToast也是依赖与Acitvity的生命周期。

posted on 2011-09-20 14:59  OKSharp  阅读(562)  评论(2)    收藏  举报