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