仿探探的雷達(dá)探測(cè)View

寫(xiě)點(diǎn)東西記錄下矫夷,分享下存谎,愿大家能一起成長(zhǎng)瞻凤。..
打開(kāi)"探探"的app,就在首頁(yè)你可能會(huì)發(fā)現(xiàn)一個(gè)蠻有意思的View,看起來(lái)像雷達(dá)探測(cè)冈敛,個(gè)人感覺(jué)效果蠻好的。如果你也覺(jué)得有意思鸣皂,喜歡的話那么就繼續(xù)看看下面的內(nèi)容吧抓谴。
由于時(shí)間問(wèn)題,只仿了8成左右,有一些地方還可以再改進(jìn)改進(jìn)的,因?yàn)轶w驗(yàn)還是比原版的要差些,如果項(xiàng)目要用的話可能也需要自己改動(dòng)改動(dòng)寞缝。
下面就要開(kāi)始了癌压,如果發(fā)現(xiàn)有什么不對(duì)的或者可以有更好的實(shí)現(xiàn)的話,請(qǐng)告訴我吧,及時(shí)改正一同進(jìn)步荆陆。~~
首先先上張效果圖看看:

GIF.gif

不點(diǎn)擊中間圖片的話滩届,只有外圈在旋轉(zhuǎn),看起來(lái)就像雷達(dá)探測(cè)一樣被啼。點(diǎn)擊中間圖片中間圖片會(huì)進(jìn)行縮放帜消,還會(huì)產(chǎn)生"波紋",效果看起蠻好玩吧。

接下來(lái)先看定義的變量吧:

/**中間的圖片*/
private Bitmap mBitmap;
/**圖片寬度*/
private int mBitmapWidth;
/**圖片的高度*/
private int mBitmapHeight;
/** 圖片是否被點(diǎn)擊*/
private boolean mIsTouchBitmap = false;
/** 圖片縮放的比值*/
private float[] s = {1.05f, 1.1f, 1.15f, 1.2f, 1.25f, 1.2f, 1.1f, 1.0f, 0.9f, 0.8f, 0.75f, 0.8f, 0.9f, 1.0f};
/**圖片縮放的下標(biāo)*/
private int mScaleIndex = 0;
/**波紋的畫(huà)筆*/
private Paint mCirclePaint;
/** 點(diǎn)擊生成的波紋  記錄波紋的半徑*/
private List<Integer> mCircleRadiusArray = new ArrayList<>();
/** 外部圓的半徑*/
private int mExternalCircleRadius;
/** 初始圓的半徑大小*/
private int mInitCircleRadius;
/** 外圍旋轉(zhuǎn)的雷達(dá)圖片*/
private Bitmap mRadarBitmap;
/** 主要用于外圍雷達(dá)的旋轉(zhuǎn)*/
private Matrix mRadarMatrix;
/** 旋轉(zhuǎn)的角度*/
private int mRotateDegree;

接下來(lái)我們初始化一些需要后面需要用到的東西,加載圖片浓体,波紋的畫(huà)筆泡挺,設(shè)置初始波紋的半徑,和外圈的Matrix(用于旋轉(zhuǎn))命浴。
<pre>
private void init() {
//加載圖片
mBitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.welcome_radar_image);
mBitmapWidth = mBitmap.getWidth();
mBitmapHeight = mBitmap.getHeight();
//初始波紋的半徑 設(shè)置 比圖片的半徑多20
mInitCircleRadius = mBitmapWidth / 2 + 20;
//波紋畫(huà)筆的初始化
mCirclePaint = new Paint();
mCirclePaint.setColor(getResources().getColor(android.R.color.holo_red_light));
mCirclePaint.setStrokeWidth(10.0f);
mCirclePaint.setAntiAlias(true);
mCirclePaint.setStyle(Paint.Style.STROKE);
//主要用于外圈的旋轉(zhuǎn)
mRadarMatrix = new Matrix();
}
</pre>

接下來(lái)設(shè)置計(jì)算View的寬度和高度,如果布局中l(wèi)ayout_width是wrap_content的話,這里偷懶,View的寬度就為:圖片的寬度+400,高度也是一樣的娄猫。

<pre>
private int measureWidth(int measureSpec) {
int result = mBitmapWidth + 400;
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
if (specMode == MeasureSpec.EXACTLY) {
result = specSize;
} else {
result += getPaddingLeft()
+ getPaddingRight();
if (specMode == MeasureSpec.AT_MOST) {
// Respect AT_MOST value if that was what is called for by measureSpec
result = Math.min(result, specSize);
}
}
return result;
}
</pre>

<pre>
private int measureHeight(int measureSpec) {
int result = mBitmapHeight + 400;
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
if (specMode == MeasureSpec.EXACTLY) {

        result = specSize;
    } else {
        result += getPaddingTop()
                + getPaddingBottom();
        if (specMode == MeasureSpec.AT_MOST) {
            result = Math.min(result, specSize);
        }
    }
    return result;
}

