先來看看效果:
首先來分析一下:
這個菜單可以分成三個菜單:
1.一級菜單(即最內圈那個菜單)
2.二級菜單(即中間圈那個菜單)
3.三級菜單(即最外圈那個菜單)
首先,可以將這三個菜單使用相對布局
一級菜單只有一個按鈕(即home),可以控制二級和三級菜單
二級菜單有三個按鈕(即menu),中間那個按鈕可以控制三級菜單
三級菜單有七個按鈕
那先把布局檔案先寫出來,採用三個相對布局(即每個菜單採用一個相對布局)
<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" tools:context="com.example.youkumenu.MainActivity" > <!-- 三級菜單 --> <RelativeLayout android:id="@+id/level3_Rl" android:layout_width="220dp" android:layout_height="110dp" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true" android:background="@drawable/level3" > <ImageView android:id="@+id/channel1" android:layout_marginLeft="5dp" android:layout_alignParentBottom="true" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/channel1"/> <ImageView android:id="@+id/channel2" android:layout_marginBottom="10dp" android:layout_marginLeft="25dp" android:layout_above="@id/channel1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/channel2"/> <ImageView android:layout_marginBottom="1dp" android:layout_marginLeft="52dp" android:layout_above="@id/channel2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/channel3"/> <ImageView android:layout_centerHorizontal="true" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/channel4"/> <ImageView android:id="@+id/channel7" android:layout_marginRight="5dp" android:layout_alignParentRight="true" android:layout_alignParentBottom="true" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/channel7"/> <ImageView android:id="@+id/channel6" android:layout_alignParentRight="true" android:layout_marginBottom="10dp" android:layout_marginRight="25dp" android:layout_above="@id/channel7" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/channel6"/> <ImageView android:layout_marginBottom="1dp" android:layout_marginRight="52dp" android:layout_alignParentRight="true" android:layout_above="@id/channel6" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/channel5"/> </RelativeLayout> <!-- 二級菜單 --> <RelativeLayout android:id="@+id/level2_Rl" android:layout_width="140dp" android:layout_height="70dp" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true" android:background="@drawable/level2" > <ImageView android:layout_marginLeft="3dp" android:layout_alignParentBottom="true" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/icon_search"/> <ImageView android:id="@+id/menu_Iv" android:layout_centerHorizontal="true" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/icon_menu"/> <ImageView android:id="@+id/myyouku_Iv" android:layout_marginRight="3dp" android:layout_alignParentBottom="true" android:layout_alignParentRight="true" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/icon_myyouku"/> </RelativeLayout> <!-- 一級菜單 --> <RelativeLayout android:layout_width="80dp" android:layout_height="40dp" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true" android:background="@drawable/level1" > <ImageView android:id="@+id/home_Iv" android:layout_centerInParent="true" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/icon_home" /> </RelativeLayout></RelativeLayout>
那好,布局寫好,就能看到這樣的效果,只不過現在只是靜態,沒有加邏輯而已
下面就該來分析下邏輯了,先來看看home(即一級菜單中間那個按鈕)
點擊home,會有三種情況,下面分情況考慮:
情況1.二級、三級菜單都顯示,就將二、三級菜單隱藏掉
情況2.二、三級菜單都不顯示的時候,就將二級菜單顯示
情況3.二級菜單顯示且三級菜單不顯示的時候,就將二級菜單隱藏
當然我們知道,要知道菜單隱藏或者顯示,只需要設個標記位即可
那要如何隱藏或顯示菜單,當然是使用動畫了,可以使用補間動畫和
屬性動畫,我這裡就使用補間動畫
下面就該來分析下邏輯了,先來看看menu(即二級菜單中間那個按鈕)
點擊menu,會有三種情況,下面分情況考慮:
情況1.三級顯示的時候,就將三級菜單隱藏
情況2.三級隱藏的時候,就將三級菜單顯示
這個就比較簡單了,就兩種情況。
public class MainActivity extends Activity implements OnClickListener{ //一級菜單中的home按鈕 private ImageView home_Iv; //二級菜單中的Menu按鈕 private ImageView menu_Iv; //用於判斷二級菜單的顯示狀況,true為顯示,false為隱藏 private boolean level2ListPlay = true; //用於判斷二級菜單的顯示狀況,true為顯示,false為隱藏 private boolean level3ListPlay = true; //二級和三級菜單 private RelativeLayout level2_Rl,level3_Rl; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView(); } //初始化組件 private void initView() { home_Iv = (ImageView) findViewById(R.id.home_Iv); home_Iv.setOnClickListener(this); level2_Rl = (RelativeLayout) findViewById(R.id.level2_Rl); level3_Rl = (RelativeLayout) findViewById(R.id.level3_Rl); menu_Iv = (ImageView) findViewById(R.id.menu_Iv); menu_Iv.setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.home_Iv: //點擊home按鈕的邏輯代碼 clickHomeIv(); break; case R.id.menu_Iv: clickMenuIv(); //點擊二級菜單中的menu按鈕的邏輯代碼 break; default: break; } } //點擊二級菜單中的menu按鈕的邏輯代碼 private void clickMenuIv() { //分情況考慮 //1.三級顯示的時候,就將三級菜單隱藏 if (level3ListPlay) { hideMenu(level3_Rl,0); level3ListPlay = false; return; } //2.三級隱藏的時候,就將三級菜單顯示 if (!level3ListPlay) { showMenu(level3_Rl); level3ListPlay = true; return; } } //點擊一級菜單中的home按鈕的邏輯代碼 private void clickHomeIv() { //分情況考慮 //1.二級、三級菜單都顯示,就將二、三級菜單隱藏掉 if (level2ListPlay && level3ListPlay) { //將二三級菜單隱藏,並改變標記 hideMenu(level2_Rl,300); hideMenu(level3_Rl,500); level2ListPlay = false; level3ListPlay = false; return; } //2.二、三級菜單都不顯示的時候,就將二級菜單顯示 if (!level2ListPlay && !level3ListPlay) { showMenu(level2_Rl); level2ListPlay = true; return; } //3.二級菜單顯示且三級菜單不顯示的時候,就將二級菜單隱藏 if (level2ListPlay && !level3ListPlay) { hideMenu(level2_Rl,0); level2ListPlay = false; return; } } /** * 顯示菜單 * @param view 要顯示的菜單 */ private void showMenu(RelativeLayout view) {// view.setVisibility(View.VISIBLE); //旋轉動畫 RotateAnimation animation = new RotateAnimation(-180, 0, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 1.0f); animation.setDuration(500); //設定動畫持續的時間 animation.setFillAfter(true); //動畫停留在動畫結束的位置 view.startAnimation(animation); } /** * 隱藏菜單 * @param view 要隱藏的菜單 ,startOffset 動畫順延強制的時間 */ private void hideMenu(RelativeLayout view,long startOffset) {// view.setVisibility(View.GONE); /** * 旋轉動畫 * RotateAnimation(fromDegrees, toDegrees, pivotXType, pivotXValue, pivotYType, pivotYValue) * fromDegrees 開始旋轉角度 * toDegrees 旋轉的結束角度 * pivotXType X軸 參照物 (X軸的伸縮模式,可以取值為ABSOLUTE、RELATIVE_TO_SELF) * pivotXValue x軸 旋轉的參考點(x座標的伸縮值) * pivotYType Y軸 參照物 (Y軸的伸縮模式,可以取值為ABSOLUTE、RELATIVE_TO_SELF) * pivotYValue Y軸 旋轉的參考點 ((Y座標的伸縮值) ) */ RotateAnimation animation = new RotateAnimation(0, -180, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 1.0f); animation.setDuration(500); animation.setFillAfter(true); //動畫停留在動畫結束的位置 animation.setStartOffset(startOffset); //設定動畫的順延強制 view.startAnimation(animation); }}
寫到這裡,應該差不多可以看到效果了,但是細心的夥伴應該會發現兩個bug:
第一:當你快速點擊一級菜單home按鈕或二級菜單menu按鈕的時候,會發現二級菜單或三級菜單的第一次動畫還沒執行完,又執行第二次動畫,看起來就在晃一樣。(原因:就是執行的動畫都設定了一定時間,你點擊的時間快於動畫執行的時間)
解決辦法:
對動畫進行監聽,當動畫開始執行和結束的時候,對它進行監聽,大家應該會想到用一個標記位來判斷,可我們知道一個標記為只能判斷兩種狀態,可這裡有兩種動畫(顯示的動畫和隱藏的動畫),一個標記位肯定不行,可以用一個Int值來控制
//用於記錄有多少個動畫在執行 private int annimationCount = 0; //對動畫進行監聽的時候 animation.setAnimationListener(new AnimationListener() { @Override public void onAnimationStart(Animation animation) {// menu_Iv.setOnClickListener(null);// home_Iv.setOnClickListener(null); annimationCount ++; } @Override public void onAnimationRepeat(Animation animation) { } @Override public void onAnimationEnd(Animation animation) {// menu_Iv.setOnClickListener(MainActivity.this);// home_Iv.setOnClickListener(MainActivity.this); annimationCount --; } //當點擊的時候就可以進行判斷,只要annimationCount值大於0,說明還有動畫在執行 if (annimationCount > 0) { return ; }
第二:當二級菜單隱藏的時候,你點擊二級菜單中menu按鈕(雖然現在看不見)時,你會驚奇的發現三級菜單居然顯示了。(原因:補間動畫,沒有真正的改變組件的屬性,而屬性動畫就不一樣,大家有時間可以試試屬性動畫做做)
解決辦法:
只要當二級菜單隱藏的時候,就讓二級菜單的所有選項按鈕都不可點。因為二級菜單有可以能有多個按鈕,所以拿到父容器,去使它的子控制項失去焦點即可。
//如果要顯示菜單,那麼就將相應的控制項設為有焦點 //擷取父容器中有幾個子控制項 int childCount = view.getChildCount(); for (int i = 0; i < childCount; i++) { view.getChildAt(i).setEnabled(true); }
寫到這裡就差不多了,大家可以試試
這裡把我寫的完整代碼貼出來:
public class MainActivity extends Activity implements OnClickListener{ //一級菜單中的home按鈕 private ImageView home_Iv; //二級菜單中的Menu按鈕 private ImageView menu_Iv; //用於判斷二級菜單的顯示狀況,true為顯示,false為隱藏 private boolean level2ListPlay = true; //用於判斷二級菜單的顯示狀況,true為顯示,false為隱藏 private boolean level3ListPlay = true; //二級和三級菜單 private RelativeLayout level2_Rl,level3_Rl; //用於記錄有多少個動畫在執行 private int annimationCount = 0; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView(); } //初始化組件 private void initView() { home_Iv = (ImageView) findViewById(R.id.home_Iv); home_Iv.setOnClickListener(this); level2_Rl = (RelativeLayout) findViewById(R.id.level2_Rl); level3_Rl = (RelativeLayout) findViewById(R.id.level3_Rl); menu_Iv = (ImageView) findViewById(R.id.menu_Iv); menu_Iv.setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.home_Iv: //點擊home按鈕的邏輯代碼 clickHomeIv(); break; case R.id.menu_Iv: clickMenuIv(); //點擊二級菜單中的menu按鈕的邏輯代碼 break; default: break; } } //點擊二級菜單中的menu按鈕的邏輯代碼 private void clickMenuIv() { //當點擊的時候就可以進行判斷,只要annimationCount值大於0,說明還有動畫在執行 if (annimationCount > 0) { return ; } //分情況考慮 //1.三級顯示的時候,就將三級菜單隱藏 if (level3ListPlay) { hideMenu(level3_Rl,0); level3ListPlay = false; return; } //2.三級隱藏的時候,就將三級菜單顯示 if (!level3ListPlay) { showMenu(level3_Rl); level3ListPlay = true; return; } } //點擊一級菜單中的home按鈕的邏輯代碼 private void clickHomeIv() { //當點擊的時候就可以進行判斷,只要annimationCount值大於0,說明還有動畫在執行 if (annimationCount > 0) { return ; } //分情況考慮 //1.二級、三級菜單都顯示,就將二、三級菜單隱藏掉 if (level2ListPlay && level3ListPlay) { //將二三級菜單隱藏,並改變標記 hideMenu(level2_Rl,300); hideMenu(level3_Rl,500); level2ListPlay = false; level3ListPlay = false; return; } //2.二、三級菜單都不顯示的時候,就將二級菜單顯示 if (!level2ListPlay && !level3ListPlay) { showMenu(level2_Rl); level2ListPlay = true; return; } //3.二級菜單顯示且三級菜單不顯示的時候,就將二級菜單隱藏 if (level2ListPlay && !level3ListPlay) { hideMenu(level2_Rl,0); level2ListPlay = false; return; } } /** * 顯示菜單 * @param view 要顯示的菜單 */ private void showMenu(RelativeLayout view) {// view.setVisibility(View.VISIBLE); //如果要顯示菜單,那麼就將相應的控制項設為有焦點 //擷取父容器中有幾個子控制項 int childCount = view.getChildCount(); for (int i = 0; i < childCount; i++) { view.getChildAt(i).setEnabled(true); } //旋轉動畫 RotateAnimation animation = new RotateAnimation(-180, 0, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 1.0f); animation.setDuration(500); //設定動畫持續的時間 animation.setFillAfter(true); //動畫停留在動畫結束的位置 view.startAnimation(animation); animation.setAnimationListener(new AnimationListener() { @Override public void onAnimationStart(Animation animation) { //動畫開始的時候回調// menu_Iv.setOnClickListener(null);// home_Iv.setOnClickListener(null); annimationCount ++; } @Override public void onAnimationRepeat(Animation animation) { //動畫執行程序呼叫 } @Override public void onAnimationEnd(Animation animation) { //動畫結束的時候調用// menu_Iv.setOnClickListener(MainActivity.this);// home_Iv.setOnClickListener(MainActivity.this); annimationCount --; } }); } /** * 隱藏菜單 * @param view 要隱藏的菜單 ,startOffset 動畫順延強制的時間 */ private void hideMenu(RelativeLayout view,long startOffset) {// view.setVisibility(View.GONE); //如果要隱藏菜單,那麼就將相應的控制項設為沒有焦點 //擷取父容器中有幾個子控制項 int childCount = view.getChildCount(); for (int i = 0; i < childCount; i++) { view.getChildAt(i).setEnabled(false); } /** * 旋轉動畫 * RotateAnimation(fromDegrees, toDegrees, pivotXType, pivotXValue, pivotYType, pivotYValue) * fromDegrees 開始旋轉角度 * toDegrees 旋轉的結束角度 * pivotXType X軸 參照物 (X軸的伸縮模式,可以取值為ABSOLUTE、RELATIVE_TO_SELF) * pivotXValue x軸 旋轉的參考點(x座標的伸縮值) * pivotYType Y軸 參照物 (Y軸的伸縮模式,可以取值為ABSOLUTE、RELATIVE_TO_SELF) * pivotYValue Y軸 旋轉的參考點 ((Y座標的伸縮值) ) */ RotateAnimation animation = new RotateAnimation(0, -180, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 1.0f); animation.setDuration(500); animation.setFillAfter(true); //動畫停留在動畫結束的位置 animation.setStartOffset(startOffset); //設定動畫的順延強制 view.startAnimation(animation); animation.setAnimationListener(new AnimationListener() { @Override public void onAnimationStart(Animation animation) {// menu_Iv.setOnClickListener(null);// home_Iv.setOnClickListener(null); annimationCount ++; } @Override public void onAnimationRepeat(Animation animation) { } @Override public void onAnimationEnd(Animation animation) {// menu_Iv.setOnClickListener(MainActivity.this);// home_Iv.setOnClickListener(MainActivity.this); annimationCount --; } }); }}
布局檔案:
<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" tools:context="com.example.youkumenu.MainActivity" > <!-- 三級菜單 --> <RelativeLayout android:id="@+id/level3_Rl" android:layout_width="220dp" android:layout_height="110dp" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true" android:background="@drawable/level3" > <ImageView android:id="@+id/channel1" android:layout_marginLeft="5dp" android:layout_alignParentBottom="true" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/channel1"/> <ImageView android:id="@+id/channel2" android:layout_marginBottom="10dp" android:layout_marginLeft="25dp" android:layout_above="@id/channel1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/channel2"/> <ImageView android:layout_marginBottom="1dp" android:layout_marginLeft="52dp" android:layout_above="@id/channel2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/channel3"/> <ImageView android:layout_centerHorizontal="true" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/channel4"/> <ImageView android:id="@+id/channel7" android:layout_marginRight="5dp" android:layout_alignParentRight="true" android:layout_alignParentBottom="true" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/channel7"/> <ImageView android:id="@+id/channel6" android:layout_alignParentRight="true" android:layout_marginBottom="10dp" android:layout_marginRight="25dp" android:layout_above="@id/channel7" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/channel6"/> <ImageView android:layout_marginBottom="1dp" android:layout_marginRight="52dp" android:layout_alignParentRight="true" android:layout_above="@id/channel6" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/channel5"/> </RelativeLayout> <!-- 二級菜單 --> <RelativeLayout android:id="@+id/level2_Rl" android:layout_width="140dp" android:layout_height="70dp" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true" android:background="@drawable/level2" > <ImageView android:layout_marginLeft="3dp" android:layout_alignParentBottom="true" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/icon_search"/> <ImageView android:id="@+id/menu_Iv" android:layout_centerHorizontal="true" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/icon_menu"/> <ImageView android:id="@+id/myyouku_Iv" android:layout_marginRight="3dp" android:layout_alignParentBottom="true" android:layout_alignParentRight="true" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/icon_myyouku"/> </RelativeLayout> <!-- 一級菜單 --> <RelativeLayout android:layout_width="80dp" android:layout_height="40dp" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true" android:background="@drawable/level1" > <ImageView android:id="@+id/home_Iv" android:layout_centerInParent="true" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/icon_home" /> </RelativeLayout></RelativeLayout>
以上就是本文的全部內容,希望對大家的學習有所協助,也希望大家繼續關注云棲社區的更多精彩內容!