在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 教程/ Android/ Building Apps with Graphics & Animation
Launch mode 和 Intent flags專題
Canvas & Drawables
UTAustinX_UT.9.01x: Effective Thinking Through Mathematics
《JavaScript 語言精粹》
Memory leak專題
React基礎(chǔ)
《Test Driven Development: By Example》一書
Developer tools
安卓開發(fā)技能樹
<a rel="nofollow" href="https://mp.weixin.qq.com/s?__biz=MzA3NDM
Best Practices for Interaction and Engagement
各個安卓版本引入的主要新特性
Building Apps with Connectivity &amp; the Cloud
List.toArray()再強轉(zhuǎn)是一定會失敗的
深入Android frameworks
Google dev 100 days系列視頻
Building Apps with Contacts &amp; Sign-In
關(guān)系型數(shù)據(jù)庫設(shè)計范式
《App研發(fā)錄》一書
REST API設(shè)計
Google IO 2015摘要
自定義View/ViewGroup以及高性能實現(xiàn)自定義UI
安卓系統(tǒng)點擊事件處理
《50 Android Hacks》一書
Building Apps with Content Sharing
Flux基礎(chǔ)
<a rel="nofollow" href="http://developer.android.com/training/in
依賴注入(以Dagger 2為例)
Java同步機制
Java對象內(nèi)存的使用情況
JSR133(Java memory model)
Google官方Material Design手冊(<a rel="nofollow" href="http://develop
Futurice公司安卓團隊的建議
安卓性能優(yōu)化
  • 1.
Best Practices for Performance
<a rel="nofollow" href="http://www.vogella.com/tutorials/Android
<a rel="nofollow" href="http://blog.danlew.net/2014/11/19/styles
Handling Runtime Changes
<a rel="nofollow" href="http://www.vogella.com/tutorials/Android
Building Apps with Graphics &amp; Animation
<a rel="nofollow" href="http://tools.android.com/tech-docs/new-b
Android項目架構(gòu)
MVP(Model-View-Presenter)模式
<a rel="nofollow" href="http://www.infoq.com/cn/es6-in-depth/"">
《Android源碼設(shè)計模式解析與實戰(zhàn)》一書
Rx在Android中的最佳實踐
函數(shù)調(diào)用時,傳遞參數(shù)應(yīng)該是不可變的(Immutable)
ProGuard
面向?qū)ο罅笤瓌t(SOLID+)
深入理解Java虛擬機
深入Java深淺拷貝、immutable、unmodifiable
Best Practices for User Input
UI上的一些高效方式/最佳實踐
<a rel="nofollow" href="https://blog.stylingandroid.com/ripples-
Best Practices for User Interface
安卓測試驅(qū)動開發(fā)/安卓測試驗證
暗時間:學(xué)會正確思考
技術(shù)筆記
Aspect Oriented Programming(AOP)
Best Practices for Background Jobs
安卓系統(tǒng)動效專題
Feed系統(tǒng)的設(shè)計
Data binding(MVVM,Model-View-ViewModel)
Effective Java一書筆記
<a rel="nofollow" href="http://developer.android.com/training/in
Rx (Reactive eXtention)
MultiDex專題
一些很棒的點子
WebRTC

Building Apps with Graphics &amp; Animation

