// 圆形菜单
public class CircleMenuLayout extends ViewGroup {
// 圆形直径
private int mRadius;
// 该容器内child item的默认尺寸
private static final float RADIO_DEFAULT_CHILD_DIMENSION = 1 / 4f;
// 该容器的内边距,无视padding属性,如需边距请用该变量
private static final float RADIO_PADDING_LAYOUT = 1 / 12f;
// 该容器的内边距,无视padding属性,如需边距请用该变量
private float mPadding;
// 布局时的开始角度
private double mStartAngle = 0;
// 菜单项的文本
private String[] mItemTexts;
// 菜单项的图标
private int[] mItemImgs;
// 菜单的个数
private int mMenuItemCount;
// 菜单布局资源id
private int mMenuItemLayoutId = R.layout.circle_menu_item;
// MenuItem的点击事件接口
private OnItemClickListener mOnMenuItemClickListener;
public CircleMenuLayout(Context context, AttributeSet attrs) {
super(context, attrs);
// 无视padding
setPadding(0, 0, 0, 0);
}
// 设置菜单条目的图标和文本
public void setMenuItemIconsAndTexts(int[] images, String[] texts) {
if (images == null && texts == null) {
throw new IllegalArgumentException("菜单项文本和图片至少设置其一");
}
mItemImgs = images;
mItemTexts = texts;
// 初始化mMenuCount
mMenuItemCount = images == null ? texts.length : images.length;
if (images != null && texts != null) {
mMenuItemCount = Math.min(images.length, texts.length);
}
// 构建菜单项
buildMenuItems();
}
// 构建菜单项
private void buildMenuItems() {
// 根据用户设置的参数,初始化menu item
for (int i = 0; i < mMenuItemCount; i++) {
View itemView = inflateMenuView(i);
// 初始化菜单项
initMenuItem(itemView, i);
// 添加view到容器中
addView(itemView);
}
}
private View inflateMenuView(final int childIndex) {
LayoutInflater mInflater = LayoutInflater.from(getContext());
View itemView = mInflater.inflate(mMenuItemLayoutId, this, false);
itemView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (mOnMenuItemClickListener != null) {
mOnMenuItemClickListener.onClick(v, childIndex);
}
}
});
return itemView;
}
private void initMenuItem(View itemView, int childIndex) {
ImageView iv = (ImageView) itemView
.findViewById(R.id.id_circle_menu_item_image);
TextView tv = (TextView) itemView
.findViewById(R.id.id_circle_menu_item_text);
iv.setVisibility(View.VISIBLE);
iv.setImageResource(mItemImgs[childIndex]);
tv.setVisibility(View.VISIBLE);
tv.setText(mItemTexts[childIndex]);
}
// 设置MenuItem的布局文件,必须在setMenuItemIconsAndTexts之前调用
public void setMenuItemLayoutId(int mMenuItemLayoutId) {
this.mMenuItemLayoutId = mMenuItemLayoutId;
}
// 设置MenuItem的点击事件接口
public void setOnItemClickListener(OnItemClickListener listener) {
this.mOnMenuItemClickListener = listener;
}
// 代码省略
}
//设置布局的宽高,并策略menu item宽高
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// 丈量自身尺寸
measureMyself(widthMeasureSpec, heightMeasureSpec);
// 丈量菜单项尺寸
measureChildViews();
}
private void measureMyself(int widthMeasureSpec, int heightMeasureSpec) {
int resWidth = 0;
int resHeight = 0;
// 根据传入的参数,分别获取测量模式和测量值
int width = MeasureSpec.getSize(widthMeasureSpec);
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int height = MeasureSpec.getSize(heightMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
// 如果宽或者高的测量模式非精确值
if (widthMode != MeasureSpec.EXACTLY
|| heightMode != MeasureSpec.EXACTLY) {
// 主要设置为背景图的高度
resWidth = getSuggestedMinimumWidth();
// 如果未设置背景图片,则设置为屏幕宽高的默认值
resWidth = resWidth == 0 ? getDefaultWidth() : resWidth;
resHeight = getSuggestedMinimumHeight();
// 如果未设置背景图片,则设置为屏幕宽高的默认值
resHeight = resHeight == 0 ? getDefaultWidth() : resHeight;
} else {
// 如果都设置为精确值,则直接取小值;
resWidth = resHeight = Math.min(width, height);
}
setMeasuredDimension(resWidth, resHeight);
}
private void measureChildViews() {
// 获得半径
mRadius = Math.max(getMeasuredWidth(), getMeasuredHeight());
// menu item数量
final int count = getChildCount();
// menu item尺寸
int childSize = (int) (mRadius * RADIO_DEFAULT_CHILD_DIMENSION);
// menu item测量模式
int childMode = MeasureSpec.EXACTLY;
// 迭代测量
for (int i = 0; i < count; i++) {
final View child = getChildAt(i);
if (child.getVisibility() == GONE) {
continue;
}
// 计算menu item的尺寸;以及和设置好的模式,去对item进行测量
int makeMeasureSpec = -1;
makeMeasureSpec = MeasureSpec.makeMeasureSpec(childSize,
childMode);
child.measure(makeMeasureSpec, makeMeasureSpec);
}
mPadding = RADIO_PADDING_LAYOUT * mRadius;
}
// 布局menu item的位置
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
final int childCount = getChildCount();
int left, top;
// menu item 的尺寸
int itemWidth = (int) (mRadius * RADIO_DEFAULT_CHILD_DIMENSION);
// 根据menu item的个数,计算item的布局占用的角度
float angleDelay = 360 / childCount;
// 遍历所有菜单项设置它们的位置
for (int i = 0; i < childCount; i++) {
final View child = getChildAt(i);
if (child.getVisibility() == GONE) {
continue;
}
// 菜单项的起始角度
mStartAngle %= 360;
// 计算,中心点到menu item中心的距离
float distanceFromCenter = mRadius / 2f
- itemWidth / 2 - mPadding;
// distanceFromCenter cosa 即menu item中心点的left坐标
left = mRadius / 2 + (int)Math.round(distanceFromCenter
* Math.cos(Math.toRadians(mStartAngle))
* - 1 / 2f * itemWidth);
// distanceFromCenter sina 即menu item的纵坐标
top = mRadius / 2
+ (int) Math.round(distanceFromCenter
* Math.sin( Math.toRadians(mStartAngle) )
* - 1 / 2f * itemWidth);
// 布局child view
child.layout(left, top,
left + itemWidth, top + itemWidth);
// 叠加尺寸
mStartAngle += angleDelay;
}
}
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/bg" android:gravity="center" android:orientation="horizontal" > <com.dp.widgets.CircleMenuLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/id_menulayout" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/circle_bg" /> </LinearLayout>
public class MainActivity extends Activity {
private CircleMenuLayout mCircleMenuLayout;
// 菜单标题
private String[] mItemTexts = new String[] {
"安全中心 ", "特色服务", "投资理财",
"转账汇款", "我的账户", "信用卡"
};
// 菜单图标
Private int[] mItemImgs = new int[] {
R.drawable.home_mbank_1_normal,
R.drawable.home_mbank_2_normal, R.drawable.home_mbank_3_normal,
R.drawable.home_mbank_4_normal, R.drawable.home_mbank_5_normal,
R.drawable.home_mbank_6_normal
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 初始化圆形菜单
mCircleMenuLayout = (CircleMenuLayout)
findViewById(R.id.id_menulayout);
// 设置菜单数据项
mCircleMenuLayout.setMenuItemIconsAndTexts(mItemImgs,
mItemTexts);
// 设置菜单项点击事件
mCircleMenuLayout.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onClick(View view, int pos) {
Toast.makeText(MainActivity.this,
mItemTexts[pos],
Toast.LENGTH_SHORT).show();
}
});
}
}
// 圆形菜单
public class CircleMenuLayout extends ViewGroup {
// 字段省略
// 设置Adapter
public void setAdapter(ListAdapter mAdapter) {
this.mAdapter = mAdapter;
}
// 构建菜单项
private void buildMenuItems() {
// 根据用户设置的参数,初始化menu item
for (int i = 0; i < mAdapter.getCount(); i++) {
final View itemView = mAdapter.getView(i, null, this);
final int position = i;
itemView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (mOnMenuItemClickListener != null) {
mOnMenuItemClickListener.onClick(itemView, position);
}
}
});
// 添加view到容器中
addView(itemView);
}
}
@Override
protected void onAttachedToWindow() {
if (mAdapter != null) {
buildMenuItems();
}
super.onAttachedToWindow();
}
// 丈量、布局代码省略
}
static class MenuItem {
public int imageId;
public String title;
public MenuItem(String title, int resId) {
this.title = title;
imageId = resId;
}
}
static class CircleMenuAdapter extends BaseAdapter {
List<MenuItem> mMenuItems;
public CircleMenuAdapter(List<MenuItem> menuItems) {
mMenuItems = menuItems;
}
// 加载菜单项布局,并且初始化每个菜单
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
LayoutInflater mInflater = LayoutInflater.from(parent.getContext());
View itemView = mInflater.inflate(R.layout.circle_menu_item, parent, false);
initMenuItem(itemView, position);
return itemView;
}
// 初始化菜单项
private void initMenuItem(View itemView, int position) {
// 获取数据项
final MenuItem item = getItem(position);
ImageView iv = (ImageView) itemView
.findViewById(R.id.id_circle_menu_item_image);
TextView tv = (TextView) itemView
.findViewById(R.id.id_circle_menu_item_text);
// 数据绑定
iv.setImageResource(item.imageId);
tv.setText(item.title);
}
// 省略获取item count等代码
}
public class MainActivity extends Activity {
private ListView mListView;
List<MenuItem> mMenuItems = new ArrayList<MenuItem>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 模拟数据
mockMenuItems();
mListView = (ListView) findViewById(R.id.id_menulayout);
// 设置适配器
mListView.setAdapter(new CircleMenuAdapter(mMenuItems));
// 设置点击事件
mListView.setOnItemClickListener(new OnItemClickListener(){
@Override
public void onItemClick(AdapterView<?> parent,
View view, int position, long id) {
Toast.makeText(MainActivity.this,
mMenuItems.get(position).title,
Toast.LENGTH_SHORT).show();
}
});
}
机械节能产品生产企业官网模板...
大气智能家居家具装修装饰类企业通用网站模板...
礼品公司网站模板
宽屏简约大气婚纱摄影影楼模板...
蓝白WAP手机综合医院类整站源码(独立后台)...苏ICP备2024110244号-2 苏公网安备32050702011978号 增值电信业务经营许可证编号:苏B2-20251499 | Copyright 2018 - 2025 源码网商城 (www.ymwmall.com) 版权所有