1. 程式人生 > >Andorid 八角盤(風水八宅圖)八圓輪簡單實現

Andorid 八角盤(風水八宅圖)八圓輪簡單實現

這裡寫圖片描述

風水八角盤

困,為了開源精神,繼續寫點部落格,證明一下自己的存在感。之前,專案需求說要做個八角八圓輪圖。聽了之後就矇蔽了。臥槽,好難,想想之後,好像有點思路。思路其實挺簡單,無非就是寫幾行程式碼嘛。廢話不多說,先上預覽圖。

這裡寫圖片描述

實現思路

1、八角背景圖
2、自定義ViewGroup實現八個圓輪位置+LL線性垂直佈局
3、採用FrameLayout佈局層疊

上碼不廢話

八角底部圖就不上了,UI一瞬間就秒出來~~~

XML碼

這裡就用幀佈局來是先把。。

<FrameLayout
                android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_gravity="center" android:layout_marginTop="@dimen/x15"> <com.eightbears.bear.ec.main.index.luopan.view.CircleLinearLayout app:circleRadius="@dimen/x100" android:layout_gravity="center_horizontal"
android:layout_width="@dimen/x300" android:layout_height="@dimen/x300" android:background="@mipmap/icon_bagua"> <android.support.v7.widget.LinearLayoutCompat android:id="@+id/ll_gua1" android:orientation="vertical"
android:layout_width="wrap_content" android:gravity="center" android:background="@mipmap/icon_baguaniu" android:layout_height="wrap_content"> <TextView android:id="@+id/tv_gua1" android:layout_width="wrap_content" android:textSize="@dimen/font_size_20" android:textColor="@color/text_color_333" android:layout_height="wrap_content" android:gravity="center" android:text="" /> <TextView android:id="@+id/tv_wei1" android:layout_marginTop="-2dp" android:layout_width="wrap_content" android:textSize="@dimen/font_size_15" android:layout_height="wrap_content" android:textColor="@color/text_bazai_red_c91d1d" android:gravity="center" android:text="" /> </android.support.v7.widget.LinearLayoutCompat> <android.support.v7.widget.LinearLayoutCompat android:id="@+id/ll_gua2" android:orientation="vertical" android:layout_width="wrap_content" android:gravity="center" android:background="@mipmap/icon_baguaniu" android:layout_height="wrap_content"> <TextView android:id="@+id/tv_gua2" android:layout_width="wrap_content" android:textSize="@dimen/font_size_20" android:textColor="@color/text_color_333" android:layout_height="wrap_content" android:gravity="center" android:text="" /> <TextView android:id="@+id/tv_wei2" android:layout_marginTop="-2dp" android:layout_width="wrap_content" android:textSize="@dimen/font_size_15" android:layout_height="wrap_content" android:textColor="@color/text_bazai_red_c91d1d" android:gravity="center" android:text="" /> </android.support.v7.widget.LinearLayoutCompat> <android.support.v7.widget.LinearLayoutCompat android:id="@+id/ll_gua3" android:orientation="vertical" android:layout_width="wrap_content" android:gravity="center" android:background="@mipmap/icon_baguaniu" android:layout_height="wrap_content"> <TextView android:id="@+id/tv_gua3" android:layout_width="wrap_content" android:textSize="@dimen/font_size_20" android:textColor="@color/text_color_333" android:layout_height="wrap_content" android:gravity="center" android:text="" /> <TextView android:id="@+id/tv_wei3" android:layout_marginTop="-2dp" android:layout_width="wrap_content" android:textSize="@dimen/font_size_15" android:layout_height="wrap_content" android:textColor="@color/text_bazai_red_c91d1d" android:gravity="center" android:text="" /> </android.support.v7.widget.LinearLayoutCompat> <android.support.v7.widget.LinearLayoutCompat android:id="@+id/ll_gua4" android:orientation="vertical" android:layout_width="wrap_content" android:gravity="center" android:background="@mipmap/icon_baguaniu" android:layout_height="wrap_content"> <TextView android:id="@+id/tv_gua4" android:layout_width="wrap_content" android:textSize="@dimen/font_size_20" android:textColor="@color/text_color_333" android:layout_height="wrap_content" android:gravity="center" android:text="" /> <TextView android:id="@+id/tv_wei4" android:layout_marginTop="-2dp" android:layout_width="wrap_content" android:textSize="@dimen/font_size_15" android:layout_height="wrap_content" android:textColor="@color/text_bazai_red_c91d1d" android:gravity="center" android:text="" /> </android.support.v7.widget.LinearLayoutCompat> <android.support.v7.widget.LinearLayoutCompat android:id="@+id/ll_gua5" android:orientation="vertical" android:layout_width="wrap_content" android:gravity="center" android:background="@mipmap/icon_baguaniu" android:layout_height="wrap_content"> <TextView android:id="@+id/tv_gua5" android:layout_width="wrap_content" android:textSize="@dimen/font_size_20" android:textColor="@color/text_color_333" android:layout_height="wrap_content" android:gravity="center" android:text="" /> <TextView android:id="@+id/tv_wei5" android:layout_marginTop="-2dp" android:layout_width="wrap_content" android:textSize="@dimen/font_size_15" android:layout_height="wrap_content" android:textColor="@color/text_bazai_red_c91d1d" android:gravity="center" android:text="" /> </android.support.v7.widget.LinearLayoutCompat> <android.support.v7.widget.LinearLayoutCompat android:id="@+id/ll_gua6" android:orientation="vertical" android:layout_width="wrap_content" android:gravity="center" android:background="@mipmap/icon_baguaniu" android:layout_height="wrap_content"> <TextView android:id="@+id/tv_gua6" android:layout_width="wrap_content" android:textSize="@dimen/font_size_20" android:textColor="@color/text_color_333" android:layout_height="wrap_content" android:gravity="center" android:text="" /> <TextView android:id="@+id/tv_wei6" android:layout_marginTop="-2dp" android:layout_width="wrap_content" android:textSize="@dimen/font_size_15" android:layout_height="wrap_content" android:textColor="@color/text_bazai_red_c91d1d" android:gravity="center" android:text="" /> </android.support.v7.widget.LinearLayoutCompat> <android.support.v7.widget.LinearLayoutCompat android:id="@+id/ll_gua7" android:orientation="vertical" android:layout_width="wrap_content" android:gravity="center" android:background="@mipmap/icon_baguaniu" android:layout_height="wrap_content"> <TextView android:id="@+id/tv_gua7" android:layout_width="wrap_content" android:textSize="@dimen/font_size_20" android:textColor="@color/text_color_333" android:layout_height="wrap_content" android:gravity="center" android:text="" /> <TextView android:id="@+id/tv_wei7" android:layout_marginTop="-2dp" android:layout_width="wrap_content" android:textSize="@dimen/font_size_15" android:layout_height="wrap_content" android:textColor="@color/text_bazai_red_c91d1d" android:gravity="center" android:text="" /> </android.support.v7.widget.LinearLayoutCompat> <android.support.v7.widget.LinearLayoutCompat android:id="@+id/ll_gua8" android:orientation="vertical" android:layout_width="wrap_content" android:gravity="center" android:background="@mipmap/icon_baguaniu" android:layout_height="wrap_content"> <TextView android:id="@+id/tv_gua8" android:layout_width="wrap_content" android:textSize="@dimen/font_size_20" android:textColor="@color/text_color_333" android:layout_height="wrap_content" android:gravity="center" android:text="" /> <TextView android:id="@+id/tv_wei8" android:layout_marginTop="-2dp" android:layout_width="wrap_content" android:textSize="@dimen/font_size_15" android:layout_height="wrap_content" android:textColor="@color/text_bazai_red_c91d1d" android:gravity="center" android:text="" /> </android.support.v7.widget.LinearLayoutCompat> </com.eightbears.bear.ec.main.index.luopan.view.CircleLinearLayout> <com.eightbears.bear.ec.main.index.luopan.view.CircleLinearLayout app:circleRadius="@dimen/x55" android:layout_gravity="center_horizontal" android:layout_width="@dimen/x300" android:layout_height="@dimen/x300" > <android.support.v7.widget.AppCompatImageView android:id="@+id/iv_jx1" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <android.support.v7.widget.AppCompatImageView android:id="@+id/iv_jx2" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <android.support.v7.widget.AppCompatImageView android:id="@+id/iv_jx3" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <android.support.v7.widget.AppCompatImageView android:id="@+id/iv_jx4" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <android.support.v7.widget.AppCompatImageView android:id="@+id/iv_jx5" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <android.support.v7.widget.AppCompatImageView android:id="@+id/iv_jx6" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <android.support.v7.widget.AppCompatImageView android:id="@+id/iv_jx7" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <android.support.v7.widget.AppCompatImageView android:id="@+id/iv_jx8" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </com.eightbears.bear.ec.main.index.luopan.view.CircleLinearLayout> <android.support.v7.widget.AppCompatTextView android:id="@+id/tv_gua_xiang" android:layout_width="wrap_content" android:text="震" android:textColor="@color/text_color_fff" android:textStyle="bold" android:layout_gravity="center" android:textSize="@dimen/font_size_36" android:layout_height="wrap_content" /> </FrameLayout>

