package com.example.asus.ndk.circlemenulayout; import android.content.Context; import android.util.AttributeSet; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView; import com.example.asus.ndk.R; public class CircleMenuLayout extends ViewGroup { //圆形直径 private int mRadius; //该容器内child item 默认尺寸 private static final float RADIO_DEFAULT_CHILD_DIMENSION = 1 / 4f; private static final float RADIO_PADDING_LAYOUT = 1 / 12f; private float mPadding; private double mStartAngle = 0; private String[] itemText; private int[] itemImgs; private int mMenuItemCount; private int mMenuLayoutId = R.layout.circle_menu_item; public CircleMenuLayout(Context context) { super(context); } public CircleMenuLayout(Context context, AttributeSet attrs) { super(context, attrs); setPadding(0,0,0,0); } public void setMenuItemIconsAndText(String[] text,int[] img){ if (text == null && img == null){ throw new IllegalArgumentException("菜单设置项最少一项"); } itemText = text; itemImgs = img; mMenuItemCount = itemImgs == null ? text.length : img.length; if (img != null && text != null){ mMenuItemCount = Math.min(img.length,text.length); } buildMenuItem(); } private void buildMenuItem() { for (int i = 0;i<mMenuItemCount;++i){ View view = inflateMenuView(i); initMenuItem(view,i); addView(view); }; } private View inflateMenuView(int childView){ LayoutInflater inflater = LayoutInflater.from(getContext()); View itemView = inflater.inflate(mMenuLayoutId,this,false); return itemView; } //初始化菜单 private void initMenuItem(View view,int position){ ImageView imageView = view.findViewById(R.id.circle_menu_img); TextView textView = view.findViewById(R.id.circle_menu_text); imageView.setVisibility(VISIBLE); imageView.setImageResource(itemImgs[position]); textView.setVisibility(VISIBLE); textView.setText(itemText[position]); } //设置menu itemView id public void setMenuItemLayoutId(int layoutId){ mMenuLayoutId = layoutId; } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); //丈量自身尺寸 measureMyself(widthMeasureSpec,heightMeasureSpec); //丈量自布局 measureChildView(); } private void measureMyself(int widthMeasureSpec,int heightMeasureSpec){ int resWidth = 0; int resHeight = 0; int width = MeasureSpec.getSize(widthMeasureSpec); int height = MeasureSpec.getSize(heightMeasureSpec); int widthMode = MeasureSpec.getMode(widthMeasureSpec); int heightMode = MeasureSpec.getMode(heightMeasureSpec); if (widthMode == MeasureSpec.EXACTLY || heightMode == MeasureSpec.EXACTLY){ resWidth = getSuggestedMinimumWidth(); resWidth = resWidth == 0 ? getWidth() : resWidth; resHeight = getSuggestedMinimumHeight(); resHeight = resHeight == 0 ? getHeight() : resHeight; }else { resWidth = resHeight = Math.min(width,height); } setMeasuredDimension(resWidth,resHeight); } private void measureChildView(){ mRadius = Math.max(getMeasuredWidth(),getMeasuredHeight()); //menu 数量 int menuCount = getChildCount(); //menu 尺寸 int childSize = (int) (mRadius * RADIO_DEFAULT_CHILD_DIMENSION); int childMode = MeasureSpec.EXACTLY; for (int i=0;i<menuCount;++i){ 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; } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { int childCount = getChildCount(); int left,top; int itemWidth = (int) (mRadius * RADIO_DEFAULT_CHILD_DIMENSION); float angleDelay = 360/childCount; for (int i=0;i<childCount;++i){ View child = getChildAt(i); if (child.getVisibility() == GONE){ continue; } mStartAngle %= 360; int distanceFromCenter = (int) (mRadius/2f - itemWidth/2 - mPadding); left = mRadius/2 + (int) Math.round(distanceFromCenter * Math.cos(Math.toRadians(mStartAngle))-1/2f*itemWidth); top = mRadius/2 + (int) Math.round(distanceFromCenter*Math.sin(Math.toRadians(mStartAngle))-1/2f*itemWidth); child.layout(left,top,left+itemWidth,top+itemWidth); mStartAngle += angleDelay; } } }
android 适配器模式训练(一)前期布局
最新推荐文章于 2023-10-30 18:47:24 发布