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

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

Best Practices for Interaction and Engagement

Designing Effective Navigation

  • Planning Screens and Their Relationships
    • 實(shí)體關(guān)系圖(Entity-relationship diagram),數(shù)據(jù)、用戶之間的關(guān)系、操作
    • 詳盡的用例場(chǎng)景
    • 界面關(guān)系圖
  • Planning for Multiple Touchscreen Sizes
    • 界面組合技術(shù),在平板電腦、電視上,屏幕很大,可以把列表界面和詳情界面左右排布一起顯示
  • Providing Descendant and Lateral Navigation
    • Descendant,父界面前往子界面
    • Lateral,兄弟界面之間的跳轉(zhuǎn)
    • list和section
  • Providing Ancestral and Temporal Navigation
    • Temporal(時(shí)間性),按下返回鍵,應(yīng)該回到上一界面
    • Ancestral(父子性),ActionBar/ToolBar上的返回按鈕,返回父界面(通常是上一界面,但并不全是,容納WebView的Activity就是很好的例子),需要注意的是,一定要清除backstack
  • ...

Implementing Effective Navigation

  • Creating Swipe Views with Tabs
    • ViewPager,PagerTitleStrip,FragmentPagerAdapterFragmentStatePagerAdapter
  • Creating a Navigation Drawer
    • drawer layout里面可以顯式一個(gè)菜單列表
    • ActionBarDrawerToggle(appcompat-v7中)可以監(jiān)聽(tīng)drawer的開(kāi)啟與關(guān)閉事件,也可以用代碼控制drawer的開(kāi)啟與關(guān)閉
    • 完整樣例
  • Providing Up Navigation

    • 首先在manifest里面為activity聲明其parent activity,用于up navigation
    • 然后在onOptionsItemSelected回調(diào)中處理up navigation:
      @Override
      public boolean onOptionsItemSelected(MenuItem item) {
          switch (item.getItemId()) {
          // Respond to the action bar's Up/Home button
          case android.R.id.home:
              Intent upIntent = NavUtils.getParentActivityIntent(this);
              if (NavUtils.shouldUpRecreateTask(this, upIntent)) {
                  // This activity is NOT part of this app's task, so create a new task
                  // when navigating up, with a synthesized back stack.
                  TaskStackBuilder.create(this)
                          // Add all of this activity's parents to the back stack
                          .addNextIntentWithParentStack(upIntent)
                          // Navigate up to the closest parent
                          .startActivities();
              } else {
                  // This activity is part of this app's task, so simply
                  // navigate up to the logical parent activity.
                  NavUtils.navigateUpTo(this, upIntent);
              }
              return true;
          }
          return super.onOptionsItemSelected(item);
      }
  • Providing Proper Back Navigation

    • 安卓系統(tǒng)都有一個(gè)物理返回鍵,所以不應(yīng)該在UI上額外添加一個(gè)返回鍵
    • 安卓系統(tǒng)的back stack通常情況下都可以應(yīng)對(duì)back navigation
    • 但是以下情況需要特殊考慮

      • 從通知欄消息、widget、navigation drawer直接進(jìn)入一個(gè)深層次的activity
          // Intent for the activity to open when user selects the notification
          Intent detailsIntent = new Intent(this, DetailsActivity.class);
      
          // Use TaskStackBuilder to build the back stack and get the PendingIntent
          PendingIntent pendingIntent =
                  TaskStackBuilder.create(this)
                                  // add all of DetailsActivity's parents to the stack,
                                  // followed by DetailsActivity itself
                                  .addNextIntentWithParentStack(upIntent)
                                  .getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
      
          NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
          builder.setContentIntent(pendingIntent);
      • fragment之間的導(dǎo)航
          // Works with either the framework FragmentManager or the
          // support package FragmentManager (getSupportFragmentManager).
          getSupportFragmentManager().beginTransaction()
                                  .add(detailFragment, "detail")
                                  // Add this transaction to the back stack
                                  .addToBackStack()
                                  .commit();

      需要注意的是,當(dāng)fragment是在ViewPager中水平切換時(shí),不應(yīng)該把transaction 加入到 backstack中。

      • WebView
          @Override
          public void onBackPressed() {
              if (mWebView.canGoBack()) {
                  mWebView.goBack();
                  return;
              }
      
              // Otherwise defer to system default behavior.
              super.onBackPressed();
          }
  • Implementing Descendant Navigation

    • 通常都是Intent加上startActivity(intent),或者FragmentTransaction來(lái)完成向子界面的導(dǎo)航
    • 需要注意的是,如果app將打開(kāi)其他app的界面,為了防止用戶中途離開(kāi),再次從launcher打開(kāi)app時(shí),卻是其他app的界面,可以為intent設(shè)置FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET flag
      Intent externalActivityIntent = new Intent(Intent.ACTION_PICK);
      externalActivityIntent.setType("image/*");
      externalActivityIntent.addFlags(
              Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
      startActivity(externalActivityIntent);
  • Notifying the User

    • Building a Notification
      • 使用NotificationCompat.Builder創(chuàng)建通知欄消息
      • 響應(yīng)用戶對(duì)通知欄消息的點(diǎn)擊,啟動(dòng)相應(yīng)Activity,同時(shí)要考慮是否提供返回的導(dǎo)航設(shè)計(jì)
    • Preserving Navigation when Starting an Activity
      • 點(diǎn)擊通知欄消息,可能會(huì)啟動(dòng)兩種類(lèi)型的Activity:正常使用流程會(huì)啟動(dòng)的Activity;僅僅是把通知欄消息展開(kāi)的Activity;
      • 前者通常需要提供back導(dǎo)航支持,在manifest中聲明Activity父子關(guān)系,同時(shí)構(gòu)造PendingIntent時(shí)構(gòu)造back stack,使用stackBuilder.getPendingIntent創(chuàng)建PendingIntent
      • 后者通常不需要加入到back stack中,無(wú)需手動(dòng)構(gòu)造back stack,使用PendingIntent.getActivity創(chuàng)建PendingIntent,同時(shí)在manifest中設(shè)置以下選項(xiàng):
          <activity
              android:name=".ResultActivity"
          ...
              android:launchMode="singleTask"
              android:taskAffinity=""
              android:excludeFromRecents="true">
          </activity>
    • 完整示例:

      Intent resultIntent = new Intent(this, ResultActivity.class);
      TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
      // Adds the back stack
      stackBuilder.addParentStack(ResultActivity.class);
      // Adds the Intent to the top of the stack
      stackBuilder.addNextIntent(resultIntent);
      // Gets a PendingIntent containing the entire back stack
      PendingIntent resultPendingIntent =
              stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
      
      NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this)
          .setSmallIcon(R.drawable.notification_icon)
          .setContentTitle("My notification")
          .setContentText("Hello World!")
          .setContentIntent(resultPendingIntent);
      
      // Sets an ID for the notification
      int mNotificationId = 001;
      // Gets an instance of the NotificationManager service
      NotificationManager mNotifyMgr = 
              (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
      // Builds the notification and issues it.
      mNotifyMgr.notify(mNotificationId, mBuilder.build());
    • Updating Notifications
      • 創(chuàng)建通知欄消息時(shí),如果指定了id,以后可以通過(guò)id對(duì)已經(jīng)顯示的消息進(jìn)行修改/更新、移除操作;
      • 修改/更新只需以相同的id,新的Notification對(duì)象,調(diào)用mNotifyMgr.notify即可;
      • 如果消息支持被移除,則用戶可以手動(dòng)移除(單個(gè)或者所有),setAutoCancel()會(huì)讓消息在用戶點(diǎn)擊時(shí)自動(dòng)消失;cancel(id)cancelAll()可以代碼移除通知欄消息;
    • Using Big View Styles

      • Android 4.1之后,通知欄消息引入了action的支持,方便用戶快捷操作
      // Sets up the Snooze and Dismiss action buttons that will appear in the
      // big view of the notification.
      Intent dismissIntent = new Intent(this, PingService.class);
      dismissIntent.setAction(CommonConstants.ACTION_DISMISS);
      PendingIntent piDismiss = PendingIntent.getService(this, 0, dismissIntent, 0);
      
      Intent snoozeIntent = new Intent(this, PingService.class);
      snoozeIntent.setAction(CommonConstants.ACTION_SNOOZE);
      PendingIntent piSnooze = PendingIntent.getService(this, 0, snoozeIntent, 0);
      
      // Constructs the Builder object.
      NotificationCompat.Builder builder =
              new NotificationCompat.Builder(this)
              .setSmallIcon(R.drawable.ic_stat_notification)
              .setContentTitle(getString(R.string.notification))
              .setContentText(getString(R.string.ping))
              .setDefaults(Notification.DEFAULT_ALL) // requires VIBRATE permission
              /*
              * Sets the big view "big text" style and supplies the
              * text (the user's reminder message) that will be displayed
              * in the detail area of the expanded notification.
              * These calls are ignored by the support library for
              * pre-4.1 devices.
              */
              .setStyle(new NotificationCompat.BigTextStyle()
                      .bigText(msg))
              .addAction (R.drawable.ic_stat_dismiss,
                      getString(R.string.dismiss), piDismiss)
              .addAction (R.drawable.ic_stat_snooze,
                      getString(R.string.snooze), piSnooze);
    • Displaying Progress in a Notification
      • setProgress (int max, int progress, boolean indeterminate)可以為通知欄消息設(shè)置進(jìn)度條,支持實(shí)時(shí)進(jìn)度、持續(xù)模式
  • Supporting Swipe-to-Refresh

  • Adding Search Functionality

    • 在App Bar中添加SearchView,注意它有support版本

      res/menu/options_menu.xml:

          <?xml version="1.0" encoding="utf-8"?>
          <menu xmlns:android="http://schemas.android.com/apk/res/android">
              <item android:id="@+id/search"
                  android:title="@string/search_title"
                  android:icon="@drawable/ic_search"
                  android:showAsAction="collapseActionView|ifRoom"
                  android:actionViewClass="android.widget.SearchView" />
          </menu>
          @Override
          public boolean onCreateOptionsMenu(Menu menu) {
              MenuInflater inflater = getMenuInflater();
              inflater.inflate(R.menu.options_menu, menu);
      
              return true;
          }
    • 創(chuàng)建可搜索的配置

      res/xml/searchable.xml,配置SearchView的label,hint

          <?xml version="1.0" encoding="utf-8"?>
          <searchable xmlns:android="http://schemas.android.com/apk/res/android"
                  android:label="@string/app_name"
                  android:hint="@string/search_hint" />

      manifest

          <activity ... >
              ...
              <meta-data android:name="android.app.searchable"
                      android:resource="@xml/searchable" />
      
          </activity>
          @Override
          public boolean onCreateOptionsMenu(Menu menu) {
              MenuInflater inflater = getMenuInflater();
              inflater.inflate(R.menu.options_menu, menu);
      
              // Associate searchable configuration with the SearchView
              SearchManager searchManager =
                  (SearchManager) getSystemService(Context.SEARCH_SERVICE);
              SearchView searchView =
                      (SearchView) menu.findItem(R.id.search).getActionView();
              searchView.setSearchableInfo(
                      searchManager.getSearchableInfo(getComponentName()));
      
              return true;
          }
    • 當(dāng)用戶提交一個(gè)query時(shí),SearchView會(huì)發(fā)出一個(gè)ACTION_SEARCH intent,需要在manifest文件中聲明響應(yīng)此intent
  • Making Your App Content Searchable by Google

    • Google對(duì)如何優(yōu)化對(duì)app內(nèi)的內(nèi)容、網(wǎng)站的搜索,提供了相應(yīng)的建議
    • Deep Links,通過(guò)在manifest中聲明感興趣的Intent,可以在用戶在其他app內(nèi)觸發(fā)此intent時(shí)啟動(dòng)自己的app,intent可以設(shè)置action, category, scheme來(lái)進(jìn)行過(guò)濾
  • 優(yōu)化app的assistant內(nèi)容

  • app link,讓自己的app成為自己網(wǎng)站uri的默認(rèn)打開(kāi)方式