Android仿優酷圓形菜單學習筆記分享_Android

來源:互聯網
上載者:User

先來看看效果:

首先來分析一下:

這個菜單可以分成三個菜單:

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>

以上就是本文的全部內容,希望對大家的學習有所協助,也希望大家繼續關注云棲社區的更多精彩內容!

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.