</pre>

初始下外圈雷達(dá)的圖片,加載了圖片后發(fā)現(xiàn)圖片有點(diǎn)下生闲,所以用matrix放大下圖片
<pre>
//外圈的半徑
mExternalCircleRadius = getWidth() / 2 - 10;
//外圈的圖片
mRadarBitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.radar);
//根據(jù)外圈的半徑和圖片的大小計(jì)算放大的比例媳溺,然后放大~~
Matrix matrix = new Matrix();
matrix.setScale(mExternalCircleRadius * 2.0f / mRadarBitmap.getWidth(), mExternalCircleRadius * 2.0f / mRadarBitmap.getHeight());
//生成放大后的外圈圖片
mRadarBitmap = Bitmap.createBitmap(mRadarBitmap, 0, 0, mRadarBitmap.getWidth(), mRadarBitmap.getHeight(), matrix, true);
</pre>

接下來(lái)看下onDraw的方法:
<pre>
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//外圈開(kāi)始自動(dòng)旋轉(zhuǎn)
startRotateRadar(canvas);
//是否中間的圖片是否被點(diǎn)擊,如果被點(diǎn)擊了就開(kāi)始縮放圖片,否則就畫(huà)一個(gè)中間的圖不動(dòng)就好
if (mIsTouchBitmap) {
touchBitmapEvent(canvas);
} else {
canvas.drawBitmap(mBitmap, getWidth() / 2 - mBitmapWidth / 2, getHeight() / 2 - mBitmapHeight / 2, null);

    }
    //如果點(diǎn)擊了就會(huì)生成波紋碍讯,就是這個(gè)方法開(kāi)始畫(huà)波紋的
    startWave(canvas);
}

</pre>

按順序我們先看外圈旋轉(zhuǎn)的實(shí)現(xiàn):
<pre>
/**
* 開(kāi)始雷達(dá)
*/
private void startRotateRadar(Canvas canvas) {
//旋轉(zhuǎn)角度每次加2就好了
mRotateDegree = mRotateDegree + 2;
//開(kāi)始旋轉(zhuǎn)畫(huà)圖
mRadarMatrix.setRotate(mRotateDegree, mRadarBitmap.getWidth() / 2, mRadarBitmap.getHeight() / 2);
canvas.drawBitmap(mRadarBitmap, mRadarMatrix, null);
//每次都是延遲35毫秒進(jìn)行重繪
postInvalidateDelayed(35);
}
</pre>

接下來(lái)我們看點(diǎn)擊事件和中間圖片縮放的實(shí)現(xiàn):
1.實(shí)現(xiàn)onTouchEvent()
<pre>
@Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
float y = event.getY();

    //計(jì)算不在點(diǎn)擊返回的空間
    int leftSpace = (getWidth() - mBitmapWidth) / 2;
    int rightSpce = leftSpace + mBitmapWidth;
    int topSpace = (getHeight() - mBitmapHeight) / 2;
    int bottomSpace = topSpace + mBitmapHeight;

    switch (event.getAction()) {
        case MotionEvent.ACTION_UP:
            //判斷是否在點(diǎn)擊圖片
            if (x > leftSpace && x < rightSpce && y > topSpace && y < bottomSpace) {
                //中間圖片被點(diǎn)擊
                mIsTouchBitmap = true;
                //縮放下標(biāo)從0開(kāi)始
                mScaleIndex = 0;
                //波紋出現(xiàn)的時(shí)間延長(zhǎng)一點(diǎn)時(shí)間
                postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        mCircleRadiusArray.add(mInitCircleRadius);
                    }
                }, 400);
            }
            break;
    }
    return true;
}

</pre>

<pre>
/**
* 點(diǎn)擊圖片對(duì)圖片進(jìn)行放大縮小
*/
private void touchBitmapEvent(Canvas canvas) {
if (mIsTouchBitmap) {
if (mScaleIndex < s.length) {
//點(diǎn)擊對(duì)圖片進(jìn)行縮放和移動(dòng)處理
Matrix matrix = new Matrix();
matrix.setScale(s[mScaleIndex], s[mScaleIndex], mBitmap.getWidth() / 2, mBitmap.getHeight() / 2);
matrix.postTranslate(getWidth() / 2 - mBitmap.getWidth() / 2, getHeight() / 2 - mBitmap.getHeight() / 2);
canvas.drawBitmap(mBitmap, matrix, null);
mScaleIndex++;
} else {
//縮放完成..這個(gè)可能要改下
canvas.drawBitmap(mBitmap, getWidth() / 2 - mBitmapWidth / 2, getHeight() / 2 - mBitmapHeight / 2, null);
mIsTouchBitmap = false;
}
}
}
</pre>

