編輯:關於Android編程
動畫在Android中是一個相當於重要的知識點,使用場景也很多,炫酷的界面效果少不了動畫來提升,這裡我們就先來說說Android中的動畫,在說Android的動畫之前,我們先來了解一下動畫這個效果的通用含義。
我們在平常生活中,經常會遇到動畫這個詞,大家也不要想歪了,可不是大家理解的島國xx片哦!,那動畫究竟是什麼吶?在不同的場景中,這個詞的名詞解釋都不一樣,那我們這裡也來討論一下動畫是什麼?
1,動畫就是動起來的畫
2,動畫最基本的一點就是能夠隨一定的時間間隔而變化
這個定義也是我總結的,感覺還挺契合這個概念,如果大家有異議,請告訴我,反正我也不會改的。
動畫的概念已經有了,那通用的動畫有哪些屬性吶,或者說具備哪些屬性,比如我有如下一個動畫:
從這個動畫我們能夠得出哪些屬性?
上面我大致總結了一下公共的屬性,這些屬性針對任何動畫都適用,可能還總結的不夠全,這裡只是起到一個拋磚引玉的作用。
定義有了,屬性有了,還有啥公共是屬性?那就是動畫的執行效果了,一般有單個動畫,就是一次只執行一個動畫,還有就是組合動畫了,多個動畫可以組合成,串行,並行,串並行動畫。
對公共的動畫我們大致就先說這麼多,現在開始轉移到我們的主題內容,Android動畫。接下的我們就來說說在Android中的動畫的一些概念和怎麼使用!
到這裡,我們終於今天本章的主題了。這裡主要來首先來說說視圖動畫,在下一章中我們會說說屬性動畫。視圖動畫與屬性動畫都同屬於Android,但是實現方式是完全不同的。
注意:視圖動畫只能作用於View,能夠實現的效果也僅限於上述的幾種和他們動畫的組合。
前面我們總結了動畫的通用屬性,那我們這裡就來看看Android中這些屬性的對應關系:
我們可以看到在Android中,屬性對應的名稱大致跟通用的總結的一致,至少看到名字就能理解意思。因此我們後面在實現動畫的時候就按照這些屬性來配置就ok了。
視圖動畫主要有兩種方式來實現:
1,xml實現,首先在res/anim目錄下定義動畫的xml文件,之後帶代碼中用AnimationUtils.loadAnimation()加載
2, 代碼實現,直接new對應的動畫實例來實現動畫。
我們來看幾個動畫效果,之後實例進行操作一遍:
在res/anim下定義動畫文件,我們分別定義漸變,平移,旋轉,縮放四個動畫文件:
漸變動畫,名稱為alpha.xml
fromAlpha表示動畫開始的透明度,toAlpha表示動畫結束的透明度,1.0表示完全不透明,0.0便是完全透明,兩個都是浮點數,duration便是動畫的持續時間,單位為毫秒,2000毫秒表示2秒。startOffset表示動畫開始的延遲時間,點擊開始1秒後開始執行,單位也是毫秒。
平移動畫,名稱為translate.xml
fromXDelta,fromYDelta表示動畫開始時的x,y坐標,toXDelta,toYDelta動畫結束的x,y坐標,這裡需要注意的是他可以設置三種類型的值,比如我們設置50:
50: 表示50個像素,是絕對值
50%: 表示自身大小一半,記住這裡是可以設置%號的,他等於0.5,如果設置0.5表示絕對值0.5
50%p :表示父元素大小的一半,p表示相對於父元素
縮放動畫,名稱為scale.xml
fromXScale,fromXScale動畫開始時x,y的縮放大小,toXScale,toXScale:動畫結束的x,y縮放大小,1表示本身大小,數值越大,縮放比例越大,pivotX,piovtY:縮放的中心坐標位置,可以設置值與平移動畫可以設置的類似:
50: 表示50個像素,是絕對值
50%: 表示自身中心位置
50%p :表示父元素的中心位置,p表示相對於父元素
旋轉動畫,名稱為rotate.xml
fromDegrees動畫開始的角度,toDegress動畫結束的角度,正數為順時針,負數為逆時針,pivotX,piovtY:旋轉的中心坐標位置,設置的方式與縮放相似。
xml文件定義好後,我們就需要在代碼中進行使用,可以先定義一個view,之後在界面中find出來,之後對view設置動畫:
private void rotate() { Animation rotate = AnimationUtils.loadAnimation(this, R.anim.rotate); imageView.startAnimation(rotate); } private void scale() { Animation scale = AnimationUtils.loadAnimation(this, R.anim.scale); imageView.startAnimation(scale); } private void translate() { Animation translate = AnimationUtils.loadAnimation(this, R.anim.translate); imageView.startAnimation(translate); } private void alpha() { Animation alpha = AnimationUtils.loadAnimation(this, R.anim.alpha); imageView.startAnimation(alpha); }
在代碼中,都需要先load動畫,采用AnimationUtils來進行load,之後將load出來的動畫設置到view上就可以了。
上面我們采用xml實現四種動畫,接下來我們用代碼來實現這個四種動畫:
private void rotate() { RotateAnimation rotate = new RotateAnimation(0, 360, Animation.RELATIVE_TO_SELF, 0.5f,Animation.RELATIVE_TO_SELF, 0.5f); rotate.setDuration(3000); imageView.startAnimation(rotate); } private void scale() { ScaleAnimation scale = new ScaleAnimation(1,2, 1, 2, Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF, 0.5f); scale.setDuration(3000); imageView.startAnimation(scale); } private void translate() { TranslateAnimation translate = new TranslateAnimation(0, 200, 0, 0); translate.setDuration(3000); imageView.startAnimation(translate); } private void alpha() { AlphaAnimation alpha = new AlphaAnimation(1.0f, 0.0f); alpha.setDuration(3000); imageView.startAnimation(alpha); }
從代碼可以看出,四種動畫都分別對應了不同的類,已經有四種現場的動畫類可以使用。每次使用只需要new對應的實例,設置不同的參數,參數設置也很簡單。這裡就不在詳細說了。
動畫我們已經實現了,但是如果你需要在動畫的執行過程中,做某些操作怎麼辦吶?比如在動畫開始的時候提示一下動畫的開始,在動畫的結束時,我們提示動畫的結束,這我們又能怎麼做吶?
系統也完全考慮到這個問題,我們可以對動畫設置監聽,可以對動畫設置AnimationListener,如下:
rotate.setAnimationListener(new Animation.AnimationListener() { @Override public void onAnimationStart(Animation animation) { //todo } @Override public void onAnimationEnd(Animation animation) { // todo next anim } @Override public void onAnimationRepeat(Animation animation) { } });
設置動畫監聽,在動畫開始結束等時機,系統都會回調對應的函數,比如onAnimationStart就是告訴動畫開始執行了。這樣我們就可以根據不同的回調做想要做的事情。
我們在抽象動畫的公共屬性說過,動畫有單個動畫,還有組合動畫,上面我們所實現的都是單個動畫,那怎麼實現組合動畫,組合動畫又分為串行動畫,並行動畫,或者既有串行又有並行。這些又怎麼實現:
多個單個動畫來實現我們需要實現如下效果的動畫,由於將MP4轉換成gif,效果變得很差,將就著看吧:
vcq9yrXP1qOseG1syrXP1tPrtPrC68q1z9ajrNXiwO/N8rHksrvA68bk19qjrNa7sru5/crHvavJz8PmtcS1pbj2tq+7rbCy17DQ6NKqtcTQp7n71+m6z9K7z8K+zW9ro6zPwsPmztLDx9PDeG1swLTKtc/W0rvPwrjDtq+7raO6PC9wPg0KPHA+tqjS5dK7uPZsb3ZlX2ZsYXkueG1sPC9wPg0KPHByZSBjbGFzcz0="brush:java;">
代碼加載上面的定義的xml。
private void loveAnim() { Animation animation = AnimationUtils.loadAnimation(this, R.anim.love_fly); love.startAnimation(animation); }
這樣我們就實現了上面要求的效果,那代碼方式又怎麼實現? 首先定義多個單個動畫,之後采用AnimationSet來實現,將定義的動畫都add到set中,比如我們需要實現一個在平移的過程中放大並且逐漸消失的動畫:
private void alpha() { AlphaAnimation alpha = new AlphaAnimation(1.0f, 0.0f); alpha.setDuration(3000); TranslateAnimation translate = new TranslateAnimation(0, 200, 0, 0); translate.setDuration(3000); ScaleAnimation scale = new ScaleAnimation(1,2, 1, 2, Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF, 0.5f); scale.setDuration(3000); AnimationSet set = new AnimationSet(true); set.addAnimation(alpha); set.addAnimation(translate); set.addAnimation(alpha); imageView.startAnimation(set); }
new AnimationSet(true),true表示是否公用插值器,後面我們會詳細說說插值器。
這裡我們就已經說完了怎麼實現組合動畫,之後我們來講講插值器是個啥!
說道插值器,我們首先要知道插值器是干什麼用的?
插值器控制動畫在時間軸上的變換效果
我們先來幾個效果:
我們分別就這幾個效果來做一下說明系統到底是怎麼來控制效果的,首先我們來看看AccelerateDecelerateInterpolator,該插值器是先加速後減速。
插值器中主要是根據getInterpolation來獲取某一個時間點的值,AccelerateDecelerateInterpolator的調用函數為(float)(Math.cos((input + 1) * Math.PI) / 2.0f) + 0.5f; 輸入范圍為0到1,根據這個函數我們可以生產如下的圖片:
從函數圖可以看出,當輸入在0到1中時,函數先加速後減速,系統就是靠這個來控制動畫的執行效果的。
我們在來看CycleInterpolator,該插值器有一個震蕩的效果,我們來看看他的調用函數:(float)(Math.sin(2 * mCycles * Math.PI * input)); mCycles = 2, input( 0, 1),mCycles為2表示震蕩兩次,我們來看看函數圖:
可以看到在0到1中循環了兩次。
從上面的可以看到如果你想實現特定的效果,只需要實現特定的插值器就好了。
上面我們執行了多個動畫,都發現每次執行完成後都回到了初始位置,那我們怎麼才能將動畫停止在最終位置?其實很容易實現該效果,只需要設置動畫的setFillAfter為true就可以了。
我們對動畫設置點擊事件,代碼如下:
public class LocationActivity extends AppCompatActivity { private ImageView love; public static void start(Context context) { Intent intent = new Intent(); intent.setClass(context, LocationActivity.class); context.startActivity(intent); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_location); findViews(); setViewListener(); } private void findViews() { love = (ImageView) findViewById(R.id.love); love.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Toast.makeText(LocationActivity.this, "clicked", Toast.LENGTH_LONG).show(); } }); } private void setViewListener() { findViewById(R.id.set).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { loveAnim(); } }); } private void loveAnim() { TranslateAnimation translate = new TranslateAnimation(0,0,0,-200); translate.setDuration(3000); translate.setFillAfter(true); love.startAnimation(translate); } }
執行後,發現動畫在最終位置不能點擊,而點擊事件還是在初始位置。
視圖動畫是不可交互動畫,點擊事件還是在初始位置
我們來看看如下效果:
首先我們需要定義一個動畫文件,但是該動畫文件不是放在res/anim下,而是放置drawable下面。
定義一個play_list.xml:
之後在代碼中進行加載:
public class FrameActivity extends AppCompatActivity implements View.OnClickListener { private ImageView frame; private AnimationDrawable drawable; public static void start(Context context) { Intent intent = new Intent(); intent.setClass(context, FrameActivity.class); context.startActivity(intent); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_frame); findViews(); setViewsListener(); } private void findViews() { frame = (ImageView) findViewById(R.id.frame); } private void setViewsListener() { findViewById(R.id.start).setOnClickListener(this); findViewById(R.id.end).setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.start: startAnim(); break; case R.id.end: stopAnim(); break; } } private void stopAnim() { if(drawable!=null){ if(drawable.isRunning()){ drawable.stop(); } } } private void startAnim() { if(drawable==null){ frame.setBackgroundResource(R.drawable.play_list); drawable = (AnimationDrawable) frame.getBackground(); drawable.setOneShot(true); } if(!drawable.isRunning()){ drawable.start(); } } }
將動畫文件設置為view的背景,之後在獲取出來為AnimationDrawable,setOneShot如果為true,表示只執行一次,start開始執行動畫,isRunning表示動畫知否在執行,stop停止動畫。其他屬性就不一一解釋了。
到此視圖動畫就講述完了,下一章來說說屬性動畫。
大家好,今天給大家分享的是解決解析圖片的出現oom的問題,我們可以用BitmapFactory這裡的各種Decode方法,如果圖片很小的話,不會出現oom,但是當圖片很大
在上篇文章的例子中,我們使用了一張圖片和一個文本作為每一行的數據,發現效果已經完全達到了,而且沒出現什麼問題。但如果我們將Item的數量調大,比如調到1000、10000
感覺 Android 到處都是坑,每個地方都要把人折騰半天。 今天來簡單說說 Android之ActionBar、Tabs、Fragment、ViewPager 實現標簽
中國移動推出的一卡多號業務可以在已有移動手機號上增加1-3個副號,不用換機、換卡。特別適合想擁有多個手機號碼的用戶或需要保護隱私的用戶服務。在不增加手機、不