Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android自定義控件教程一:Android如何實現老版優酷客戶端三級環形菜單

Android自定義控件教程一:Android如何實現老版優酷客戶端三級環形菜單

編輯:關於Android編程


轉載請附上本文鏈接:http://blog.csdn.net/cyp331203/article/details/40423727


先來看看效果:

\



<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4KPHA+0rsmIzMwNTI0O7+0yc/IpbrDz/G7uc2m7MW1xKOsuNC+9bHIvc+4tNTToaOho6GjyrW8ysnPsqKyu8TRo6zPwsPmztLDx8C0v7S/tMjnus7Ktc/Wo7o8L3A+CjxwPrv5sb7L2LLEvs3Kx8/Cw+bI/bj2o7o8L3A+CjxwPjxicj4KPC9wPgo8cD48YnI+CjwvcD4KPHA+PGltZyBzcmM9"/uploadfile/Collfiles/20141025/20141025085738134.png" alt="\">\\



我們先來看看布局文件怎麼寫,實際上這裡這三張圖片都差不多,我們這裡使用RelativeLayout,方便後續小圖標的加入,基本就是centerInParentaliagnParentBottom,只是外圈小圖標的安排要稍微注意一下,這裡我們左半邊圖標以最左邊的一個圖標為基准,右半邊的圖標以最右邊的一個圖標為基准,在這裡分別是iv_channel1iv_channel7





    


        
    


    


        
        


        
        


        


    


    


        


        




        


        


        


        


        
    




布局完之後的效果:


\


之後我們就可以開始著手這個怎麼實現,我們的基本想法是(小房子圖標所在的為level1,第二圈灰色的部分為level2,最外圈為level3):

1、點擊小房子圖標,如果level2和level3都處於顯示狀態,則將這兩層都隱藏,如果這兩層都不存在,則只將level2顯示出來;如果只有level2顯示著,那麼將level2隱藏


2、點擊levle2的”三“字圖標,則實現隱藏和顯示level3組件


3、點擊手機的menu鍵,則實現如果level1,2,3都處於顯示狀態,則將三者都隱藏,如果只有level1、level2顯示,則將level1、2隱藏,如果只有level1顯示,則將level1隱藏;如果沒有任何level顯示著,則將level1和level2顯示出來


4、上面的顯示和隱藏的過程,都使用動畫來實現


基本邏輯關系已經理清楚了,那麼現在的問題就在於這個Animation如何寫;顯然我們這裡需要用到一個RotateAnimation旋轉動畫,由於這裡牽涉到旋出和旋入的效果,我們必須要清楚這個動畫的角度是如何定的,比如從0~180是旋入還是旋出效果?

經過實驗,我們發現,RotateAnimation的角度如下,我們可以發現,它的角度定義是按照順時針增長的

\


那麼按照這個角度來看,我們如果想要組件順時針旋入,同時順時針旋出的話,角度是要如何確定的呢


\

從上圖可以比較容易看出來,順時針旋出的話,角度是從0~180度,那麼旋入呢?是不是從180~0度?,實際上這裡旋入應該是180~360度。


在角度確定好之後呢,我們可以來著手實現動畫效果,這裡由於三個組件level1、level2、level3的動畫都是一致的,所以這裡選擇使用一個工具類,來實現幾個靜態方法,來定義動畫,達到復用的效果:

工具類如下:


package com.alexchen.youkumenuexercise.utils;

import android.view.View;
import android.view.animation.RotateAnimation;

public class AnimationUtils {
	//旋出的動畫,無延遲時間
	public static void startAnimationOut(View view) {
		startAnimationOut(view, 0);

	}
	//旋入的動畫,無延遲時間
	public static void startAnimationIn(View view) {
		startAnimationIn(view, 0);
	}
	
