Android 首页六边形控件布局


 

实际实现

主页面布局文件

<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>

 

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM