实际实现
主页面布局文件
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:define="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center_horizontal" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".MainActivity" > <com.example.title.DefineViewGroup android:id="@+id/defineViewGroup1" android:layout_width="fill_parent" android:layout_height="fill_parent" > <com.example.title.DefineView android:layout_width="fill_parent" android:layout_height="fill_parent" define:stringtext="火车" define:viewcolor="#B1D548" /> <com.example.title.DefineView android:layout_width="fill_parent" android:layout_height="fill_parent" define:stringtext="酒店" define:viewcolor="#34D4F3" /> <com.example.title.DefineView android:layout_width="fill_parent" android:layout_height="fill_parent" define:stringtext="飞机" define:viewcolor="#F39023" /> <com.example.title.DefineView android:layout_width="fill_parent" android:layout_height="fill_parent" define:stringtext="飞机" define:viewcolor="#19C2C5" /> <com.example.title.DefineView android:layout_width="fill_parent" android:layout_height="fill_parent" define:stringtext="飞机" define:viewcolor="#1D9DF7" /> <com.example.title.DefineView android:layout_width="fill_parent" android:layout_height="fill_parent" define:stringtext="飞机" define:viewcolor="#E8BA23" /> <com.example.title.DefineView android:layout_width="fill_parent" android:layout_height="fill_parent" define:stringtext="飞机" define:viewcolor="#7F57EC" /> </com.example.title.DefineViewGroup> </RelativeLayout>
自定义view
package com.example.title; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.Paint.Align; import android.graphics.Paint.Style; import android.graphics.Path; import android.util.AttributeSet; import android.util.Log; import android.view.MotionEvent; import android.view.View; import android.view.animation.Animation; import android.view.animation.ScaleAnimation; public class DefineView extends View { private int mWidth; private int mHeight; private int centreX; private int centreY; private int mLenght; private Paint paint; private Bitmap bitmap; private String stringtext; private String paintcolor; public DefineView(Context context) { super(context); init(); } public DefineView(Context context, AttributeSet attrs) { super(context, attrs); TypedArray type=context.obtainStyledAttributes(attrs, R.styleable.defineView); stringtext=type.getString(R.styleable.defineView_stringtext); paintcolor=type.getString(R.styleable.defineView_viewcolor); init(); } private void init() { // TODO Auto-generated method stub bitmap=BitmapFactory.decodeResource(getResources(), R.drawable.icon_flight); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); mWidth = getWidth(); mHeight = getHeight(); // 计算中心点 centreX = mWidth / 2; centreY = mHeight / 2; mLenght = mWidth / 2; double radian30 = 30 * Math.PI / 180; float a = (float) (mLenght * Math.sin(radian30)); float b = (float) (mLenght * Math.cos(radian30)); float c = (mHeight - 2 * b) / 2; if (null == paint) { paint = new Paint(); paint.setAntiAlias(true); paint.setStyle(Style.FILL); paint.setColor(Color.parseColor(paintcolor)); paint.setAlpha(200); } Path path = new Path(); path.moveTo(getWidth(), getHeight() / 2); path.lineTo(getWidth() - a, getHeight() - c); path.lineTo(getWidth() - a - mLenght, getHeight() - c); path.lineTo(0, getHeight() / 2); path.lineTo(a, c); path.lineTo(getWidth() - a, c); path.close(); canvas.drawPath(path, paint); Paint paintcontent = new Paint(); paintcontent.setColor(Color.WHITE); paintcontent.setTextAlign(Align.CENTER); Matrix matrix=new Matrix(); matrix.postTranslate(this.getWidth() / 2 - bitmap.getWidth()/ 2, this.getHeight() / 2 - bitmap.getHeight() / 2-5); canvas.drawText(stringtext, this.getWidth()/2, this.getHeight()-5, paintcontent); canvas.drawBitmap(bitmap, matrix, paintcontent); /* 问:canvas.drawText("3", x, y, paint); x和y是指画得时候数字3中心的坐标吗?还是左上角的坐标? 答:x默认是‘3’这个字符的左边在屏幕的位置,如果设置了paint.setTextAlign(Paint.Align.CENTER);那就是字符的中心,y是指定这个字符baseline在屏幕上的位置。*/ } @Override public boolean onTouchEvent(MotionEvent event) { float start = 1.0f; float end = 0.92f; Animation scaleAnimation = new ScaleAnimation(start, end, start, end, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); Animation endAnimation = new ScaleAnimation(end, start, end, start, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); scaleAnimation.setDuration(100); scaleAnimation.setFillAfter(true); endAnimation.setDuration(100); endAnimation.setFillAfter(true); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: //判断的方法实际上就是点击的点 a(x,y) 与View的中心点c(x,y)之间距离组成的正方形的面积dist //与View内切园面积比较大小 float edgeLength = ((float) getWidth()) / 2; float radiusSquare = edgeLength * edgeLength * 3 / 4;//内切圆半径的平方,内切园面积 float dist = (event.getX() - getWidth() / 2) * (event.getX() - getWidth() / 2) + (event.getY() - getHeight() / 2) * (event.getY() - getHeight() / 2); if (dist <= radiusSquare) {// 点中六边形区域 paint.setAlpha(200); this.startAnimation(scaleAnimation); invalidate(); } break; case MotionEvent.ACTION_UP: paint.setAlpha(200); this.startAnimation(endAnimation); invalidate(); break; // 滑动出去不会调用action_up,调用action_cancel case MotionEvent.ACTION_CANCEL: this.startAnimation(endAnimation); invalidate(); break; } return true; } }
自定义viewgroup
package com.example.title; import android.content.Context; import android.util.AttributeSet; import android.view.View; import android.view.ViewGroup; import android.view.WindowManager; import android.view.View.MeasureSpec; public class DefineViewGroup extends ViewGroup { private static final int SPACE = 15;// view与view之间的间隔 private int width;//屏幕宽度 private int mlength;//边长,即为view 的宽度的一半 private float mheigth;//为view的高度的一半 private int viewWidth; private int viewHeight; private int offectY;//偏移量 private int offectX; public DefineViewGroup(Context context, AttributeSet attrs) { super(context, attrs); } @Override protected void onLayout(boolean arg0, int arg1, int arg2, int arg3, int arg4) { // TODO Auto-generated method stub WindowManager wm = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE); width = wm.getDefaultDisplay().getWidth(); mlength=(width-3*SPACE)/6;//边长 double radian30 = 30 * Math.PI / 180; mheigth = (float) (mlength * Math.cos(radian30));//竖向一半的view viewWidth=mlength*2; viewHeight=(int) (mheigth*2); offectY=(viewHeight+SPACE)/2; offectX=(int) (offectY*1.732);//横向移动间距 for (int i = 0; i < getChildCount(); i++) { View view0=getChildAt(0); View view1=getChildAt(1); view0.layout(SPACE, 0, viewWidth+SPACE, viewHeight); view1.layout(SPACE, viewHeight+SPACE, viewWidth+SPACE, viewHeight*2+SPACE); View view2=getChildAt(2); View view3=getChildAt(3); View view4=getChildAt(4); view2.layout(offectX+SPACE, offectY, viewWidth+offectX+SPACE, viewHeight+offectY); view3.layout(offectX+SPACE, offectY+viewHeight+SPACE, viewWidth+offectX+SPACE, viewHeight*2+offectY+SPACE); view4.layout(offectX+SPACE, offectY+(viewHeight+SPACE)*2, viewWidth+offectX+SPACE, viewHeight*3+offectY+SPACE*2); View view5=getChildAt(5); View view6=getChildAt(6); view5.layout(offectX*2+SPACE, offectY*2+viewHeight+SPACE, viewWidth+offectX*2+SPACE, viewHeight*2+offectY*2+SPACE); view6.layout(offectX*2+SPACE, offectY*2+(viewHeight+SPACE)*2, viewWidth+offectX*2+SPACE, viewHeight*3+offectY*2+SPACE*2); } } public int getStartX(int x){ return x-mlength; } public int getStartY(int y){ return (int)(y-mheigth); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { // TODO Auto-generated method stub super.onMeasure(widthMeasureSpec, heightMeasureSpec); int width = MeasureSpec.getSize(widthMeasureSpec); int height = MeasureSpec.getSize(heightMeasureSpec); setMeasuredDimension(width, height); //设置View 的高宽 for (int i = 0; i < getChildCount(); i++) { View child = getChildAt(i); child.measure(viewWidth,viewHeight); } } }
自定义属性
attr.xml
<?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="defineView"> <attr name="viewcolor" format="string"/> <attr name="stringtext" format="string"/> </declare-styleable> </resources>