Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Давайте обращать внимание на детали? (Gorod.it, Томск, 10.11.19)

Alexey Bykov
November 10, 2018
74

Давайте обращать внимание на детали? (Gorod.it, Томск, 10.11.19)

Alexey Bykov

November 10, 2018
Tweet

Transcript

  1. ๏ Android Developer at KasperskyLab ๏ Mosdroid Speaker ๏ Android

    Academy MSK Co-orgaznizer ๏ Passionate about mobile UX About 2
  2. !3

  3. !4

  4. 23 Style <style name="SplashScreen" parent="Theme.AppCompat.Light.NoActionBar"> <item name="android:windowBackground">@drawable/background_splash</item> <item name="colorAccent">@color/light_background</item> <item

    name="windowActionBar">false</item> <item name="windowNoTitle">true</item> <item name="android:windowTranslucentStatus">true</item> </style>
  5. 24 Style <style name="SplashScreen" parent="Theme.AppCompat.Light.NoActionBar"> <item name="android:windowBackground">@drawable/background_splash</item> <item name="colorAccent">@color/light_background</item> <item

    name="windowActionBar">false</item> <item name="windowNoTitle">true</item> <item name="android:windowTranslucentStatus">true</item> </style>
  6. 28 Drawable (Placeholder) <?xml version="1.0" encoding="utf-8"?> <layer-list xmlns:android="http://schemas.android.com/apk/res/android" android:opacity=«opaque" >

    <item> <shape> <solid android:color="@color/grey"/> </shape> </item> <item android:height="?actionBarSize" android:gravity="top"> <shape android:shape="rectangle"> <solid android:color="?colorPrimary"/> </shape> </item> </layer-list>
  7. 29 Drawable (Placeholder) <?xml version="1.0" encoding="utf-8"?> <layer-list xmlns:android="http://schemas.android.com/apk/res/android" android:opacity=«opaque" >

    <item> <shape> <solid android:color="@color/grey"/> </shape> </item> <item android:height="?actionBarSize" android:gravity="top"> <shape android:shape="rectangle"> <solid android:color="?colorPrimary"/> </shape> </item> </layer-list>
  8. !32

  9. ViewGroup 39 fun ViewGroup.onKeyboardStateChanged(activity: Activity, listener: (Boolean) -> Unit) {

    viewTreeObserver.addOnGlobalLayoutListener { val screenSize = Point() activity.windowManager.defaultDisplay.getSize(screenSize) val rect = Rect() getWindowVisibleDisplayFrame(rect) val diff = screenSize.y - rect.bottom listener.invoke(diff != 0) } }
  10. ViewGroup 40 fun ViewGroup.onKeyboardStateChanged(activity: Activity, listener: (Boolean) -> Unit) {

    viewTreeObserver.addOnGlobalLayoutListener { val screenSize = Point() activity.windowManager.defaultDisplay.getSize(screenSize) val rect = Rect() getWindowVisibleDisplayFrame(rect) val diff = screenSize.y - rect.bottom listener.invoke(diff != 0) } }
  11. ViewGroup 41 fun ViewGroup.onKeyboardStateChanged(activity: Activity, listener: (Boolean) -> Unit) {

    viewTreeObserver.addOnGlobalLayoutListener { val screenSize = Point() activity.windowManager.defaultDisplay.getSize(screenSize) val rect = Rect() getWindowVisibleDisplayFrame(rect) val diff = screenSize.y - rect.bottom listener.invoke(diff != 0) } }
  12. ViewGroup 42 fun ViewGroup.onKeyboardStateChanged(activity: Activity, listener: (Boolean) -> Unit) {

    viewTreeObserver.addOnGlobalLayoutListener { val screenSize = Point() activity.windowManager.defaultDisplay.getSize(screenSize) val rect = Rect() getWindowVisibleDisplayFrame(rect) val diff = screenSize.y - rect.bottom listener.invoke(diff != 0) } }
  13. !44

  14. !48

  15. 52

  16. 54

  17. !59

  18. !64

  19. !65

  20. !66

  21. Fab animation 71 class RecyclerViewWithFloatingActionButton : RecyclerView { var mFloatingActionButton:

    FloatingActionButton? = null constructor(context: Context) : super(context) {} constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {} constructor(context: Context, attrs: AttributeSet?, defStyle: Int) : super(context, attrs, defStyle) {} override fun onScrolled(dx: Int, dy: Int) { super.onScrolled(dx, dy) if (dy > 0) { // Scrolling up mFloatingActionButton?.hide() } else { // Scrolling down mFloatingActionButton?.show() } } }
  22. Fab animation 72 class RecyclerViewWithFloatingActionButton : RecyclerView { var mFloatingActionButton:

    FloatingActionButton? = null constructor(context: Context) : super(context) {} constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {} constructor(context: Context, attrs: AttributeSet?, defStyle: Int) : super(context, attrs, defStyle) {} override fun onScrolled(dx: Int, dy: Int) { super.onScrolled(dx, dy) if (dy > 0) { // Scrolling up mFloatingActionButton?.hide() } else { // Scrolling down mFloatingActionButton?.show() } } }
  23. Fab animation 73 class RecyclerViewWithFloatingActionButton : RecyclerView { var mFloatingActionButton:

    FloatingActionButton? = null constructor(context: Context) : super(context) {} constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {} constructor(context: Context, attrs: AttributeSet?, defStyle: Int) : super(context, attrs, defStyle) {} override fun onScrolled(dx: Int, dy: Int) { super.onScrolled(dx, dy) if (dy > 0) { // Scrolling up mFloatingActionButton?.hide() } else { // Scrolling down mFloatingActionButton?.show() } } }
  24. !74

  25. Debounce Click 78 abstract class DebounceOnClickListener() : View.OnClickListener { companion

    object { const private val CLICK_DELAY = 500L private var sIsClickEnabled = true } private val mClickLockRunnable = Runnable { sIsClickEnabled = true } override fun onClick(view: View?) { if (sIsClickEnabled) { sIsClickEnabled = false onDelayedClick(view) view?.postDelayed(mClickLockRunnable, CLICK_DELAY) } } abstract fun onDelayedClick(view: View?) }
  26. Extension 79 fun View.setDebounceOnClickListener(listener: (view: View?) -> Unit) { setOnClickListener(object

    : DebounceClickListener() { override fun onDelayedClick(view: View?) { listener.invoke(view) } }) }
  27. !83

  28. !84

  29. NoPaginate 87 val noPaginate = NoPaginate.with(recyclerView) .setOnLoadMoreListener { //http or

    db request } .setLoadingTriggerThreshold(5) //0 by default .setCustomErrorItem(CustomErrorItem()) .setCustomLoadingItem(CustomLoadingItem()) .build()
  30. !89

  31. !91