最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Android自定義VIew實(shí)現(xiàn)衛(wèi)星菜單效果淺析

 更新時(shí)間:2016年11月08日 10:49:43   作者:wolf藝術(shù)  
這篇文章主要介紹了Android自定義VIew實(shí)現(xiàn)衛(wèi)星菜單效果淺析,非常不錯(cuò)具有參考借鑒價(jià)值,需要的朋友可以參考下

 一 概述:

最近一直致力于Android自定義VIew的學(xué)習(xí),主要在看《android群英傳》,還有CSDN博客鴻洋大神和wing大神的一些文章,寫的很詳細(xì),自己心血來(lái)潮,學(xué)著寫了個(gè)實(shí)現(xiàn)了類似衛(wèi)星效果的一個(gè)自定義的View,分享到博客上,望各位指點(diǎn)一二。寫的比較粗糙,見(jiàn)諒。(因?yàn)槭窃贚inux系統(tǒng)下寫的,效果圖我直接用手機(jī)拍的,難看,大家講究下就看個(gè)效果,勿噴)。

先來(lái)看個(gè)效果圖,有點(diǎn)不忍直視:

自定義VIew準(zhǔn)備:

(1)創(chuàng)建繼承自View的類;

(2)重寫構(gòu)造函數(shù);

(3)定義屬性。

(4)重寫onMeasure(),onLayout()方法。

好了,廢話不說(shuō)了,準(zhǔn)備上菜。

二 相關(guān)實(shí)現(xiàn)

首先是自定義的View,重寫構(gòu)造函數(shù),我這里是直接繼承的VIewGroup,貼上代碼:

public MoonView(Context context) { 
this(context,null); 
} 
public MoonView(Context context, AttributeSet attrs) { 
this(context, attrs,0); 
} 
public MoonView(Context context, AttributeSet attrs, int defStyleAttr) { 
super(context, attrs, defStyleAttr); 
}

這里需要讀取自定義的屬性,所以調(diào)用含三個(gè)參數(shù)的構(gòu)造函數(shù)。

自定義的屬性,我這里知定義了兩個(gè),一個(gè)是菜單弧形的半徑,還有個(gè)是菜單在屏幕的位置,這里可以設(shè)置在左上角,左下角,右上角,右下角。代碼如下:

<?xml version="1.0" encoding="utf-8"?> 
<resources> 
<declare-styleable name="MoonAttrs"> 
<attr name="mRadius" format="integer"></attr><!--菜單圓形半徑--> 
<attr name="mPosition"><!--衛(wèi)星菜單屏幕所在位置--> 
<enum name="leftTop" value="-2"></enum><!--左上角--> 
<enum name="leftBottom" value="-1"></enum><!--左下角--> 
<enum name="rightTop" value="-3"></enum><!--右上角--> 
<enum name="rightBottom" value="-4"></enum><!--右下角--> 
</attr> 
</declare-styleable> 
</resources>

然后在布局文件里面引用自定義的View,配置屬性:

<?xml version="1.0" encoding="utf-8"?> 
<com.example.liujibin.testmyview3.myView.MoonView 
xmlns:android="http://schemas.android.com/apk/res/android" 
xmlns:custom="http://schemas.android.com/apk/res/com.example.liujibin.testmyview3" 
android:orientation="vertical" 
android:layout_width="match_parent" 
android:layout_height="match_parent" 
custom:mRadius="400" 
custom:mPosition="rightBottom" 
> 
<ImageView 
android:layout_width="wrap_content" 
android:layout_height="wrap_content" 
android:background="@mipmap/sapi_icon_add_account"/> 
<ImageView 
android:layout_width="wrap_content" 
android:layout_height="wrap_content" 
android:background="@mipmap/sapi_icon_add_account"/> 
<ImageView 
android:layout_width="wrap_content" 
android:layout_height="wrap_content" 
android:background="@mipmap/sapi_icon_add_account"/> 
<ImageView 
android:layout_width="wrap_content" 
android:layout_height="wrap_content" 
android:background="@mipmap/sapi_icon_add_account"/> 
<ImageView 
android:layout_width="wrap_content" 
android:layout_height="wrap_content" 
android:background="@mipmap/sapi_icon_add_account"/> 
<ImageView 
android:layout_width="wrap_content" 
android:layout_height="wrap_content" 
android:background="@mipmap/sapi_icon_add_account"/> 
</com.example.liujibin.testmyview3.myView.MoonView>

