Lock in $30 Savings on PRO—Offer Ends Soon! ⏳

Day1 Keynote in DroidKaigi 2016

Day1 Keynote in DroidKaigi 2016

Day1 Keynote in DroidKaigi 2016

Daichi Furiya (Wasabeef)

February 17, 2016
Tweet

More Decks by Daichi Furiya (Wasabeef)

Other Decks in Programming

Transcript

  1. Stream API Lightweight-Stream-API Stream.of(lines) .map(str -> str.split(t)) .filter(arr -> arr.length

    == 2) .map(arr -> new Word(arr[0], arr[1])) .collect(Collectors.toList());
  2. JSR-310 ThreeTen Android // Now LocalDateTime.now(); // 2016.2.18 10:30:40 LocalDateTime.of(2016,

    2, 18, 10, 30, 40); // +1 truncated second LocalDateTime.now() .plusHours(1).truncatedTo(ChronoUnit.HOURS); // Epoch LocalDateTime.now() .toInstant(ZoneOffset.UTC).toEpochMilli();
  3. Sample... Support Library compile 'com.android.support:support-v4:+' compile 'com.android.support:appcompat-v7:+' compile 'com.android.support:design:+' compile

    'com.android.support:recyclerview-v7:+' compile 'com.android.support:cardview-v7:+' compile 'com.android.support:support-annotations:+' compile ‘com.android.support:percent:+'
  4. ViewAnimator AnimatorSet animSet = new AnimatorSet(); animSet.playTogether( ObjectAnimator.ofFloat(image, View.TRANSLATION_Y, -1000,0),

    ObjectAnimator.ofFloat(image, View.ALPHA, 0,1), ObjectAnimator.ofFloat(text, View.TRANSLATION_X, -200,0) ); animSet.setInterpolator(new DescelerateInterpolator()); animSet.setDuration(2000); animSet.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { AnimatorSet anim = new AnimatorSet(); anim.playTogether( ObjectAnimator.ofFloat(image, View.SCALE_X, 1f, 0.5f, 1f), ObjectAnimator.ofFloat(image, View.SCALE_Y, 1f, 0.5f, 1f) ); anim.setInterpolator(new AccelerateInterpolator()); anim.setDuration(1000); anim.start(); } }); animSet.start();
  5. ViewAnimator ViewAnimator .animate(image) .translationY(-1000, 0) .alpha(0, 1) .andAnimate(text) .dp().translationX(-200, 0)

    .descelerate() .duration(2000) .thenAnimate(image) .scale(1f, 0.5f, 1f) .accelerate() .duration(1000) .start();
  6. Android Data Binding <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:id=“@+id/user_name“

    android:layout_width="wrap_content" android:layout_height="wrap_content"/> <ImageView android:id=“@+id/user_thumbnail“ android:layout_width="160dp" android:layout_height="120dp"/> </LinearLayout>
  7. Android Data Binding <layout xmlns:android="http://schemas.android.com/apk/res/android"> <LinearLayout android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView

    android:id=“@+id/user_name“ android:layout_width="wrap_content" android:layout_height="wrap_content"/> <ImageView android:id=“@+id/user_thumbnail“ android:layout_width="160dp" android:layout_height="120dp"/> </LinearLayout> </layout>
  8. Android Data Binding <layout xmlns:android="http://schemas.android.com/apk/res/android"> <data name="MainBinding"> <variable name="user" type="com.example.User"/>

    </data> <LinearLayout android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:id=“@+id/user_name“ android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@{user.name}" android:textColor="@{user.isWomen? @color/pink : @color:blue}"/> <ImageView android:id=“@+id/user_thumbnail“ android:layout_width="160dp" android:layout_height="120dp" bind:imageUrl="@{user.thumbnail}"/> </LinearLayout> </layout>
  9. Custom Setters Android Data Binding public final class ImageBindingAdapters {

    @BindingAdapter({ "bind:image" }) public static void loadImage(ImageView view, String url) { Glide.with(view.getContext().getApplicationContext()) .load(url) .into(view); } } <ImageView android:layout_width="160dp" android:layout_height="120dp" bind:imageUrl="@{user.thumbnail}"/>
  10. DataBindingUtil Android Data Binding @Override protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState); MainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main); binding.userName.setOnClickListener(v -> ...); } <layout xmlns:android="http://schemas.android.com/apk/res/android"> <data name="MainBinding"> <variable name="user" type="com.example.User"/> </data> <!-- ... -- </layout>
  11. Retrofit Retrofit retrofit = new Retrofit.Builder() .client(okHttpClient) .baseUrl("https://api.github.com") .addConverterFactory(GsonConverterFactory.create()) .addCallAdapterFactory(RxJavaCallAdapterFactory.create())

    .build(); GitHubService service = retrofit.create(GitHubService.class); service.repos("wasabeef") .subscribe(repo -> { // ... }, e -> { Timber.w(e); }); public interface GitHubService { @GET(/users/{user}/repos) Observable<List<Repo>> repos(@Path(user) String user); }
  12. Wire syntax = "proto3"; package helloworld; message HelloRequest { string

    name = 1; } message HelloReply { string message = 1; } hello.proto
  13. Wire Build # java -jar wire-compiler-2.0.1-jar-with-dependencies.jar \ —proto_path=. \ —java_out=.

    hello.proto Writing helloworld.HelloRequest to . Writing helloworld.HelloReply to .
  14. Parceler @Parcel public class User { public String name; public

    String thumbnail; User() { } } // Wrap Bundle bundle = new Bundle(); bundle.putParcelable("user", Parcels.wrap(user)); // Unwrap User user = Parcels.unwrap(getIntent().getParcelableExtra("user"));
  15. Simple Icepick public class MainActivity extends Activity { @State String

    name; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Icepick.restoreInstanceState(this, savedInstanceState); } @Override public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); Icepick.saveInstanceState(this, outState); } }
  16. Fresco <com.facebook.drawee.view.SimpleDraweeView android:id="@+id/my_image_view" android:layout_width="20dp" android:layout_height="20dp" fresco:fadeDuration="300" fresco:actualImageScaleType="focusCrop" fresco:placeholderImage="@color/wait_color" fresco:placeholderImageScaleType="fitCenter" fresco:failureImage="@drawable/error"

    fresco:failureImageScaleType="centerInside" fresco:retryImage="@drawable/retrying" fresco:retryImageScaleType="centerCrop" fresco:progressBarImage="@drawable/progress_bar" fresco:progressBarImageScaleType="centerInside" fresco:progressBarAutoRotateInterval="1000" fresco:backgroundImage="@color/blue" fresco:overlayImage="@drawable/watermark" fresco:pressedStateOverlayImage="@color/red" fresco:roundAsCircle="false" fresco:roundedCornerRadius="1dp" fresco:roundTopLeft="true" fresco:roundTopRight="false" fresco:roundBottomLeft="false" fresco:roundBottomRight="true" fresco:roundWithOverlayColor="@color/corner_color" fresco:roundingBorderWidth="2dp" fresco:roundingBorderColor="@color/border_color" />
  17. DI

  18. View Injection Butter Knife public class MainActivity extends Activity {

    @Bind(R.id.user_name) TextView userName; @Bind(R.id.user_thumbnail) ImageView thumbnail; @BindString(R.string.title) String title; @BindDrawable(R.drawable.graphic) Drawable graphic; @BindColor(R.color.red) int red; @BindDimen(R.dimen.spacer) float spacer; }
  19. OnClick, OnTextChange, OnFocusChange...etc Butter Knife @OnClick(R.id.user_name) public void click(View view)

    { // ... } @OnClick({ R.id.user_name, R.id.user_thumbnail }) public void click(View door) { // ... }
  20. FRP

  21. Main Thread RxAndroid Observable.just("one", "two", "three", "four", "five") .subscribeOn(Schedulers.newThread()) .observeOn(AndroidSchedulers.mainThread())

    .subscribe(/* an Observer */); final Handler handler = new Handler(); Observable.just("one", "two", "three", "four", "five") .subscribeOn(Schedulers.newThread()) .observeOn(HandlerScheduler.from(handler)) .subscribe(/* an Observer */) Arbitrary Thread
  22. AnnotationでMethod Callsを Loggingできる Hugo @DebugLog public String getName(String first, String

    last) { return first + " " + last; } V/Example: ⇢ getName(first="Daichi", last="Furiya") V/Example: ⇠ getName [0ms] = “Daichi Furiya"
  23. ProGuard 15M sample-production.apk Total methods count: 99,280 (multidex enabled) 13M

    sample-production-proguard.apk Total methods count: 54,977 Proguard あり Proguard なし