如果點(diǎn)擊了,也就是在onTouchEvent方法中mIsTouchBitmap賦值為true后波紋就開(kāi)始了
<pre>
/** 開(kāi)始畫(huà)波紋*/
private void startWave(Canvas canvas) {
//每次點(diǎn)擊都會(huì)添加波紋的半徑到數(shù)組里面
if (mCircleRadiusArray.size() > 0) {
for (int i = 0; i < mCircleRadiusArray.size(); i++) {
//如果超過(guò)外圓的半徑就移除
if (mCircleRadiusArray.get(i) > mExternalCircleRadius - 5) {
mCircleRadiusArray.remove(i);
} else {
mCircleRadiusArray.set(i, mCircleRadiusArray.get(i) + 5);
//越接近外圈顏色越來(lái)越淺
float distance = mExternalCircleRadius - mCircleRadiusArray.get(i);
int circleAlpha = (int) (255.0f * (distance / (mExternalCircleRadius - mInitCircleRadius)));

                //越接近外圈波紋越細(xì)小
                float circleWidth = 10.0f * (distance / (mExternalCircleRadius - mInitCircleRadius));

//
mCirclePaint.setAlpha(circleAlpha);
mCirclePaint.setStrokeWidth(circleWidth);
canvas.drawCircle(getWidth() / 2, getWidth() / 2, mCircleRadiusArray.get(i), mCirclePaint);
}
}
}
}
</pre>

好了..這就是這個(gè)View的實(shí)現(xiàn)
Github地址:https://github.com/yuboxiaog/RadarDemo
如果有什么錯(cuò)誤的地方請(qǐng)見(jiàn)諒~~悬蔽。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市冲茸,隨后出現(xiàn)的幾起案子屯阀,更是在濱河造成了極大的恐慌,老刑警劉巖轴术,帶你破解...
    沈念sama閱讀 211,123評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件难衰,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡逗栽,警方通過(guò)查閱死者的電腦和手機(jī)盖袭,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人鳄虱,你說(shuō)我怎么就攤上這事弟塞。” “怎么了拙已?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,723評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵决记,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我倍踪,道長(zhǎng)系宫,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,357評(píng)論 1 283
  • 正文 為了忘掉前任建车,我火速辦了婚禮扩借,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘缤至。我一直安慰自己潮罪,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,412評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布领斥。 她就那樣靜靜地躺著嫉到,像睡著了一般。 火紅的嫁衣襯著肌膚如雪月洛。 梳的紋絲不亂的頭發(fā)上屯碴,一...
    開(kāi)封第一講書(shū)人閱讀 49,760評(píng)論 1 289
  • 那天,我揣著相機(jī)與錄音膊存,去河邊找鬼。 笑死忱叭,一個(gè)胖子當(dāng)著我的面吹牛隔崎,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播韵丑,決...
    沈念sama閱讀 38,904評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼爵卒,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了撵彻?” 一聲冷哼從身側(cè)響起钓株,我...
    開(kāi)封第一講書(shū)人閱讀 37,672評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎陌僵,沒(méi)想到半個(gè)月后轴合,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,118評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡碗短,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,456評(píng)論 2 325
  • 正文 我和宋清朗相戀三年受葛,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,599評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡总滩,死狀恐怖纲堵,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情闰渔,我是刑警寧澤席函,帶...
    沈念sama閱讀 34,264評(píng)論 4 328
  • 正文 年R本政府宣布,位于F島的核電站冈涧,受9級(jí)特大地震影響茂附,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜炕舵,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,857評(píng)論 3 312
  • 文/蒙蒙 一何之、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧咽筋,春花似錦溶推、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,731評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至睹耐,卻和暖如春辐赞,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背硝训。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,956評(píng)論 1 264
  • 我被黑心中介騙來(lái)泰國(guó)打工响委, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人窖梁。 一個(gè)月前我還...
    沈念sama閱讀 46,286評(píng)論 2 360
  • 正文 我出身青樓赘风,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親纵刘。 傳聞我的和親對(duì)象是個(gè)殘疾皇子邀窃,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,465評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,737評(píng)論 25 707
  • 老夫?yàn)榱私裉焓巧焚M(fèi)苦心啊,哈哈哈哈一直想模仿探探的一個(gè)雷達(dá)搜索效果(探探應(yīng)該用過(guò)吧假哎,就是和陌陌類(lèi)似的不可描述app...
    hongjay閱讀 2,418評(píng)論 1 28
  • 第一回 死於夜幕降臨後的吻 第兩回 到了時(shí)間便渺無(wú)音訊 第三回了 死於在大海中心呼喊 引來(lái)浪與鯊魚(yú) 然後連死兩回 ...
    Alfli閱讀 276評(píng)論 0 2
  • (二)聲音方向定位線索 1聲音方向定位線索 (1)雙耳強(qiáng)度差 (2)雙耳時(shí)間差 (3)雙耳周相差 原因: 兩耳的距...
    楷歌Kale閱讀 1,442評(píng)論 0 0