Android實(shí)現(xiàn)弧形菜單效果
前言:公司需求,自己寫(xiě)的一個(gè)弧形菜單!
效果:

開(kāi)發(fā)環(huán)境:AndroidStudio2.2.1+gradle-2.14.1
涉及知識(shí):1.自定義控件,2.事件分發(fā)等
部分代碼:
public class HomePageMenuLayout extends ViewGroup {
private Context context;
// 菜單項(xiàng)的文本
private String[] mItemTexts = null;
private int StatusHeight;//狀態(tài)欄高度
public HomePageMenuLayout(Context context, AttributeSet attrs) {
super(context, attrs);
this.context = context;
StatusHeight = ScreenUtils.getStatusHeight(context);
}
/**
* 設(shè)置布局的寬高,并策略menu item寬高
*/
int resWidth = 0;
int resHeight = 0;
int mRadius = 0;
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//布局寬高尺寸設(shè)置為屏幕尺寸
//設(shè)置該布局的大小
setMeasuredDimension(widthMeasureSpec, heightMeasureSpec);
/**
* 根據(jù)傳入的參數(shù),分別獲取測(cè)量模式和測(cè)量值
*/
int width = MeasureSpec.getSize(widthMeasureSpec);
resHeight = MeasureSpec.getSize(heightMeasureSpec);
resWidth = MeasureSpec.getSize(widthMeasureSpec);
// 獲得半徑
mRadius = (int) (resHeight / 2 - 2 * StatusHeight);
//設(shè)置item尺寸
int childSize = (int) (mRadius * 1 / 2);
// menu item測(cè)量模式--精確模式
int childMode = MeasureSpec.EXACTLY;
for (int i = 0; i < getChildCount(); i++) {
final View child = getChildAt(i);
if (child.getVisibility() == GONE) {
continue;
}
// 計(jì)算menu item的尺寸;以及和設(shè)置好的模式,去對(duì)item進(jìn)行測(cè)量
int makeMeasureSpec = -1;
makeMeasureSpec = MeasureSpec.makeMeasureSpec(childSize, childMode);
child.measure(makeMeasureSpec, makeMeasureSpec);
}
}
/**
* item布局的角度
*/
private int[] widthall = null;
/**
* 設(shè)置Item的位置:第一個(gè)參數(shù)1:該參數(shù)指出當(dāng)前ViewGroup的尺寸或者位置是否發(fā)生了改變
* 2.當(dāng)期繪圖光標(biāo)橫坐標(biāo)位置
* 3.當(dāng)前繪圖光標(biāo)縱坐標(biāo)位置
*/
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
int left, top;
int cWidth = (int) (mRadius * 1 / 2);
final int childCount = getChildCount();
// 計(jì)算,中心點(diǎn)到menu item中心的距離
float tmp = mRadius - cWidth / 2;
// 遍歷去設(shè)置menuitem的位置
for (int i = 0; i < childCount; i++) {
final View child = getChildAt(i);
if (child.getVisibility() == GONE) {
continue;
}
left = (int) (mRadius * Math.cos(Math.toRadians(widthall[i]))) - 65;
top = (int) (mRadius - (resHeight / 2 - 2 * StatusHeight) * Math.sin(Math.toRadians(widthall[i])) - StatusHeight);
child.layout(left, top, left + cWidth, top + cWidth);
}
}
public interface OnMenuItemClickListener {
void itemClick(View view, int pos);
}
public void setOnMenuItemClickListener(
OnMenuItemClickListener mOnMenuItemClickListener) {
this.mOnMenuItemClickListener = mOnMenuItemClickListener;
}
// 菜單的個(gè)數(shù)
private int mMenuItemCount;
/**
* 設(shè)置菜單條目的圖標(biāo)和文本
*/
public void setMenuItemIconsAndTexts(String[] mItemTexts) {
this.mItemTexts = mItemTexts;
this.mMenuItemCount = mItemTexts.length;
resultAngle();
addMenuItems();
}
private void resultAngle() {
switch (this.mMenuItemCount) {
case 3:
widthall = Constants.ITEM3;
break;
case 4:
widthall = Constants.ITEM4;
break;
case 5:
widthall = Constants.ITEM5;
break;
case 6:
widthall = Constants.ITEM6;
break;
case 7:
widthall = Constants.ITEM7;
break;
case 8:
widthall = Constants.ITEM8;
break;
case 9:
widthall = Constants.ITEM9;
break;
case 10:
widthall = Constants.ITEM10;
break;
default:
break;
}
}
/**
* 設(shè)置菜單條目的圖標(biāo)和文本
*/
public void setMenuItemIconsAndTexts() {
addMenuItems();
}
private int mMenuItemLayoutId = R.layout.homepage_item_layout;
/**
* MenuItem的點(diǎn)擊事件接口
*/
private OnMenuItemClickListener mOnMenuItemClickListener;
private float yPosition = 0;
/**
* 添加菜單項(xiàng)
*/
private void addMenuItems() {
LayoutInflater mInflater = LayoutInflater.from(getContext());
/**
* 根據(jù)用戶設(shè)置的參數(shù),初始化view
*/
for (int i = 0; i < mMenuItemCount; i++) {
final int j = i;
View view = mInflater.inflate(mMenuItemLayoutId, this, false);
final ImageView iv = (ImageView) view
.findViewById(R.id.homepage_pager1_item_img);
final TextView tv = (TextView) view
.findViewById(R.id.homepage_pager1_item_tv);
if (iv != null) {
iv.setImageResource(R.mipmap.menu_ture);
}
if (tv != null) {
tv.setText(mItemTexts[i]);
}
view.findViewById(R.id.homepage_item_layout).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {}
});
view.findViewById(R.id.homepage_item_layout).setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
yPosition = event.getY();//獲取按下的位置
iv.setImageResource(R.mipmap.menu);
} else if (event.getAction() == MotionEvent.ACTION_UP) {
iv.setImageResource(R.mipmap.menu_ture);
float displacement = Math.abs(yPosition - event.getY());
//精確按下的位置做出響應(yīng)
if (mOnMenuItemClickListener != null&&displacement<25) {
mOnMenuItemClickListener.itemClick(v,j);
}
} else if (event.getAction() == MotionEvent.ACTION_CANCEL || event.getAction() == MotionEvent.ACTION_POINTER_UP) {
iv.setImageResource(R.mipmap.menu_ture);
}
return true;
}
});
addView(view);
}
}
}
以上就是本文的全部?jī)?nèi)容,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作能帶來(lái)一定的幫助,同時(shí)也希望多多支持腳本之家!
- Android實(shí)現(xiàn)自定義的衛(wèi)星式菜單(弧形菜單)詳解
- android圖像繪制(七)ClipRect局部繪圖/切割原圖繪制總結(jié)
- android圖像繪制(四)自定義一個(gè)SurfaceView控件
- android圖像繪制(二)畫(huà)布上放大縮小問(wèn)題
- android圖像繪制(六)獲取本地圖片或拍照?qǐng)D片等圖片資源
- android圖像繪制(五)畫(huà)布保存為指定格式/大小的圖片
- android圖像繪制(一)多種方法做圖像鏡像
- android圖像繪制(三)畫(huà)布刷屏問(wèn)題記錄
- Android開(kāi)發(fā)筆記之:在ImageView上繪制圓環(huán)的實(shí)現(xiàn)方法
- Android編程繪制圓形圖片的方法
- Android編程繪圖操作之弧形繪制方法示例
相關(guān)文章
Kotlin使用TransitionDrawable實(shí)現(xiàn)顏色漸變效果流程講解
這篇文章主要介紹了Kotlin使用TransitionDrawable實(shí)現(xiàn)顏色漸變效果,這里,我們通過(guò)TransitionDrawable顯示顏色漸變效果,包括背景顏色的變化,以及圖片與圖片的漸變效果2023-02-02
Android7.0版本影響開(kāi)發(fā)的改進(jìn)分析
這篇文章主要介紹了Android7.0版本影響開(kāi)發(fā)的改進(jìn),總結(jié)分析了Android7.0版本中比較常見(jiàn)的開(kāi)發(fā)注意事項(xiàng)與操作技巧,需要的朋友可以參考下2017-11-11
Handler消息傳遞機(jī)制類引入及執(zhí)行流程詳解
這篇文章主要為大家介紹了Handler消息傳遞機(jī)制類引入及執(zhí)行流程詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-04-04
Android開(kāi)發(fā)中的單例模式應(yīng)用詳解
這篇文章主要介紹了Android開(kāi)發(fā)中的單例模式應(yīng)用,結(jié)合實(shí)例形式詳細(xì)分析了Android開(kāi)發(fā)中常用單例模式的實(shí)現(xiàn)與使用方法,需要的朋友可以參考下2018-01-01
Android播放assets文件里視頻文件相關(guān)問(wèn)題分析
這篇文章主要介紹了Android播放assets文件里視頻文件相關(guān)問(wèn)題分析,結(jié)合Android播放assets文件出現(xiàn)錯(cuò)誤的實(shí)際問(wèn)題給出了原因分析與解決方法參考,需要的朋友可以參考下2016-08-08
Android RecyclerView的Item點(diǎn)擊事件實(shí)現(xiàn)整理
這篇文章主要介紹了Android RecyclerView的Item點(diǎn)擊事件實(shí)現(xiàn)整理的相關(guān)資料,需要的朋友可以參考下2017-01-01
android開(kāi)發(fā)之調(diào)用手機(jī)的攝像頭使用MediaRecorder錄像并播放
我們玩玩手機(jī)的錄像功能吧;今天做個(gè)調(diào)用手機(jī)的攝像頭使用MediaRecorder錄像并播放的DEMO,源碼很詳細(xì),感興趣的朋友可以了解下,希望本文對(duì)你有幫助2013-01-01
Android PopupWindow實(shí)現(xiàn)遮罩層效果
這篇文章主要為大家詳細(xì)介紹了Android PopupWindow實(shí)現(xiàn)遮罩層效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-10-10