這裡面的每個item其實就是一個LL再設定背景新增TV搞定。。。

 <android.support.v7.widget.LinearLayoutCompat
                        android:id="@+id/ll_gua1"
                        android:orientation="vertical"
                        android:layout_width="wrap_content"
                        android:gravity="center"
                        android:background="@mipmap/icon_baguaniu"
                        android:layout_height="wrap_content">
                        <TextView
                            android:id="@+id/tv_gua1"
                            android:layout_width="wrap_content"
                            android:textSize="@dimen/font_size_20"
                            android:textColor="@color/text_color_333"
                            android:layout_height="wrap_content"
                            android:gravity="center"
                            android:text="" />
                        <TextView
                            android:id="@+id/tv_wei1"
                            android:layout_marginTop="-2dp"
                            android:layout_width="wrap_content"
                            android:textSize="@dimen/font_size_15"
                            android:layout_height="wrap_content"
                            android:textColor="@color/text_bazai_red_c91d1d"
                            android:gravity="center"
                            android:text="" />
                    </android.support.v7.widget.LinearLayoutCompat>

自定義八等份View

這裡的核心是按照Circle的方式排列演算法。。。
這裡我們可以通過設定半徑來調整每個item到圓心的距離。。


public class CircleLinearLayout extends ViewGroup {