Displaying Bitmaps Efficiently

  • 手機內(nèi)存資源有限,一個應(yīng)用最少可能只有16MB的內(nèi)存
  • 使用Bitmap顯示圖片,如果不壓縮,很可能一個圖片就會占用十幾MB的內(nèi)存
  • ListView, GridView, ViewPager這種View,可能顯示在屏幕上的只有幾個圖片,但是還有很多是沒有顯示在屏幕上的,如果沒有顯示在屏幕上的也占用著內(nèi)存,那將很快導(dǎo)致OOM
  • 在解碼/載入圖片到內(nèi)存(Bitmap對象)之前,要先判斷一下圖片的尺寸,獲取圖片的尺寸和類型:

      BitmapFactory.Options options = new BitmapFactory.Options();
      options.inJustDecodeBounds = true;
      BitmapFactory.decodeResource(getResources(), R.id.myimage, options);
      int imageHeight = options.outHeight;
      int imageWidth = options.outWidth;
      String imageType = options.outMimeType;

    設(shè)置options.inJustDecodeBounds = true,將只讀取文件信息,不會為圖片分配內(nèi)存

  • 載入和屏幕尺寸適配的圖片尺寸,否則空占內(nèi)存卻沒有視覺效果的提升,需要考慮以下因素:

    • 預(yù)計完全載入圖片所需的內(nèi)存大小
    • 預(yù)期為加載此圖片愿意分配的內(nèi)存
    • 用來顯示該圖片的View的尺寸
    • 當(dāng)前設(shè)備的屏幕尺寸和像素密度

          public static int calculateInSampleSize(
                      BitmapFactory.Options options, int reqWidth, int reqHeight) {
              // Raw height and width of image
              final int height = options.outHeight;
              final int width = options.outWidth;
              int inSampleSize = 1;
      
              if (height > reqHeight || width > reqWidth) {
      
                  final int halfHeight = height / 2;
                  final int halfWidth = width / 2;
      
                  // Calculate the largest inSampleSize value that is a power of 2 and keeps both
                  // height and width larger than the requested height and width.
                  while ((halfHeight / inSampleSize) > reqHeight
                          && (halfWidth / inSampleSize) > reqWidth) {
                      inSampleSize *= 2;
                  }
              }
      
              return inSampleSize;
          }
      
          public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
                  int reqWidth, int reqHeight) {
      
              // First decode with inJustDecodeBounds=true to check dimensions
              final BitmapFactory.Options options = new BitmapFactory.Options();
              options.inJustDecodeBounds = true;
              BitmapFactory.decodeResource(res, resId, options);
      
              // Calculate inSampleSize
              options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
      
              // Decode bitmap with inSampleSize set
              options.inJustDecodeBounds = false;
              return BitmapFactory.decodeResource(res, resId, options);
          }
      
          ...
          mImageView.setImageBitmap(
              decodeSampledBitmapFromResource(getResources(), R.id.myimage, 100, 100));
          ...
  • 加載、處理圖片要在非UI線程執(zhí)行,使用rx可以方便地做到這一點
  • 緩存Bitmap
    • 內(nèi)存緩存:LruCache,放入cache的要用SoftReference或者WeakReference,以免放入緩存的數(shù)據(jù)未被按時移出緩存,導(dǎo)致內(nèi)存泄漏
    • 磁盤緩存:DiskLruCache,;當(dāng)要緩存的數(shù)據(jù)經(jīng)常被訪問時,使用ContentProvider會更合適
    • 響應(yīng)Configuration change:使用headless fragment,是實現(xiàn)方式之一
  • 管理bitmap內(nèi)存
    • API <= 10:當(dāng)確定bitmap不會被使用之后,調(diào)用bitmap.recycle()
    • API >= 11:BitmapFactory.Options.inBitmap,會使得bitmap mutable,不太建議使用
  • 顯示bitmap,將資源加載到內(nèi)存的過程要在非UI線程執(zhí)行,避免程序未響應(yīng)

