当前位置: 代码迷 >> Android >> 自定义控件6:高仿安卓市场桌面悬浮菜单
  详细解决方案

自定义控件6:高仿安卓市场桌面悬浮菜单

热度:67   发布时间:2016-04-28 00:40:06.0
自定义控件六:高仿安卓市场桌面悬浮菜单

最近在学习自定义控件,无意中看到了手机上"安卓市场"桌面悬浮菜单,感觉很高大上,所以自己就简单照着样子做了一遍:

首先看原图:



涉及到的知识:

①首先这个控件是自定义的ViewGroup,需要知道自定义控件中的onMeasure、onLayout的用法。

onMeasure:主要是根据上一级推荐的宽高计算出当前控件的宽高,然后测量当前控件中的每一个子View。

onLayout:为当前控件中的每一个子View进行布局。

②初中所学的三角函数、反三角函数。

例如:

在数学中:sina = 对/斜  这里的a 角度值。

但是在Java中:sina = 对/斜     这里的a 弧度值,所以在java中要得到角度需要用Math.toRadians(a)函数将角度转化为弧度。


好了,回到代码处:

首先是activity_main.xml

<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="#e0000000"    android:gravity="center"    >    <cn.example.com.mycustomwidget_06_circlemenu_01.view.CustomCircleView        android:id="@+id/custom_father_rl"        android:background="@drawable/gears_box_float_main_background"        android:layout_width="355dip"        android:layout_height="301dip">        <RelativeLayout            android:id="@id/custom_circle_mean_center"            android:layout_width="wrap_content"            android:layout_height="wrap_content">            <ImageView                android:layout_centerInParent="true"                android:background="@drawable/gears_box_float_big_hexagon"                android:layout_width="167dip"                android:layout_height="187dip" />            <ImageView                android:layout_centerInParent="true"                android:background="@drawable/gears_box_float_big_hexagon_mask"                android:layout_width="152dip"                android:layout_height="172dip" />           </RelativeLayout>     </cn.example.com.mycustomwidget_06_circlemenu_01.view.CustomCircleView></LinearLayout>

然后是我们的每个条目的布局item文件circle_mean_item.xml 

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="wrap_content"    android:layout_height="wrap_content"    android:orientation="vertical"    android:gravity="center"    >    <ImageView        android:id="@id/custom_circle_mean_iv"        android:background="@drawable/gears_box_float_update_pressed"        android:layout_width="20dip"        android:layout_height="20dip" />    <TextView        android:textSize="13sp"        android:id="@id/custom_circle_mean_tv"        android:textColor="@android:color/white"        android:text="升级"        android:layout_width="wrap_content"        android:layout_height="wrap_content" /></LinearLayout>

最后是继承ViewGroup的自定义控件CustomCircleView

package cn.example.com.mycustomwidget_06_circlemenu_01.view;import android.content.Context;import android.util.AttributeSet;import android.util.DisplayMetrics;import android.util.Log;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.view.WindowManager;import android.widget.ImageView;import android.widget.LinearLayout;import android.widget.TextView;import java.util.zip.Inflater;import cn.example.com.mycustomwidget_06_circlemenu_01.R;/** * Created by Administrator on 2015/5/27. */public class CustomCircleView extends ViewGroup{    private onMeanItemClickListenner listenner;    //item大小为父控件大小的八分之一    private static final float MEAN_ITEM_SIZE = 1/6f;    //最中间item大小为父控件大小的六分之一    private static final float MEAN_ITEM_CENTER_SIZE = 1/3f;    //item间Padding大小为父控件大小的十二分之一    private static final float MEAN_ITEM_PADDING = 1/12f;    private static final String TAG = CustomCircleView.class.getSimpleName();    //直径    private float diameter;    //mean item大小    float meanItemSize;    //中间的mean item大小    float meanItemCenterSize;    public CustomCircleView(Context context, AttributeSet attrs) {        super(context, attrs);    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        int mWidth,mHeight;        int widthSize = MeasureSpec.getSize(widthMeasureSpec);        int widthMode = MeasureSpec.getMode(widthMeasureSpec);        int heightSize = MeasureSpec.getSize(heightMeasureSpec);        int heightMode = MeasureSpec.getMode(heightMeasureSpec);        if(widthMode != MeasureSpec.EXACTLY || heightMode != MeasureSpec.EXACTLY){            widthSize = getSuggestedMinimumWidth();            heightSize = getSuggestedMinimumHeight();            widthSize = widthSize == 0 ? getDefaultSize() : widthSize;            heightSize = heightSize == 0 ? getDefaultSize() : heightSize;            setMeasuredDimension(widthSize,heightSize);        }else{            mWidth = mHeight = Math.min(widthSize,heightSize);            setMeasuredDimension(mWidth,mHeight);        }        int measureSpec = 0;        diameter = Math.min(getMeasuredHeight(),getMeasuredWidth());        meanItemSize = diameter * MEAN_ITEM_SIZE;        meanItemCenterSize = diameter * MEAN_ITEM_CENTER_SIZE;        int meanItemMode = MeasureSpec.EXACTLY;        /**         * 依次测量mean item         */        int meanItemCount = getChildCount();        for(int i=0;i<meanItemCount;i++){            View childView = getChildAt(i);            if(childView.getId() == R.id.custom_circle_mean_center){                measureSpec = MeasureSpec.makeMeasureSpec((int) meanItemCenterSize,meanItemMode);                childView.measure(measureSpec,measureSpec);            }else{                measureSpec = MeasureSpec.makeMeasureSpec((int) meanItemSize,meanItemMode);                childView.measure(measureSpec,measureSpec);            }        }    }    @Override    protected void onLayout(boolean changed, int l, int t, int r, int b) {        /**         * 依次布局         */        int meanItemCount = getChildCount();        Log.d(TAG,"meanItemCount:"+meanItemCount);        float angle = 360 / meanItemCount;        float padding = diameter * MEAN_ITEM_PADDING;        float ItemAngle = 0;        //直角三角形的斜边        float hypotenuse = (diameter / 2) - padding - (meanItemSize / 2);        for(int i=0;i<meanItemCount;i++) {            View childView = getChildAt(i);            if (childView.getId() == R.id.custom_circle_mean_center) {                   continue;            }else{                ItemAngle %= 360;                int left = (int) (diameter /2 + (int) (Math.cos(Math.toRadians(ItemAngle)) * hypotenuse) - meanItemSize/2) ;                int top = (int) (diameter /2 + (int) (Math.sin(Math.toRadians(ItemAngle)) * hypotenuse) - meanItemSize/2);                int righe = (int) (left+meanItemSize);                int buttom = (int) (top+meanItemSize);                childView.layout(left, top, righe, buttom);                //TODO:如果是画最后一个控件,则合并                if(i == meanItemCount - 2){                    ItemAngle+=(angle+angle/2);                }else{                    ItemAngle += angle;                }            }        }        View meanCenterItem = findViewById(R.id.custom_circle_mean_center);        int cLeft = (int) (diameter/2 - meanItemCenterSize/2);        int cTop = (int) (diameter/2- meanItemCenterSize/2);        int cRight = (int) (cLeft + meanItemCenterSize);        int cButtom = (int) (cTop + meanItemCenterSize);        meanCenterItem.layout(cLeft, cTop, cRight, cButtom);        meanCenterItem.setOnClickListener(new OnClickListener() {            @Override            public void onClick(View v) {                listenner.onCenterMeanItemClick();            }        });    }    /**     * 得到默认布局大小     * @return     */    private int getDefaultSize(){        WindowManager windowManager = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);        DisplayMetrics displayMetrics = new DisplayMetrics();        windowManager.getDefaultDisplay().getMetrics(displayMetrics);        return  Math.min(displayMetrics.widthPixels,displayMetrics.heightPixels);    }    /**     * 设置文字和背景     * @param texts     * @param resIds     */    public void setTextsAndResIds(String texts[],int resIds[]){        if(texts == null || resIds == null){            throw new IllegalArgumentException("文字和图片不能为空");        }        int itemCount = Math.min(texts.length,resIds.length);        LayoutInflater inflater = LayoutInflater.from(getContext());        for(int i =0;i<itemCount;i++){            final int j = i;            View childView = inflater.inflate(R.layout.circle_mean_item,this,false);            ImageView iv = (ImageView) childView.findViewById(R.id.custom_circle_mean_iv);            TextView tv = (TextView) childView.findViewById(R.id.custom_circle_mean_tv);            iv.setBackgroundResource(resIds[i]);            tv.setText(texts[i]);            iv.setOnClickListener(new OnClickListener() {                @Override                public void onClick(View v) {                    if(listenner != null){                        listenner.onMeanItemClick(j);                    }                }            });            addView(childView);        }    }    public void setOnMeanItemClickListener(onMeanItemClickListenner listenner){        this.listenner = listenner;    }    /**     * mena item点击事件接口     */    public interface onMeanItemClickListenner{        void onMeanItemClick(int position);        void onCenterMeanItemClick();    }}


再最后是我们的MainActivity

package cn.example.com.mycustomwidget_06_circlemenu_01;import android.app.Activity;import android.os.Bundle;import android.widget.Toast;import cn.example.com.mycustomwidget_06_circlemenu_01.view.CustomCircleView;import static cn.example.com.mycustomwidget_06_circlemenu_01.view.CustomCircleView.onMeanItemClickListenner;public class MainActivity extends Activity {    private final String[] texts = new String[]{"软件升级","扫描","垃圾清理","分享","设置"};//    R.drawable.gears_box_float_update_normal    private int[] resIds = new int[]{            R.drawable.updata_selector,            R.drawable.scan_selector,            R.drawable.clean_selector,            R.drawable.share_selector ,            R.drawable.setting_selector        };    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        CustomCircleView ccv = (CustomCircleView) findViewById(R.id.custom_father_rl);        ccv.setTextsAndResIds(texts,resIds);        ccv.setOnMeanItemClickListener(new CustomCircleView.onMeanItemClickListenner(){            @Override            public void onMeanItemClick(int position){                Toast.makeText(MainActivity.this,texts[position].toString(),Toast.LENGTH_SHORT).show();            }            @Override            public void onCenterMeanItemClick(){                Toast.makeText(MainActivity.this,"center click!",Toast.LENGTH_SHORT).show();            }     });    }}

到此就结束了!!!看看效果图吧!



源码下载:http://download.csdn.net/detail/yushanfenghailin/8759033


转载请标明出处:http://blog.csdn.net/yushanddddfenghailin/article/details/46299819



  相关解决方案