    private final String TAG = "CircleLinearLayout";
    private int radius;

    public CircleLinearLayout(Context context) {
        super(context);
    }

    public CircleLinearLayout(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public CircleLinearLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        final Resources res = getResources();
        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CircleLinearLayout);
        this.radius = a.getDimensionPixelSize(R.styleable.CircleLinearLayout_circleRadius, 10);

        Log.d(TAG, "radius = " + radius);
        a.recycle();
    }

    @Override
    public LayoutParams generateLayoutParams(AttributeSet attrs) {
//        return super.generateLayoutParams(attrs);
        return new MarginLayoutParams(getContext(),attrs);
    }

    /**
     * 計算所有ChildView的寬度和高度,然後根據ChildView的計算結果設定自己的寬度和高度
     * @param widthMeasureSpec
     * @param heightMeasureSpec
     */
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        /**
         * 獲取此ViewGroup上級容器為其推薦計算模式
         */
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);

        /**
         * 獲取此ViewGroup上級容器為其推薦的寬和高
         */
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);

        //計算出所有childView的寬和高,(通過ViewGroup的measureChildren方法為其所有的孩子設定寬和高,此行執行完成後,childView的寬和高都已經正確的計算過了)
        measureChildren(widthMeasureSpec, heightMeasureSpec);

        /**
         * ViewGroup內子控制元件的寬度和高度
         */
        int widthContent = 0;
        int heightContent = 0;

        int itemHeight =getChildAt(0).getMeasuredHeight();//單個childView的高度

        heightContent = (itemHeight+radius)*2;
        widthContent = (itemHeight+radius)*2;
//        Log.d(TAG + "onMeasure", "heightContent:"+heightContent);

        /**
         * 測量ViewGroup的寬高,如果為wrap_content就按照內容計算得到的寬高
         */
        setMeasuredDimension((widthMode == MeasureSpec.EXACTLY) ? widthSize : widthContent, (heightMode == MeasureSpec.EXACTLY) ? heightSize : heightContent);

    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
