編輯:關於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,方便後續小圖標的加入,基本就是centerInParent和aliagnParentBottom,只是外圈小圖標的安排要稍微注意一下,這裡我們左半邊圖標以最左邊的一個圖標為基准,右半邊的圖標以最右邊的一個圖標為基准,在這裡分別是iv_channel1和iv_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;
}
}
}
Android使用ViewPager實現無限滑動效果
前言其實仔細想一下原理還是挺簡單的。無非是當我們滑動到最後一頁,再向後滑動時定位到第一頁;當我們滑動到第一頁,再向前滑動時定位到最後一頁。但是,相信很多朋友都遇到過這個問
Android手機截屏
剛開始打算做一個簡單的截屏程序時,以為很輕松就能搞定。 在Activity上放一個按鈕,點擊完成截屏操作,並將數據以圖片形式保存
Android界面編程——對話框控件(四)
2.5對話框控件對話框是提示用戶作出決定或輸入額外信息的小窗口。對話框不會填充屏幕,通常用於需要用戶采取行動才能繼續執行的模式事件。Android中常見跟對話框相關控件有
從零開始的Android新項目3 - 誰告訴你MVP和MVVM是互斥的
前言去年5月左右的時候,筆者在逛GitHub的時候,看到了一個MVP的項目,叫做mosby,仔細看了源碼和作者介紹的文章後,發現確實有點意思,雖然會需要多寫幾個類和方法,