Android 弧形菜單設(shè)計

1.開發(fā)環(huán)境


Android Studio 3.0

Gradle版本:4.3

開發(fā)測試手機分辨率:720 * 1280

2.功能描述


? ? ? ? 弧形菜單布局使用常規(guī)布局模式也可以實現(xiàn),但在手機分辨率眾多,機型繁雜的情況下,這種自定義形狀的菜單設(shè)計就需要自己精細雕琢?;⌒尾藛卧O(shè)計在網(wǎng)上文章非常多,本人結(jié)合自己設(shè)計經(jīng)驗,簡單描述該功能重點實現(xiàn)部分,同時大多數(shù)文章只是在講述如果實現(xiàn)自定義布局,而對于如何結(jié)合控件縮放實現(xiàn)此功能的文章基本上很難找到。

3.軟件界面

橫屏布局
縱向布局

????????自定義弧形菜單,繼承ViewGroup,實現(xiàn)onMeasure和onLayout方法,同時為自定義控件添加菜單響應事件。

```

protected void onMeasure(int widthMeasureSpec,int heightMeasureSpec) {

????super.onMeasure(widthMeasureSpec, heightMeasureSpec);

????int measureWidth = measureWidth(widthMeasureSpec);

????int measureHeight = measureHeight(heightMeasureSpec);

????// 計算自定義的ViewGroup中所有子控件的大小

? ? measureChildren(widthMeasureSpec, heightMeasureSpec);

????// 設(shè)置自定義的控件MyViewGroup的大小

? ? setMeasuredDimension(measureWidth, measureHeight);

}

protected void onLayout(boolean changed,int l,int t,int r,int b) {

final int childCount = getChildCount();

//計算容器寬度和高度及內(nèi)圈與外圈半徑

? ? int viewWidth? = r - l;

int viewHeight = b - t;

int cx = (r + l)/2;

int cy = (t + b)/2;

int mRadius0 =0;

int mRadius1 =0;

mRadius0 = viewHeight/2 -20;//中間背景圓半徑

? ? mRadius1 = mRadius0 + (viewWidth/2 - mRadius0)/2;//圖標所在圓半徑

? ? int iIconSize = mRadius0*2/3;//圖標大小

? ? int mIntervalHeight =10;//圖標之間間隔高度

? ? if ( (5 * iIconSize +120) > viewWidth)

{

iIconSize = (viewWidth -120)/5;

mRadius0 =3 * iIconSize/2;

}

mIntervalHeight = (viewHeight -2 * mRadius0)/4;

mRadius1 = mRadius0 + (viewWidth/2 - mRadius0)/2;

//確定擺放方向及

? ? int mLeft =0;

// 遍歷子View

? ? for (int i =0; i < childCount; i++) {

View childView = getChildAt(i);

// 獲得子View的高度

? ? ? ? int childViewHeight = childView.getMeasuredHeight();

// 獲得子View的寬度

? ? ? ? int childViewWidth = childView.getMeasuredWidth();

if ( i ==0)

{

RelativeLayout.LayoutParams params? =new RelativeLayout.LayoutParams( mRadius0*2 , mRadius0*2);

childView.setLayoutParams(params);

childView.layout(cx - mRadius0, cy - mRadius0, cx + mRadius0, cy + mRadius0);

}

else if ( i ==1 || i==3 || i==4 || i==6)

{

RelativeLayout.LayoutParams params? =new RelativeLayout.LayoutParams( iIconSize , iIconSize);

childView.setLayoutParams(params);

//計算圖標所在X位置

? ? ? ? ? ? int y0 = mIntervalHeight + iIconSize/2;

int x0 = (int)(viewWidth/2 - Math.sqrt( mRadius1 * mRadius1 - (viewHeight/2 - y0) * (viewHeight/2 - y0)));

if ( i==3)

{

y0 = viewHeight - y0;

}

else if ( i==4)

{

x0 = viewWidth - x0;

}

else if ( i ==6)

{

x0 = viewWidth - x0;

y0 = viewHeight - y0;

}

int x = x0 - iIconSize/2;

int y = y0 - iIconSize/2;

childView.layout(x, y, x + iIconSize, y + iIconSize);

}

else if ( i ==2 || i==5 )

{

RelativeLayout.LayoutParams params? =new RelativeLayout.LayoutParams( iIconSize , iIconSize);

childView.setLayoutParams(params);

//計算圖標所在X位置

? ? ? ? ? ? int y0 = viewHeight/2;

int x0 = viewWidth/2 - mRadius1;

if ( i ==5)

{

x0 = viewWidth - x0;

}

int x = x0 - iIconSize/2;

int y = y0 - iIconSize/2;

childView.layout(x, y, x + iIconSize, y + iIconSize);

}

else if ( i ==7)

{

RelativeLayout.LayoutParams params? =new RelativeLayout.LayoutParams( iIconSize , iIconSize);

childView.setLayoutParams(params);

//計算圖標所在X位置

? ? ? ? ? ? int y0 = viewHeight/2;

int x0 = viewWidth/2;

int x = x0 - iIconSize/2;

int y = y0 - iIconSize/2;

childView.layout(x, y, x + iIconSize, y + iIconSize);

}

}

}

```

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容