//        drawInHorizontal();
        drawInCircle();
    }

    /**
     * 按照Circle的方式排列
     */
    private void drawInCircle() {
        int cCount = getChildCount();
        int lastW = 0;

        //圓心座標
        float[] circleCentre = {getWidth()/2*1.0f, getHeight()/2*1.0f};

        //每個佔多少個弧度
//        float oItem = 360/cCount*1.0f;
        float oItem = (float) (2*Math.PI/cCount*1.0f);

        //cCount個座標
        float[][] xyPosition = new float[cCount][2];
        for (int i=0; i<cCount; i++)
        {
            xyPosition[i] = getXYPoint(circleCentre,radius,oItem*(i));

            //x座標
            int xLabel = (int) xyPosition[i][0];
            //y座標
            int yLabel = (int) xyPosition[i][1];

            Log.d(TAG, "position : (" + xLabel + "," + yLabel + ")");
            View view = getChildAt(i);
            view.layout((int) (xLabel - view.getMeasuredWidth() / 2 * 1.0f), (int) (yLabel - view.getMeasuredHeight() / 2 * 1.0f), (int) (xLabel + view.getMeasuredWidth() / 2 * 1.0f), (int) (yLabel + view.getMeasuredHeight() / 2 * 1.0f));
        }
    }

    /**
     * 按照horizontal的方式排列
     */
    private void drawInHorizontal() {
        int cCount = getChildCount();
        int lastW = 0;
        for (int i=0; i < cCount; i++){
            View view = getChildAt(i);
            view.layout(lastW,0,view.getWidth(),view.getHeight());
            lastW += view.getWidth();
            Log.i(TAG, "lastW = " + lastW);
        }
    }

    /**
     * 以原點為圓點,以radius維半徑畫圓,通過弧度o,獲得座標
     * @param radius 半徑
     * @param o 弧度
     * @return
     */
    public  float[] getXYPoint(float[] centrePoint, int radius, float o){
        Log.d(TAG,"o: "+o);
        Log.d(TAG,"radius: "+radius);
        Log.d(TAG,"centrePoint: ["+centrePoint[0]+","+centrePoint[1]+"]");
        float[] xyPoint = {(float) (radius*Math.sin(o) + centrePoint[0]), (float) ((-1)*radius*Math.cos(o) + centrePoint[1])};
//        Log.d(TAG,"test: ["+xyPoint[0]+","+xyPoint[1]+"]");
        return xyPoint;
    }
}

在values的attrs.xml檔案如下:
這裡我們可以在XML定義自定義View然後設定半徑 app:circleRadius=”@dimen/x55”
滿足我們專案中的需求。

<resources>
    <declare-styleable name="CircleLinearLayout">
        <attr name="circleRadius" format="dimension" />
</resources>

這裡就是巢狀2個自定義CircleLinearLayout+FrameLayout分層實現介面,然後每個Item都新增點選事件,完成。。。

當然,還有另外一種方法就是,動態新增item進行實現,或者新增item直接寫在自定義View裡面,這裡就先不展開了,如果讀者有更多方法歡迎開源。

需要原始碼的留言M我。

這裡寫圖片描述

相關推薦

Andorid 八角風水簡單實現

風水八角盤 困,為了開源精神,繼續寫點部落格,證明一下自己的存在感。之前,專案需求說要做個八角八圓輪圖。聽了之後就矇蔽了。臥槽,好難,想想之後,好像有點思路。思路其實挺簡單,無非就是寫幾行程式碼嘛。廢話不多說,先上預覽圖。 實現思路 1、八角背

POJ2826:An Easy Problem?!——題解配特殊情況

while 一次 mes bsp print 情況下 queue blank using http://poj.org/problem?id=2826 題目大意:給兩條線,讓它接豎直下的雨,問其能裝多少橫截面積的雨。 ———&mdas

優秀軟件測試工程師必備的8個能力!-附思維導

修改 ron 發展 數據庫架構 很多 針對 個人 run alt 結合自己以往的工作經驗,自己梳理出來一些材料,絕對原創,絕對幹貨。 優秀的軟件測試工程師必備的“8個能力” 作為一名軟件工程師,需要的能力並不多,但是要成為一名優秀的軟件測試工程師,需要的能力就比較多了,自己

POJ 1161 WallsFloyd , 建

== clas mem have 聚會 城市 define clu include 題意: 給定n個城市, 然後城市之間會有長城相連, 長城之間會圍成M個區域, 有L個vip(每個vip會處於一個城市裏)要找一個區域聚會, 問一共最少跨越多少個長城。 分析: 其實這題難就

【Bzoj4289】PA2012 TaxDijkstra+技巧建

down getc cmp priority 無向圖 mes post 起點 con Description 給出一個N個點M條邊的無向圖,經過一個點的代價是進入和離開這個點的兩條邊的邊權的較大值,求從起點1到點N的最小代價。起點的代價是離開起點的邊的邊權,終點的代價是進入