最后我們需要在自定義的View類中的構(gòu)造函數(shù)里,獲取相關(guān)的屬性值:

public MoonView(Context context, AttributeSet attrs, int defStyleAttr) { 
super(context, attrs, defStyleAttr); 
//獲取相關(guān)屬性 
TypedArray ta = context.getTheme().obtainStyledAttributes(attrs, R.styleable.MoonAttrs, 
defStyleAttr,0); 
mRaius = ta.getInt(R.styleable.MoonAttrs_mRadius,500); 
position = ta.getInt(R.styleable.MoonAttrs_mPosition,-1); 
}

做完以上的準(zhǔn)備工作,我們就可以對(duì)組件進(jìn)行測(cè)量,布局。

@Override 
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
super.onMeasure(widthMeasureSpec, heightMeasureSpec); 
count = getChildCount()-1; 
angle = 90/(count-1); 

int count = getChildCount(); 
for(int i =0;i< count;i++){ 
measureChild(getChildAt(i),widthMeasureSpec,heightMeasureSpec); 
} 
}

count獲取按鈕的數(shù)量,有一個(gè)是中心點(diǎn),不參與計(jì)算,angle是每個(gè)按鈕離基準(zhǔn)線的角度,這里以90度為準(zhǔn),固定在這個(gè)范圍里面均勻分配。

首先先把中心點(diǎn)固定好位置:

@Override 
protected void onLayout(boolean b, int i, int i1, int i2, int i3) { 
if(isChanged){ 
layoutBottom(); 
} 
} 
private void layoutBottom(){ 
View view = getChildAt(0); 
switch (position){ 
case -1: 
btml = 0; 
btmt = getMeasuredHeight() - view.getMeasuredHeight(); 
btmr = view.getMeasuredWidth(); 
btmb = getMeasuredHeight(); 
break; 
case -2: 
btml = 0; 
btmt = 0; 
btmr = view.getMeasuredWidth(); 
btmb = view.getMeasuredHeight(); 
break; 
case -3: 
btml = getMeasuredWidth() - view.getMeasuredWidth(); 
btmt = 0; 
btmr = getMeasuredWidth(); 
btmb = view.getMeasuredHeight(); 
break; 
case -4: 
btml = getMeasuredWidth() - view.getMeasuredWidth(); 
btmt = getMeasuredHeight() - view.getMeasuredHeight(); 
btmr = getMeasuredWidth(); 
btmb = getMeasuredHeight(); 
break; 
} 
btmWidth = view.getMeasuredWidth(); 
btmHeight = view.getMeasuredHeight(); 
view.setOnClickListener(this); 
view.layout(btml,btmt,btmr,btmb); 
}

position的值看屬性就明白了,對(duì)中心點(diǎn)進(jìn)行固定位置。并且注冊(cè)點(diǎn)擊事件。

現(xiàn)在開(kāi)始給剩下的按鈕布局,并隱藏按鈕:

@Override 
protected void onLayout(boolean b, int i, int i1, int i2, int i3) { 
if(isChanged){ 
layoutBottom(); 
int count = getChildCount(); 
for(int k = 0;k < count - 1;k++){ 
View view = getChildAt(k+1); 
int childWidth = view.getMeasuredWidth(); 
int childHeight = view.getMeasuredHeight(); 
int childX = (int)(mRaius*(Math.sin(angle*(k)*Math.PI/180))); 
int childY = (int)(mRaius*(Math.cos(angle*(k)*Math.PI/180))); 
int left = 0; 
int top = 0; 
int right = 0; 
int bottom = 0; 
switch(position){ 
case -1: 
left = childX+btmWidth/2-childWidth/2; 
top =getMeasuredHeight() - (childY+childHeight/2+btmHeight/2); 
right = childX+btmWidth/2+childWidth/2; 
bottom =getMeasuredHeight() - (childY + btmHeight/2) + childHeight/2; 
break; 
case -2: 
left = childX+btmWidth/2-childWidth/2; 
top =childY-childHeight/2+btmHeight/2; 
right = childX+btmWidth/2+childWidth/2; 
bottom = childY + btmHeight/2 + childHeight/2; 
break; 
case -3: 
left = getMeasuredWidth() - (childX+btmWidth/2+childWidth/2); 
top =childY-childHeight/2+btmHeight/2; 
right = getMeasuredWidth() - (childX+btmWidth/2+childWidth/2)+childWidth; 
bottom = childY + btmHeight/2 + childHeight/2; 
break; 
case -4: 
left = getMeasuredWidth() - (childX+btmWidth/2+childWidth/2); 
top =getMeasuredHeight() - (childY+childHeight/2+btmHeight/2); 
right = getMeasuredWidth() - (childX+btmWidth/2+childWidth/2)+childWidth; 
bottom =getMeasuredHeight() - (childY + btmHeight/2) + childHeight/2; 
break; 
} 
view.layout(left,top,right,bottom); 
view.setVisibility(View.GONE); 
} 
} 
}

