Android 指引蒙版的實現

實現這個功能的關鍵是: 你需要知道哪個button處需要給個指引的高亮顯示,這個涉及到座標的運算,免得位置放偏。

先給大家看看做的效果圖:把沒有做好的也放上去,這樣更容易看出問題和需要注意的地方。(圖一是沒有設置padding,效果不好;圖二是是指padding之後的效果,但是位置沒有對準;圖三才是正確的姿勢)

這裏寫圖片描述

這裏寫圖片描述

這裏寫圖片描述

看實現過程:

  1. 背景佈局和蒙版佈局需要實現重疊效果,就用了個RelativeLayout:
    背景佈局不多說了(demo中會有完整的),現在看蒙版佈局:
    <RelativeLayout
        android:id="@+id/rl_guide"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#bb000000"
        android:orientation="vertical"
        android:clickable="true"
        android:visibility="gone"
        >
        <LinearLayout
            android:id="@+id/ll_guide"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            android:background="@android:color/white"
            android:visibility="visible"
            >
            <ImageView
                android:id="@+id/iv_guide"
                android:layout_width="24dp"
                android:layout_height="24dp"
                android:src="@mipmap/send_icon48x48"
                android:layout_marginRight="10dp"
                />
            <TextView
                android:id="@+id/tv_guide"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="發消息"
                android:gravity="center_vertical"
                android:layout_gravity="center_vertical"
                />
        </LinearLayout>

        <ImageView
            android:id="@+id/iv_imageGuide"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@mipmap/guide_msg"
            android:layout_below="@+id/ll_guide"
            android:visibility="gone"
            android:clickable="true"
            />
    </RelativeLayout>

2.分析activity中的代碼:

(1)根據背景中發消息的圖標,計算它在屏幕中的位置,然後設置蒙版中對應的位置:調用getLocationOnScreen()這個方法可以獲取座標,但是這個包含了通知欄的位置,所以要相應減去通知欄高度。

/**測量通知欄高度*/
    private void getstatusBarHeight() {
        int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
        if (resourceId > 0) {
            statusBarHeight = getResources().getDimensionPixelSize(resourceId);
            System.out.println("hxy:"+"statusBarHeight"+statusBarHeight);
        }
    }

(2)正式開始計算髮消息view的座標:

private void measureGuideLocation() {
        //注意:此處需要開闢線程,延遲1s左右來做,以防測量不到座標
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                iv_sendMs.getLocationOnScreen(location);
                rect.left = iv_sendMs.getLeft();
                rect.top = iv_sendMs.getTop();
                rect.right = iv_sendMs.getRight();
                rect.bottom = iv_sendMs.getBottom();
                xLocation = location[0];
                yLocation = location[1];      
System.out.println("hxy:"+"xLocation:"+xLocation+"yLocation:"+yLocation);                    System.out.println("hxy:"+"rect.left:"+rect.left+"rect.top:"+rect.top+"rect.right"+rect.right+"rect.bottom"+rect.bottom);
                //更新控件的位置,放在UI線程中做:
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        setGuideLocation();
                    }
                });
            }
        }).start();
    }

(3)看setGuideLocation()中的方法:
實現圖一的效果的代碼,不設置padding:

 layoutParams.setMargins((int)xLocation,(int)yLocation-statusBarHeight,0,0);
 ll_guide.setLayoutParams(layoutParams);

實現圖二效果的代碼,設置padding之後有 誤差:

layoutParams.setMargins((int)xLocation,(int)yLocation-statusBarHeight,0,0);
ll_guide.setLayoutParams(layoutParams);
ll_guide.setPadding(rect.top,rect.top,rect.top,rect.top);

後面畫圖分析了下原因:

這裏寫圖片描述

再次糾正代碼,完整如下,實現了圖三的效果:

private void setGuideLocation() {
        RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams)  ll_guide.getLayoutParams();
         layoutParams.setMargins((int)xLocation-rect.top,(int)yLocation-statusBarHeight-rect.top,0,0);
        ll_guide.setLayoutParams(layoutParams);
        ll_guide.setPadding(rect.top,rect.top,rect.top,rect.top);
        rl_guide.setVisibility(View.VISIBLE);
        ll_guide.setVisibility(View.VISIBLE);
        iv_imageGuide.setVisibility(View.VISIBLE);
    }

通過以上步驟,就可以實現Android蒙版的效果了,大家可以試試,或許有更好的方法,可以一起分享。
demo下載地址點它

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章