分布式學習最佳實踐:從分布式系統的特征開始附思維導

擴展 問題 sca ref 調度 這也 集中 技術 park     我的探索歷程   這一部分,與分布式不大相關,記錄的是我是如何在分布式學習這條道路上摸索的,不感興趣的讀者請直接跳到下一章。   過去的一年,我在分布式學習這條道路上苦苦徘徊,始終沒有找到一個好的學

網絡流平面圖轉對偶

ner 分享圖片 png 大小 向上 ron -m 無需 not https://zybuluo.com/ysner/note/1098815

學校私有雲私有雲存儲解決方案

批量 上傳下載 color 功能 上傳 存儲 調用 空間 私有雲 育網雲盤核心功能簡介 一,我們的是全平臺系統(web瀏覽器端,pc客戶端,安卓端,蘋果客戶端,微信端) 支持PC客戶海量文件上傳下載,系統穩定。 二,我們的PC客戶端是按百度雲盤,360雲盤一樣的,完全

【BZOJ】2007: [Noi2010]海拔平面圖轉對偶

using targe line problem max 最小 mem AR pop 題目 傳送門:QWQ 分析 左上角是0,右下角是1。那麽大概整張圖是由0 1構成的。 那麽我們要找到0和1的分界線,值就是最小割。 然後變成求原圖最小割。 考慮

CF85E Guard Towers二分答案+二分

std pan span code continue scanf \n () 連通 題意 已知 N 座塔的坐標,N≤5000 把它們分成兩組,使得同組內的兩座塔的曼哈頓距離最大值最小 在此前提下求出有多少種分組方案 mod 109+7 題解 二分答案 mid 曼哈頓距離

洛谷P4001 [BJOI2006]狼抓兔子平面圖轉對偶

bool .html next fine pri n) www moto tdi 傳送門 明明只要最小割加點優化就能過的東西…… 然而我偏偏要去學平面圖轉對偶圖結果發現課件關鍵地方看不清->這裏 而且建圖累的半死…

New Game! 最短路+建

std fab pre lse quest map n) 位置 str New Game! https://www.nowcoder.com/acm/contest/201/L 題目描述 Eagle Jump公司正在開發一款新的遊戲。Hifumi Takimoto作為其中

2018.10.30 NOIP模擬 有環無向dijkstra+巧妙建

傳送門 建圖巧妙啊。 對於每個點的出邊,我們將它們排序之後依次連邊。 這樣可以把 O (

【HDU - 1045】Fire Net dfs 或二分

題幹: Suppose that we have a square city with straight streets. A map of a city is a square board with n rows and n columns, each representing a str

資料結構之鄰接表 稀疏

<!DOCTYPE html> <html> <head>     <title>鄰接表</title>     <meta charset="utf-8">

C++中類的三種繼承方式public公有繼承、protected保護繼承、private私有繼承之間的差別附思維導【轉】

(轉自:https://blog.csdn.net/coco56/article/details/80467975) 注:若不指明繼承方式,則預設是私有繼承。 一:對於公有繼承(public)方式: 基類的public和protected成員的訪問屬性在派生類中保持不變,但基類的p

分散式學習最佳實踐:從分散式系統的特徵開始附思維導

什麼是分散式系統 回到頂部   分散式系統是由一組通過網路進行通訊、為了完成共同的任務而協調工作的計算機節點組成的系統。分散式系統的出現是為了用廉價的、普通的機器完成單個計算機無法完成的計算、儲存任務。其目的是利用更多的機器,處理更多的資料。   首先需要明確的是,只

Kruskal演算法實現最小生成樹鄰接矩陣儲存

程式碼如下: #include <stdio.h> #include <stdlib.h> #define MAXSIZE 100 typedef struct { int u; int v; int w; }Edges; void Bubblesort(

Prim演算法實現最小生成樹鄰接矩陣儲存

程式碼如下 #include <stdio.h> #include <stdlib.h> #define MAXSIZE 100 typedef struct { int vertex[MAXSIZE]; int edges[MAXSIZE][MAXSIZE];

資料結構——整理程式碼鄰接表儲存

資料結構圖相關程式碼整理記錄——鄰接表儲存圖 環境CodeBlocks17 執行通過 #include <iostream> #include <stdio.h> #include <stdlib.h> #include <queue> usi