現(xiàn)在我們實(shí)現(xiàn)點(diǎn)擊事件:

@Override 
public void onClick(View view) { 
if(isChanged){ 
int count = getChildCount(); 
for(int i = 0;i < count - 1;i++){ 
View childView = getChildAt(i+1); 
int childX = (int)(mRaius*(Math.sin(angle*(i)*Math.PI/180))); 
int childY = (int)(mRaius*(Math.cos(angle*(i)*Math.PI/180))); 
int childWidth = view.getMeasuredWidth(); 
int childHeight = view.getMeasuredHeight(); 
int left = 0; 
int top = 0; 
TranslateAnimation ta = null; 
switch(position){ 
case -1: 
left = childX+btmWidth/2-childWidth/2; 
top =getMeasuredHeight() - (childY+childHeight/2+btmHeight/2); 
ta = new TranslateAnimation(-(left+childView.getMeasuredWidth()),0,getMeasuredHeight()-top,0); 
break; 
case -2: 
left = childX+btmWidth/2-childWidth/2; 
top =childY-childHeight/2+btmHeight/2; 
ta = new TranslateAnimation(-(left+childView.getMeasuredWidth()),0,-top,0); 
break; 
case -3: 
left = getMeasuredWidth() - (childX+btmWidth/2+childWidth/2); 
top =childY-childHeight/2+btmHeight/2; 
ta = new TranslateAnimation(getMeasuredWidth()-(left+childView.getMeasuredWidth()),0,-top,0); 
break; 
case -4: 
left = getMeasuredWidth() - (childX+btmWidth/2+childWidth/2); 
top =getMeasuredHeight() - (childY+childHeight/2+btmHeight/2); 
ta = new TranslateAnimation(getMeasuredWidth()-(left+childView.getMeasuredWidth()),0,getMeasuredHeight()-top,0); 
break; 
} 
ta.setDuration(500); 
childView.setAnimation(ta); 
childView.setVisibility(View.VISIBLE); 
} 
isChanged = false; 
}else{ 
int count = getChildCount(); 
for(int i = 0;i < count - 1;i++){ 
View childView = getChildAt(i+1); 
int childX = (int)(mRaius*(Math.sin(angle*(i)*Math.PI/180))); 
int childY = (int)(mRaius*(Math.cos(angle*(i)*Math.PI/180))); 
int childWidth = view.getMeasuredWidth(); 
int childHeight = view.getMeasuredHeight(); 
int left = 0; 
int top = 0; 
TranslateAnimation ta = null; 
switch(position){ 
case -1: 
left = childX+btmWidth/2-childWidth/2; 
top =getMeasuredHeight() - (childY+childHeight/2+btmHeight/2); 
ta = new TranslateAnimation(0,-(left+childView.getMeasuredWidth()),0,getMeasuredHeight()-top); 
break; 
case -2: 
left = childX+btmWidth/2-childWidth/2; 
top =childY-childHeight/2+btmHeight/2; 
ta = new TranslateAnimation(0,-(left+childView.getMeasuredWidth()),0,-top); 
break; 
case -3: 
left = getMeasuredWidth() - (childX+btmWidth/2+childWidth/2); 
top =childY-childHeight/2+btmHeight/2; 
ta = new TranslateAnimation(0,getMeasuredWidth()-(left+childView.getMeasuredWidth()),0,-top); 
break; 
case -4: 
left = getMeasuredWidth() - (childX+btmWidth/2+childWidth/2); 
top =getMeasuredHeight() - (childY+childHeight/2+btmHeight/2); 
ta = new TranslateAnimation(0,getMeasuredWidth()-(left+childView.getMeasuredWidth()),0,getMeasuredHeight()-top); 
break; 
} 
ta.setDuration(500); 
childView.setAnimation(ta); 
childView.setVisibility(View.GONE); 
} 
isChanged = true; 
} 
}

設(shè)置點(diǎn)擊顯示以及隱藏,并且?guī)эh動(dòng)的動(dòng)畫效果。

四個(gè)角落效果如下:






以上所述是小編給大家介紹的Android自定義VIew實(shí)現(xiàn)衛(wèi)星菜單效果淺析,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!

相關(guān)文章

  • RecyclerView上拉加載封裝代碼

    RecyclerView上拉加載封裝代碼

    這篇文章主要為大家詳細(xì)介紹了RecyclerView上拉加載封裝代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-08-08
  • Android實(shí)現(xiàn)網(wǎng)絡(luò)加載圖片點(diǎn)擊大圖后瀏覽可縮放

    Android實(shí)現(xiàn)網(wǎng)絡(luò)加載圖片點(diǎn)擊大圖后瀏覽可縮放

    這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)網(wǎng)絡(luò)加載圖片點(diǎn)擊大圖后瀏覽可縮放,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-12-12
  • 設(shè)置Android系統(tǒng)永不鎖屏永不休眠的方法

    設(shè)置Android系統(tǒng)永不鎖屏永不休眠的方法

    在進(jìn)行Android系統(tǒng)開(kāi)發(fā)的時(shí)候,有些特定的情況需要設(shè)置系統(tǒng)永不鎖屏,永不休眠。本篇文章給大家介紹Android 永不鎖屏,開(kāi)機(jī)不鎖屏,刪除設(shè)置中休眠時(shí)間選項(xiàng),需要的朋友一起學(xué)習(xí)吧
    2016-03-03
  • Android實(shí)現(xiàn)圖片加載進(jìn)度提示

    Android實(shí)現(xiàn)圖片加載進(jìn)度提示

    這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)圖片加載進(jìn)度提示,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-06-06
  • Android AAPT(Android Asset Packaging Tool)詳解

    Android AAPT(Android Asset Packaging Too

    AAPT - Android Asset Packaging Tool作用AAPT基本命令A(yù)APT編譯資源源碼解析AAPT打包和系統(tǒng)不一致的資源
    2024-04-04
  • Android 中 EventBus 的使用之多線程事件處理

    Android 中 EventBus 的使用之多線程事件處理

    這篇文章主要介紹了Android 中 EventBus 的使用之多線程事件處理的相關(guān)資料,需要的朋友可以參考下
    2015-11-11
  • 詳解Android應(yīng)用層制作LED指示燈

    詳解Android應(yīng)用層制作LED指示燈

    這篇文章主要介紹了詳解Android應(yīng)用層制作LED指示燈的相關(guān)資料,需要的朋友可以參考下
    2017-06-06
  • kotlin實(shí)現(xiàn)語(yǔ)音聊天機(jī)器人案例詳解

    kotlin實(shí)現(xiàn)語(yǔ)音聊天機(jī)器人案例詳解

    Android智能問(wèn)答機(jī)器人是時(shí)下非常流行的一種服務(wù),微軟“小冰”的出現(xiàn)更是讓其實(shí)實(shí)在在的風(fēng)靡了一把。那么,本文章就將帶領(lǐng)大家完整的實(shí)現(xiàn)整個(gè)問(wèn)答機(jī)器人的制作
    2023-02-02
  • Android WebView交互傳遞json字符串并解析的方法

    Android WebView交互傳遞json字符串并解析的方法

    這篇文章主要給大家介紹了關(guān)于Android中WebView交互傳遞json字符串并解析的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)各位Android開(kāi)發(fā)者具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。
    2018-05-05
  • Android實(shí)現(xiàn)手勢(shì)密碼功能

    Android實(shí)現(xiàn)手勢(shì)密碼功能

    這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)手勢(shì)密碼功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-12-12

最新評(píng)論

河池市| 嘉义县| 辉南县| 济源市| 密云县| 临泉县| 灌阳县| 民丰县| 尚义县| 大宁县| 饶河县| 万全县| 连南| 两当县| 梁平县| 峨眉山市| 大方县| 自治县| 绥德县| 龙门县| 永川市| 仪征市| 丘北县| 莱西市| 湟源县| 始兴县| 固安县| 民权县| 印江| 镇雄县| 湖北省| 拜城县| 郑州市| 沐川县| 崇文区| 茂名市| 堆龙德庆县| 富平县| 西乡县| 靖远县| 东乌珠穆沁旗|