	//旋出的動畫
	//delay為動畫延遲的時間,單位是毫秒
	public static void startAnimationOut(View view, long delay) {
		RotateAnimation animation = new RotateAnimation(0, 180,
				view.getWidth() / 2, view.getHeight());
		animation.setDuration(500);
		animation.setStartOffset(delay);
		animation.setFillAfter(true);
		view.startAnimation(animation);

	}
	//旋入的動畫
	//delay為動畫延遲的時間,單位是毫秒
	public static void startAnimationIn(View view, long delay) {
		RotateAnimation animation = new RotateAnimation(180, 360,
				view.getWidth() / 2, view.getHeight());
		animation.setDuration(500);
		animation.setStartOffset(delay);
		animation.setFillAfter(true);
		view.startAnimation(animation);
	}

}



其中設置了兩個能夠延時開啟動畫的方法,為的是讓三個組件進出的時候能夠體現出層次感,讓用戶體驗更好。


最後是Activity中的代碼,這裡沒有做任何生命周期相關的處理,只是簡單的實現功能:


package com.alexchen.youkumenuexercise;

import com.alexchen.youkumenuexercise.utils.AnimationUtils;

import android.app.Activity;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageView;
import android.widget.RelativeLayout;

public class MainActivity extends Activity implements OnClickListener {

	private RelativeLayout level1;
	private RelativeLayout level2;
	private RelativeLayout level3;

	private ImageView iv_icon_menu;
	private ImageView iv_icon_home;
	/**
	 * 表示level3是否是現狀狀態,默認為true
	 */
	private boolean isLevel3In;
	private boolean isLevel2In;
	private boolean isLevel1In;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		isLevel3In = true;
		isLevel2In = true;
		isLevel1In = true;
		initViews();
		setOnclickListenersForViews();
	}

	/**
	 * 設置views的監聽事件
	 */
	private void setOnclickListenersForViews() {
		iv_icon_home.setOnClickListener(this);
		iv_icon_menu.setOnClickListener(this);

	}

	/**
	 * 初始化需要的view組件
	 */
	private void initViews() {
		level1 = (RelativeLayout) findViewById(R.id.level1);
		level2 = (RelativeLayout) findViewById(R.id.level2);
		level3 = (RelativeLayout) findViewById(R.id.level3);
		iv_icon_menu = (ImageView) findViewById(R.id.iv_icon_menu);
		iv_icon_home = (ImageView) findViewById(R.id.iv_icon_home);
	}

	/**
	 * activity響應的點擊事件
	 */
	@Override
	public void onClick(View v) {
		switch (v.getId()) {
		case R.id.iv_icon_menu:
			if (isLevel3In) {
				// 如果level3是顯示的,那麼就讓出去
				AnimationUtils.startAnimationOut(level3);
				isLevel3In = false;
			} else {
				// 如果level3是不顯示的,那麼讓其進入
				AnimationUtils.startAnimationIn(level3);
				isLevel3In = true;
			}

			break;
		case R.id.iv_icon_home:
			if (isLevel2In) {
				// 如果level2是顯示狀態
				AnimationUtils.startAnimationOut(level2, 200);
				isLevel2In = false;
			} else {
				AnimationUtils.startAnimationIn(level2);
				isLevel2In = true;
			}
			if (isLevel3In) {
				AnimationUtils.startAnimationOut(level3);
				isLevel3In = false;
			}

			break;

		default:
			break;
		}
	}

	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		if (keyCode == KeyEvent.KEYCODE_MENU) {
			// 如果是menu鍵按下的話:
			changeLevelState();

		}
		return super.onKeyDown(keyCode, event);
	}

	/**
	 * 改變三個圓環的狀態
	 */
	private void changeLevelState() {
		if (isLevel1In) {
			AnimationUtils.startAnimationOut(level1, 400);
			isLevel1In = false;
		} else {
			AnimationUtils.startAnimationIn(level1);
			isLevel1In = true;
		}
		if (isLevel2In) {
			AnimationUtils.startAnimationOut(level2, 200);
			isLevel2In = false;
		} else {
			AnimationUtils.startAnimationIn(level2, 200);
			isLevel2In = true;
		}
		if (isLevel3In) {
			AnimationUtils.startAnimationOut(level3);
			isLevel3In = false;
		}
	}

}




  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved