android實現六邊形等不規則布局

來源:互聯網
上載者:User

標籤:

在去年廣告機項目中,UI設計出一個比較華麗的UI,但是對於我來說無從下手,我試過view的疊加並設定外邊距實現,雖然勉強可以實現,但是擷取單擊焦點是有很多問題; 
如下: 


最後只有另外想辦法;我對viewgroup進行了自訂,並且自訂了每個按鈕 
源碼:http://download.csdn.net/detail/hcb1230/6479979 
以下是我的實現方式: 
1.SpecailButton.java 

public class SpecailButton extends TextView implements View.OnClickListener {    private static final String TAG = "SpecailButton";        public static final int TEXT_ALIGN_LEFT              = 0x00000001;    public static final int TEXT_ALIGN_RIGHT             = 0x00000010;    public static final int TEXT_ALIGN_CENTER_VERTICAL   = 0x00000100;    public static final int TEXT_ALIGN_CENTER_HORIZONTAL = 0x00001000;    public static final int TEXT_ALIGN_TOP               = 0x00010000;    public static final int TEXT_ALIGN_BOTTOM            = 0x00100000;    /** 控制項畫筆 */    private Paint paint;    /** 文字的方位 */    private int textAlign;    /** 文字的顏色 */    private int textColor;    /** 控制項的寬度 */    private int viewWidth;    /** 控制項的高度 */    private int viewHeight;    /** 文本中軸線X座標 */    private float textCenterX;    /** 文本baseline線Y座標 */    private float textBaselineY;    private String text;    private FontMetrics fm;    private Context mContext;    private boolean checked = false;    public SpecailButton(Context context) {        super(context);        mContext = context;        init();    }    public SpecailButton(Context context, AttributeSet attrs, int defStyle) {        super(context, attrs, defStyle);        mContext = context;        init();    }    public SpecailButton(Context context, AttributeSet attrs) {        super(context, attrs);        mContext = context;        init();    }    /**     * 變數初始化     */    private void init() {        setOnClickListener(this);        text = getText().toString();        setText("");        paint = new Paint();        paint.setTextSize(22);        paint.setAntiAlias(true);        paint.setTextAlign(Align.CENTER);        //預設情況下文字置中顯示        textAlign = TEXT_ALIGN_CENTER_HORIZONTAL | TEXT_ALIGN_CENTER_VERTICAL;        //預設的文本顏色是黑色        textColor = Color.BLACK;    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        int wMode = MeasureSpec.getMode(widthMeasureSpec);        int wSize = MeasureSpec.getSize(widthMeasureSpec);        int hMode = MeasureSpec.getMode(heightMeasureSpec);        int hSize = MeasureSpec.getSize(heightMeasureSpec);        setMeasuredDimension(wSize, hSize);        Log.i(TAG, "onMeasure()--wMode=" + wMode + ",wSize=" + wSize + ",hMode=" + hMode+ ",hSize=" + hSize);        super.onMeasure(widthMeasureSpec, heightMeasureSpec);    }    @Override    protected void onLayout(boolean changed, int left, int top, int right,            int bottom) {        Log.i(TAG, "onLayout");        viewWidth = right - left;         viewHeight = bottom - top;        super.onLayout(changed, left, top, right, bottom);    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        //繪製控制項內容        setTextLocation(text);        canvas.drawText(text, textCenterX, textBaselineY, paint);    }    /**     * 定位文本繪製的位置     */    private void setTextLocation(String text) {//        paint.setTextSize(textSize);        paint.setColor(textColor);        fm = paint.getFontMetrics();        //文本的寬度        float textWidth = paint.measureText(text);        float textCenterVerticalBaselineY = viewHeight / 2 - fm.descent + (fm.descent - fm.ascent) / 2;        switch (textAlign) {        case TEXT_ALIGN_CENTER_HORIZONTAL | TEXT_ALIGN_CENTER_VERTICAL:            textCenterX = (float)viewWidth / 2;            textBaselineY = textCenterVerticalBaselineY;            break;        case TEXT_ALIGN_LEFT | TEXT_ALIGN_CENTER_VERTICAL:            textCenterX = textWidth / 2;            textBaselineY = textCenterVerticalBaselineY;            break;        case TEXT_ALIGN_RIGHT | TEXT_ALIGN_CENTER_VERTICAL:            textCenterX = viewWidth - textWidth / 2;            textBaselineY = textCenterVerticalBaselineY;            break;        case TEXT_ALIGN_BOTTOM | TEXT_ALIGN_CENTER_HORIZONTAL:            textCenterX = viewWidth / 2;            textBaselineY = viewHeight - fm.bottom;             break;        case TEXT_ALIGN_TOP | TEXT_ALIGN_CENTER_HORIZONTAL:            textCenterX = viewWidth / 2;            textBaselineY = -fm.ascent;            break;        case TEXT_ALIGN_TOP | TEXT_ALIGN_LEFT:            textCenterX = textWidth / 2;            textBaselineY = -fm.ascent;            break;        case TEXT_ALIGN_BOTTOM | TEXT_ALIGN_LEFT:            textCenterX = textWidth / 2;            textBaselineY = viewHeight - fm.bottom;             break;        case TEXT_ALIGN_TOP | TEXT_ALIGN_RIGHT:            textCenterX = viewWidth - textWidth / 2;            textBaselineY = -fm.ascent;            break;        case TEXT_ALIGN_BOTTOM | TEXT_ALIGN_RIGHT:            textCenterX = viewWidth - textWidth / 2;            textBaselineY = viewHeight - fm.bottom;             break;        }    }    public interface OnClickListener {        void onClick(View v, boolean checked);    }    private OnClickListener mListener;    public void setOnClickListener(OnClickListener listener) {        mListener = listener;    }    @Override    public void onClick(View v) {        checked = !checked;        setBackgroundResource(checked ? 0 : R.drawable.logo);        if (mListener != null) {            mListener.onClick(v, checked);        }    }    public String getTextString() {        return text;    }}


2.外面的父控制項: 

public class SpecailView extends ViewGroup {    private static final String TAG = "SpecailView";    private static final int RADIU_COUNT = 8;    private static final int PADDING = 10;    private int childRadius;    private int childWidth;    private int childHeight;    private int mChildCount;    private int centerX ,centerY;    public SpecailView(Context context) {        super(context);        Log.i(TAG, "SpecailView()");    }    public SpecailView(Context context, AttributeSet attrs, int defStyle) {        super(context, attrs, defStyle);        Log.i(TAG, "SpecailView( , , )");    }    public SpecailView(Context context, AttributeSet attrs) {        super(context, attrs);        Log.i(TAG, "SpecailView( , )");    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        int wMode = MeasureSpec.getMode(widthMeasureSpec);        int wSize = MeasureSpec.getSize(widthMeasureSpec);        int hMode = MeasureSpec.getMode(heightMeasureSpec);        int hSize = MeasureSpec.getSize(heightMeasureSpec);        setMeasuredDimension(wSize, hSize);        centerX = wSize / 2;        centerY = hSize / 2;        childRadius = (wSize - PADDING * 2) / RADIU_COUNT;        childWidth = childRadius * 2;        childHeight = (int)(childRadius * Math.sqrt(3) / 2)*2;        final int count = getChildCount();        for (int index = 0; index < count; index++) {            View child = getChildAt(index);            // measure            child.measure(childWidth, childHeight);        }        if (mChildCount != count) {            mChildCount = count;        }//        if (mChildCount > centers.size()) {            computerPoint(centerX, centerY, childHeight);//        }        Log.i(TAG, "onMeasure()--childWidth="+childWidth+",childHeight="+childHeight);        Log.i(TAG, "onMeasure()--wMode=" + wMode + ",wSize=" + wSize + ",hMode=" + hMode+ ",hSize=" + hSize);        super.onMeasure(widthMeasureSpec, heightMeasureSpec);    }    @Override    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {        final int count = getChildCount();        int childLeft, childTop;        for (int i = 0; i < count; i++) {            View child = getChildAt(i);            childLeft = (int)(centers.get(i).x-childRadius);            childTop =  (int)(centers.get(i).y-childHeight/2);            child.layout(childLeft, childTop, childLeft + childWidth, childTop + childHeight);        }        Log.i(TAG, "onLayout()--changed=" + changed + ",left=" + left + ",top=" + top + ",right="                + right + ",bottom=" + bottom + ",count=" + count);    }    private int getCircleIndex(int i) {        int index = 0;        while (i > (3*index*index + 3*index)) {            index ++;        }        return index;    }    /**     *  index start from 0     */    private int getCircleCount(int index) {        if (index == 0) {            return 1;        }        return index*6;    }    private void computerPoint(double a, double b, double h) {        double sqrt3 = Math.sqrt(3);        CircleCenteter c01 = new CircleCenteter(a, b);        CircleCenteter c11 = new CircleCenteter(a, b-h);        CircleCenteter c12 = new CircleCenteter(a + sqrt3*h/2, b - h/2);        CircleCenteter c13 = new CircleCenteter(a + sqrt3*h/2, b + h/2);        CircleCenteter c14 = new CircleCenteter(a, b + h);        CircleCenteter c15 = new CircleCenteter(a - sqrt3*h/2, b + h/2);        CircleCenteter c16 = new CircleCenteter(a - sqrt3*h/2, b - h/2);        CircleCenteter c21 = new CircleCenteter(a, b-2*h);        CircleCenteter c22 = new CircleCenteter(a + sqrt3*h/2, b-3*h/2);        CircleCenteter c23 = new CircleCenteter(a + sqrt3*h, b - h);        CircleCenteter c24 = new CircleCenteter(a + sqrt3*h, b);        CircleCenteter c25 = new CircleCenteter(a + sqrt3*h, b + h);        CircleCenteter c26 = new CircleCenteter(a + sqrt3*h/2, b + 3*h/2);        CircleCenteter c27 = new CircleCenteter(a, b + 2*h);        CircleCenteter c28 = new CircleCenteter(a - sqrt3*h/2, b + 3*h/2);        CircleCenteter c29 = new CircleCenteter(a - sqrt3*h, b + h);        CircleCenteter c210 = new CircleCenteter(a - sqrt3*h, b);        CircleCenteter c211 = new CircleCenteter(a - sqrt3*h, b - h);        CircleCenteter c212 = new CircleCenteter(a - sqrt3*h/2, b-3*h/2);        centers.clear();        centers.add(c01);        centers.add(c11);        centers.add(c12);        centers.add(c13);        centers.add(c14);        centers.add(c15);        centers.add(c16);        centers.add(c21);        centers.add(c22);        centers.add(c23);        centers.add(c24);        centers.add(c25);        centers.add(c26);        centers.add(c27);        centers.add(c28);        centers.add(c29);        centers.add(c210);        centers.add(c211);        centers.add(c212);    }    public void setOnItemClick(SpecailButton.OnClickListener l) {        int count = getChildCount();        for (int i = 0; i < count; i++) {            ((SpecailButton)getChildAt(i)).setOnClickListener(l);        }    }    private ArrayList<CircleCenteter> centers = new ArrayList<SpecailView.CircleCenteter>(7);    class CircleCenteter {        double x ,y;        public CircleCenteter(double x, double y){            this.x = x;            this.y = y;        }    }}


3.activity_main.xml 

<RelativeLayout 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" >    <com.qiang.testspecialview.SpecailView        android:id="@+id/specail_view"        android:layout_width="match_parent"        android:layout_height="400dip"        android:background="#78675645" >                <com.qiang.testspecialview.SpecailButton             android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:background="@drawable/logo"            android:gravity="center"            android:text="婚禮0"/>        <com.qiang.testspecialview.SpecailButton             android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:background="@drawable/logo"            android:gravity="center"            android:text="婚禮1"/>                <com.qiang.testspecialview.SpecailButton             android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:background="@drawable/logo"            android:gravity="center"            android:text="婚禮2"/>                <com.qiang.testspecialview.SpecailButton             android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:background="@drawable/logo"            android:gravity="center"            android:text="婚禮3"/>                <com.qiang.testspecialview.SpecailButton             android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:background="@drawable/logo"            android:gravity="center"            android:text="婚禮4"/>                <com.qiang.testspecialview.SpecailButton             android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:background="@drawable/logo"            android:gravity="center"            android:text="婚禮5"/>                <com.qiang.testspecialview.SpecailButton             android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:background="@drawable/logo"            android:gravity="center"            android:text="婚禮6"/>                <com.qiang.testspecialview.SpecailButton             android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:background="@drawable/logo"            android:gravity="center"            android:text="婚禮7"/>                <com.qiang.testspecialview.SpecailButton             android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:background="@drawable/logo"            android:gravity="center"            android:text="婚禮8"/>                <com.qiang.testspecialview.SpecailButton             android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:background="@drawable/logo"            android:gravity="center"            android:text="婚禮9"/>                <com.qiang.testspecialview.SpecailButton             android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:background="@drawable/logo"            android:gravity="center"            android:text="婚禮10"/>                <com.qiang.testspecialview.SpecailButton             android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:background="@drawable/logo"            android:gravity="center"            android:text="婚禮11"/>                <com.qiang.testspecialview.SpecailButton             android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:background="@drawable/logo"            android:gravity="center"            android:text="婚禮12"/>                <com.qiang.testspecialview.SpecailButton             android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:background="@drawable/logo"            android:gravity="center"            android:text="婚禮13"/>                <com.qiang.testspecialview.SpecailButton             android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:background="@drawable/logo"            android:gravity="center"            android:text="婚禮14"/>                <com.qiang.testspecialview.SpecailButton             android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:background="@drawable/logo"            android:gravity="center"            android:text="婚禮15"/>        <com.qiang.testspecialview.SpecailButton             android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:background="@drawable/logo"            android:gravity="center"            android:text="婚禮16"/>                <com.qiang.testspecialview.SpecailButton             android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:background="@drawable/logo"            android:gravity="center"            android:text="婚禮17"/>                <com.qiang.testspecialview.SpecailButton             android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:background="@drawable/logo"            android:gravity="center"            android:text="婚禮18"/>    </com.qiang.testspecialview.SpecailView></RelativeLayout>


4.MainActivity.java 

public class MainActivity extends Activity implements SpecailButton.OnClickListener  {    private SpecailView layout;    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        layout = (SpecailView)findViewById(R.id.specail_view);        layout.setOnItemClick(this);    }    @Override    public void onClick(View v, boolean checked) {        String text = ((SpecailButton)v).getTextString();        Toast.makeText(this, text + checked, Toast.LENGTH_SHORT).show();    }}


好了最後運行效果如下: 


有需要工程的,源碼:http://download.csdn.net/detail/hcb1230/6479979 

 

轉載自:http://www.sjsjw.com/kf_mobile/article/10_3422_10725.asp

android實現六邊形等不規則布局

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.