歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> 基於Android浮動組件 可用於應用中新功能展示等

基於Android浮動組件 可用於應用中新功能展示等

日期:2017/3/1 10:49:38   编辑:Linux編程

基於Android的浮動組件,可以用於應用中的新功能展示等等。

前言

在開發Android應用時,加新功能是必不可少的,我們加入了新的功能,有的一看界面就可以看出來,但是有的新功能就比較隱蔽,也就是用戶很難知道你添加了這個新功能,這個時候就需要用戶在打開我們的應用時給出一些提示,說明我們在哪裡添加了新功能,點擊哪裡可以看到這個新功能。這時我們第一時間想到的可能是Toast,因為它用法簡單,又不影響用戶操作,但是它有個缺點,就是不能明確的指示是哪裡添加了新功能,除非你用文字描述出來。為此,我基於Toast編寫了一個小組件FloatTextToast(下面遇到的這個名字代替我寫的這個組件),他和Toast的用法一樣簡單,並且彌補了Toast的缺點,也更顯得更好看。 組件源代碼和效果圖的Demo下載

免費下載地址在 http://linux.linuxidc.com/

用戶名與密碼都是www.linuxidc.com

具體下載目錄在 /pub/Android源碼集錦/2011年/12月/基於Android浮動組件 可用於應用中新功能展示等/

效果圖


你可以學到

  1. Toast的基本用法
  2. Android的消息機制,如何創建自己的消息隊列
  3. 怎樣在Activity啟動時獲取一個View的width、height、top、left等屬性

基本思路


  1. 首先你要有一個處理好的9 PNG的圖片,用於自適應文字顯示,關於9 PNG處理可以參考Android Doc
  2. 要顯示在哪個View的下面,就要知道這個目標View的位置
  3. 把要顯示的文本放在一個TextView裡,使用Toast的setView方法設置Toast要顯示的View。
  4. 根據得到的位置,最後就是使用Toast的setGravity方法把要顯示的內容放到正確的位置顯示出來即可。
總的來說首先就是要知道目標View,根據targetView計算出要顯示提示的位置,然後根據位置使用Toast把提示的文本顯示出來。但是這裡有幾個難點,下面就一一解決

Activity加載完成時獲取targetVIew的寬高和位置屬性

我們加入了新的功能提示,自然會在用戶打開這個界面的時候就提示,但是在UI沒有渲染完成綁定倒Window上的時候,是不能獲取倒targetView的width、height和position的,那麼我們怎麼才能知道targetView的這些屬性呢?Activity的onAttachedToWindow回調方法是不能用的,況且它是在API 5加上的,以前的API中並沒有。不過我們還有一種方法,那就是在顯示提示的時候獲取targetView的屬性,如果獲取不到(為0)就一直獲取,直到獲取到為止,這其實是一個輪詢。為了達到這一目的,我們在開發者調用FloatTextToast.show()的時候使用Android的Message機制輪詢獲取一個targetView的屬性,如果獲取到,就會顯示提示文字了。在此之前先看下FloatTextToast構造函數,可以對它有個大概的了解,防止後面的代碼中出現的成員變量不認識。
  1. private FloatTextToast(Context context,View targetView) {
  2. this.mTargetView = targetView;
  3. this.mContext= context;
  4. mToast=new Toast(mContext);
  5. mContentView=new TextView(mContext);
  6. mContentView.setBackgroundResource(R.drawable.float_text_toast_bg);
  7. mContentView.setTextColor(Color.BLACK);
  8. mContentView.setTextSize(TypedValue.COMPLEX_UNIT_DIP,16);
  9. mToast.setView(mContentView);
  10. //初始化一個Handler線程
  11. mHandlerThread=new HandlerThread("FloatTextToast");
  12. mHandlerThread.start();
  13. mHandler=new FloatTextToastHandler(mHandlerThread.getLooper());
  14. }

自定義自己的消息循環機制

要想在一個自定義的組件中使用Message機制,一定要有自己的Looper機制,我們不能使用Activity的Looper,因為主Looper可能會有其他的Message需要處理,這就會導致我們的show方法會延遲調用,這樣效果就不好了,所以要有一個專門的Looper來處理此Message。要聲明自己的Looper,就需要HandlerThread這個類的配合了,這可是個好東西,使用它你會很容易的創建一個自己的線程用於處理你Message。使用方法很簡單,如下代碼:
  1. //初始化一個Handler線程
  2. mHandlerThread=new HandlerThread("FloatTextToast");
  3. mHandlerThread.start();
  4. mHandler=new FloatTextToastHandler(mHandlerThread.getLooper());
這樣就聲明了一個HandlerThread並且讓它運行,運行之後我們就可以獲取一個屬於該Thread的Looper,然後把Message發送給這個Looper,那麼這個線程就可以處理你發送的消息了。。看看我們的自定義Handler
  1. private class FloatTextToastHandler extends Handler{
  2. public FloatTextToastHandler(Looper looper) {
  3. super(looper);
  4. }
  5. @Override
  6. public void handleMessage(Message msg) {
  7. switch(msg.what){
  8. case WHAT_SHOW:
  9. showInHandler();
  10. }
  11. }
  12. }
它需要傳遞一個Looper作為構造參數聲明,意思就是使用這個Looper處理我發send的Message的意思。上面的代碼
  1. mHandler=new FloatTextToastHandler(mHandlerThread.getLooper());
正是我們使用自己開啟的線程處理我們的Message的意思。下面看下我們的showInHandler()方法是怎麼處理的。
  1. /**在Handler調用的show方法,主要為了等待{@link #mTargetView}的位置*/
  2. private void showInHandler(){
  3. int[] targetPos=getTargetViewPos();
  4. if(targetPos[0]==0&&targetPos[1]==0){
  5. mHandler.sendEmptyMessageDelayed(WHAT_SHOW, 100);
  6. }else{
  7. final Rect contentPos=getContentViewPos(targetPos);
  8. mToast.setGravity(Gravity.LEFT|Gravity.TOP, contentPos.left, contentPos.top);
  9. mToast.show();
  10. }
  11. }
該方法其實就是在獲取targetVIew的位置,如果獲取不到,則向自定義的Looper裡發送一個Message重新調用該函數,如果得到了位置,那麼就調用Toast的setGravity方法設置好要顯示文本的位置,然後顯示即可。
Copyright © Linux教程網 All Rights Reserved