addison_lin 发表于 2012-1-7 10:56:53

可以锚定的Toast

由于项目的需要,要求做一个提示框,这个提示框需要在某个控件的下方做出一个提示,并具有动画特效。
实现 ·         功能定位:本功能需要实现的是,每一个提示都需要加入队列中。·         类图 ·          ·         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]
查看完整版本: 可以锚定的Toast