Displaying Graphics with OpenGL ES

  • Transitions Framework原生API支持,需要API >= 19, Animations backported to Android 4.0+. API compatible with Android 2.2+
  • The Transitions Framework

    • 動效的意義:幫助用戶理解app的行為,理解視覺變化的意義
    • 包含的功能
      • Group-level animations:可以應(yīng)用于整個View hierarchy
      • Transition-based animation:基于property animation
      • Built-in animations:內(nèi)置了很多動效實現(xiàn)
      • Resource file support:支持在xml中定義動效
      • Lifecycle callbacks:具備生命周期回調(diào),便于響應(yīng)動效狀態(tài)進行邏輯操作
    • 原理

    http://wiki.jikexueyuan.com/project/notes/images/transitions_diagram.png" alt="transitions_diagram.png" />

    • Scene
      • 記錄View hierarchy的狀態(tài)
      • 支持從xml創(chuàng)建/從ViewGroup對象創(chuàng)建
      • 通常不需要顯式指定開始的Scene,默認是前一個ending Scene,或者當(dāng)前屏幕上顯示的view hierarchy
      • Scene的轉(zhuǎn)化都發(fā)生在同一個Scene root中
        • Transition
      • 在動效框架中,通過把scene的變化轉(zhuǎn)化為一系列的關(guān)鍵幀,動畫的信息保存在Transition對象中,通過TransitionManager來播放動畫
      • 可以為兩個Scene創(chuàng)建動畫,也可以為當(dāng)前Scene的不同狀態(tài)創(chuàng)建動畫
      • 內(nèi)部實現(xiàn)了常用的動效:fading, resizing...
        • Limitations
      • 對SurfaceView應(yīng)用動效可能不會正常顯示,SurfaceView在非UI線程進行更新
      • 有些動效可能對TextureView無效
      • 對AdapterView(例如ListView)使用動效,可能會導(dǎo)致界面卡住
      • 對TextView使用resize動效時,文字可能會在動效完成之前先“彈”出去,所以避免對有文字的view使用resize動效
  • Creating a Scene

    • 從xml創(chuàng)建

      scene root

          <FrameLayout
              android:id="@+id/scene_root">
              <include layout="@layout/a_scene" />
          </FrameLayout>

      starting scene

          <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:id="@+id/scene_container"
              android:orientation="vertical"
              android:layout_width="match_parent"
              android:layout_height="match_parent" >
              <TextView
                  android:id="@+id/text_view1
                  android:text="Text Line 1" />
              <TextView
                  android:id="@+id/text_view2
                  android:text="Text Line 2" />
          </LinearLayout>

      ending scene

          <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:id="@+id/scene_container"
              android:orientation="vertical"
              android:layout_width="match_parent"
              android:layout_height="match_parent" >
              <TextView
                  android:id="@+id/text_view2
                  android:text="Text Line 2" />
              <TextView
                  android:id="@+id/text_view1
                  android:text="Text Line 1" />
          </LinearLayout>

      創(chuàng)建scene

          Scene mAScene;
          Scene mAnotherScene;
      
          // Create the scene root for the scenes in this app
          mSceneRoot = (ViewGroup) findViewById(R.id.scene_root);
      
          // Create the scenes
          mAScene = Scene.getSceneForLayout(mSceneRoot, R.layout.a_scene, this);
          mAnotherScene =
              Scene.getSceneForLayout(mSceneRoot, R.layout.another_scene, this);
    • 代碼創(chuàng)建

          Scene mScene;
      
          // Obtain the scene root element
          mSceneRoot = (ViewGroup) mSomeLayoutElement;
      
          // Obtain the view hierarchy to add as a child of
          // the scene root when this scene is entered
          mViewHierarchy = (ViewGroup) someOtherLayoutElement;
      
          // Create a scene
          mScene = new Scene(mSceneRoot, mViewHierarchy);
    • Create Scene Actions
      • 當(dāng)涉及的View不在同一個view hierarchy中時,可以通過創(chuàng)建scene action來輔助實現(xiàn)動效
      • 動效框架無法自動創(chuàng)建scene action時,可以手動創(chuàng)建,例如ListView
      • 把要執(zhí)行的操作封裝到Runnable中,設(shè)置給Scene.setExitAction()Scene.setEnterAction()
      • 注意:不要在scene action中傳遞數(shù)據(jù)
  • 應(yīng)用動效

    • 內(nèi)置動效
      • AutoTransition/<autoTransition/>:Default transition. Fade out, move and resize, and fade in views, in that order.
      • Fade/<fade/>:fade_in fades in views; fade_out fades out views; fade_in_out (default) does a fade_out followed by a fade_in.
      • ChangeBounds/<changeBounds/>:Moves and resizes views.
    • 從xml創(chuàng)建

      res/transition/fade_transition.xml

          <fade xmlns:android="http://schemas.android.com/apk/res/android" />

      inflate

          Transition mFadeTransition =
                  TransitionInflater.from(this).
                  inflateTransition(R.transition.fade_transition);
    • 代碼創(chuàng)建:Transition mFadeTransition = new Fade();
    • 應(yīng)用動效:TransitionManager.go(mEndingScene, mFadeTransition);
    • 支持只對view hierarchy中的部分view應(yīng)用動效:removeTarget(),addTarget()
    • 同時使用多種效果:TransitionSet

      在res/transitions/目錄下創(chuàng)建資源文件

          <transitionSet xmlns:android="http://schemas.android.com/apk/res/android"
              android:transitionOrdering="sequential">
              <fade android:fadingMode="fade_out" />
              <changeBounds />
              <fade android:fadingMode="fade_in" />
          </transitionSet>
    • 不使用Scene而直接應(yīng)用動效
      • 通過removeView/addView來改變view hierarchy, 并使用delayed transition
      • 改變view hierarchy之前調(diào)用TransitionManager.beginDelayedTransition()
      • 修改view:增/減/改
    • 實現(xiàn)TransitionListener以在動效生命周期回調(diào)中執(zhí)行操作
  • 自定義Transition

    • 繼承Transition類

          public class CustomTransition extends Transition {
      
              @Override
              public void captureStartValues(TransitionValues values) {}
      
              @Override
              public void captureEndValues(TransitionValues values) {}
      
              @Override
              public Animator createAnimator(ViewGroup sceneRoot,
                                          TransitionValues startValues,
                                          TransitionValues endValues) {}
          }
    • Capture View Property Values

      • captureStartValues

      scene中的每個view都會調(diào)用一遍,TransitionValues包含view對象,和一個map,用于記錄view對象的各個感興趣的屬性值

      public class CustomTransition extends Transition {
      
          // Define a key for storing a property value in
          // TransitionValues.values with the syntax
          // package_name:transition_class:property_name to avoid collisions
          private static final String PROPNAME_BACKGROUND =
              "com.example.android.customtransition:CustomTransition:background";
      
          @Override
          public void captureStartValues(TransitionValues transitionValues) {
              // Call the convenience method captureValues
              captureValues(transitionValues);
          }
      
          // For the view in transitionValues.view, get the values you
          // want and put them in transitionValues.values
          private void captureValues(TransitionValues transitionValues) {
              // Get a reference to the view
              View view = transitionValues.view;
              // Store its background property in the values map
              transitionValues.values.put(PROPNAME_BACKGROUND, view.getBackground());
          }
          ...
      }
      • captureEndValuescaptureStartValues類似
      @Override
      public void captureEndValues(TransitionValues transitionValues) {
          captureValues(transitionValues);
      }
    • createAnimator,transition framework調(diào)用此函數(shù)的次數(shù)與scene的變化有關(guān)
      • 例如5個view,變化后有2個被移除,1個新加入,則會調(diào)用6次:3個保持存在,2個移除,1個加入;
      • 保持存在的view,調(diào)用時兩個TransitionValues都不為null,而只存在于一個狀態(tài)的,另一個狀態(tài)對應(yīng)的TransitionValues參數(shù)為null;
      • 最終利用兩個TransitionValues參數(shù),返回一個property animator

