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 Walls(Floyd , 建圖)
== clas mem have 聚會 城市 define clu include 題意: 給定n個城市, 然後城市之間會有長城相連, 長城之間會圍成M個區域, 有L個vip(每個vip會處於一個城市裏)要找一個區域聚會, 問一共最少跨越多少個長城。 分析: 其實這題難就
【Bzoj4289】PA2012 Tax(Dijkstra+技巧建圖)
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