Adding Animations

  • 交叉隱現(xiàn)
    • View.animate()方法返回ViewPropertyAnimator對象,對其可以進行各種property animation
  • ViewPager的使用
    • 通常結(jié)合Fragment使用
    • ListView類似,ViewPager也需要一個Adapter,FragmentStatePagerAdapter的實現(xiàn)類
    • ViewPagerIndicator
    • 實現(xiàn)ViewPager.PageTransformer接口,通過其transformPage函數(shù)自定義page切換動效
      • position參數(shù)表示當(dāng)前page的位置
      • 小于0表示位于屏幕中心點左側(cè)
      • 小于-1表示完全移出了屏幕
      • 大于0表示位于屏幕中心點右側(cè)
      • 大于1表示完全移出了屏幕
    • ViewPagerTransforms, VerticalViewPager
  • Displaying Card Flip Animations
    • 為FragmentTransition設(shè)置過場動效:setCustomAnimations,注意:這個函數(shù)的調(diào)用順序很重要,一定在add, replace等操作之前。
  • Zooming a View
    • 示例演示了組合使用ObjectAnimator來實現(xiàn)縮略圖放大到大圖的動畫效果,以及反向效果。
  • Animating Layout Changes
    • 使用setLayoutTransition()設(shè)置自定義layout變化動效
    • 新的Scene框架也可以做這個事情
    • back-port的transition everywhere庫也有相應(yīng)接口:TransitionManager.beginDelayedTransition(ViewGroup)
  • 更多,安卓系統(tǒng)動效專題