Разделы презентаций


Android Animation: from hate to love

Содержание

GitHub со всеми анимациями

Слайды и текст этой презентации

Слайд 1Android Animation: from hate to love
View Animation
Property Animation
Transitions
Motion Layout
Алексей Зотов

Android Animation:  from hate to loveView AnimationProperty AnimationTransitionsMotion LayoutАлексей Зотов

Слайд 2GitHub со всеми анимациями

GitHub со всеми анимациями

Слайд 3View animation

android:toYDelta="200" />

private fun startAnimation(view: View) { val animation =

AnimationUtils.loadAnimation(this, R.anim.view_animation) view.startAnimation(animation) }

View animationprivate fun startAnimation(view: View) {   val animation = AnimationUtils.loadAnimation(this, R.anim.view_animation)   view.startAnimation(animation) }

Слайд 4Property animator
private fun startAnimation(view: View) { view.animate()

.translationY(200f) .setDuration(250) .start() }

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

Property animatorprivate fun startAnimation(view: View) {   view.animate()     .translationY(200f)

Слайд 5Property animator
private fun startAnimation(view: View) { view.animate()

.translationY(200f) .rotation(180f) .setDuration(400)

.start() }

Property animatorprivate fun startAnimation(view: View) {   view.animate()     .translationY(200f)

Слайд 6private fun startAnimation(view: View) { view.animate()

.translationY(200f) .rotation(180f) .scaleY(3f)

.scaleX(4f) .setDuration(400) .start() }

Property animator

private fun startAnimation(view: View) {   view.animate()     .translationY(200f)

Слайд 7transition
TransitionManager.beginDelayedTransition(main_container)

TransitionManager.go(scene)

private val startSet = ConstraintSet() private val endSet = ConstraintSet()

startSet.clone(main_container) endSet.clone(this, R.layout.scene_a)

private

fun startAnimation(reverse: Boolean) { TransitionManager.beginDelayedTransition(main_container) (if (reverse) startSet

else endSet).applyTo(main_container) }

Scene.getSceneForLayout(main_container, R.layout.scene_a, this)

transitionTransitionManager.beginDelayedTransition(main_container)TransitionManager.go(scene)private val startSet = ConstraintSet() private val endSet = ConstraintSet()startSet.clone(main_container) endSet.clone(this, R.layout.scene_a)private fun startAnimation(reverse: Boolean) {

Слайд 8transition
android:transitionName="@string/cat_transition"

private fun openCatActivity(cat: View) { val bundle = ActivityOptions.makeSceneTransitionAnimation(

this, cat,

getString(R.string.cat_transition) ).toBundle() startActivity( Intent(this, CatInfoActivity::class.java), bundle ) }

transitionandroid:transitionName=

Слайд 9transition



name="android:windowActivityTransitions">true @transition/cat_open @transition/cat_open



transition                true

Слайд 10Motion layout

android:id="@+id/motion_container" android:layout_width="match_parent" android:layout_height="match_parent" app:layoutDescription="@xml/scene" tools:showPaths="true">







Motion layout

Слайд 11Motion layout

motion:constraintSetEnd="@+id/end" motion:constraintSetStart="@+id/start" motion:duration="1000">



Motion layout

Слайд 12Motion layout

/>

Motion layout

Слайд 13Motion layout

/>

Motion layout

Слайд 14Motion layout

android:id="@+id/motion_container" android:layout_width="match_parent" android:layout_height="match_parent" app:layoutDescription="@xml/scene" tools:showPaths="true">







Motion layout

Слайд 16GitHub со всеми анимациями

GitHub со всеми анимациями

Слайд 17Спасибо
Алексей зотов

СпасибоАлексей зотов

Слайд 19Reactive approach:
keep it simple in android
Даниэл Сергеев, AutoRu android

developer

Reactive approach: keep it simple in androidДаниэл Сергеев, AutoRu android developer

Слайд 20Подходы к написанию приложений
Императивный подход — парадигма программирования, ориентированная на последовательное

выполнение команд, и внешних синхронных операций.

Реактивный подход — парадигма программирования, ориентированная

на потоки данных и асинхронное распространение изменений.

Подходы к написанию приложенийИмперативный подход — парадигма программирования, ориентированная на последовательное выполнение команд, и внешних синхронных операций.Реактивный подход —

Слайд 21Реактивный подход
Эффективен
В асинхронных приложениях
Для обработки ошибок
Для разгрузки main thread

Недостатки
Высокий порог

вхождения
Высокая сложность

Реактивный подходЭффективенВ асинхронных приложенияхДля обработки ошибокДля разгрузки main threadНедостаткиВысокий порог вхожденияВысокая сложность

Слайд 22Зачем реактивный подход? Callback hell

Зачем реактивный подход? Callback hell

Слайд 23Императивный подход
interface IUserManager { fun getUser(): User fun

getUserBalance(userId: String): BigDecimal fun updateUserBalance(userId: String, balance: BigDecimal) } private val

manager: IUserManager = UserManager() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val user = manager.getUser() val balance = manager.getUserBalance(user.id) val newBalance = balance - payment manager.updateUserBalance(user.id, newBalance) view.showSnack("Balance has been updated to $newBalance")
Императивный подход interface IUserManager {   fun getUser(): User   fun getUserBalance(userId: String): BigDecimal

Слайд 24Добавим асинхронность
interface IUserManager { fun getUser(onSuccess: (User) -> Unit,

onError: (Throwable) -> Unit) fun getUserBalance(userId: String, onSuccess: (BigDecimal)

-> Unit, onError: (Throwable) -> Unit) fun updateUserBalance(userId: String, balance: BigDecimal, onSuccess: () -> Unit, onError: (Throwable) -> Unit) } private val manager: IUserManager = UserManager() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) manager.getUser( onSuccess = { user -> manager.getUserBalance( userId = user.id, onSuccess = { balance -> val newBalance = balance - payment manager.updateUserBalance( userId = user.id, balance = newBalance, onSuccess = { view.showSnack("balance updated") }, onError = ::processError ) }, onError = ::processError ) }, onError = ::processError ) } private fun processError(th: Throwable) { ... }

Добавим асинхронностьinterface IUserManager {   fun getUser(onSuccess: (User) -> Unit, onError: (Throwable) -> Unit)

Слайд 25Добавим асинхронность
interface IUserManager { fun getUser(onSuccess: (User) -> Unit,

onError: (Throwable) -> Unit) fun getUserBalance(userId: String, onSuccess: (BigDecimal)

-> Unit, onError: (Throwable) -> Unit) fun updateUserBalance(userId: String, balance: BigDecimal, onSuccess: () -> Unit, onError: (Throwable) -> Unit) } private val manager: IUserManager = UserManager() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) manager.getUser( onSuccess = { user -> manager.getUserBalance( userId = user.id, onSuccess = { balance -> val newBalance = balance - payment manager.updateUserBalance( userId = user.id, balance = newBalance, onSuccess = { view.showSnack("balance updated") }, onError = ::processError ) }, onError = ::processError ) }, onError = ::processError ) } private fun processError(th: Throwable) { ... }

Слишком сложно

Добавим асинхронностьinterface IUserManager {   fun getUser(onSuccess: (User) -> Unit, onError: (Throwable) -> Unit)

Слайд 26Реактивный подход
interface IUserManager { fun getUser(): Single fun

getUserBalance(userId: String): Single fun updateUserBalance(userId: String, balance: BigDecimal): Completable } private

val manager: IUserManager = UserManager() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) manager.getUser() .flatMapCompletable { user -> manager.getUserBalance(user.id) .map { balance -> balance - cost } .flatMap { balance -> updateUserBalance(user.id, balance) } } .subscribe( onSuccess = { view.showSnack("balance updated") }, onError = ::processError ) }

Реактивный подходinterface IUserManager {   fun getUser(): Single   fun getUserBalance(userId: String): Single

Слайд 27Реактивный подход – это просто? Ну такое…

Реактивный подход – это просто? Ну такое…

Слайд 281. RxJava
https://github.com/ReactiveX/RxJava

2. Coroutines https://kotlinlang.org/docs/reference/coroutines-overview.html

3.

Android LiveData
https://developer.android.com/topic/libraries/architecture/livedata
4. Reactor, Akka, ets..
Реализация реактивного

подхода в android
1. RxJava   https://github.com/ReactiveX/RxJava2. Coroutines     https://kotlinlang.org/docs/reference/coroutines-overview.html3. Android LiveData    https://developer.android.com/topic/libraries/architecture/livedata

Слайд 29RxJava is a Java VM implementation of Reactive Extensions: a

library for composing asynchronous and event-based programs by using observable

sequences.

Основные паттерны
Observable
Observer (Subscriber)
Operators
Subscription
Schedulers

rxjava

RxJava is a Java VM implementation of Reactive Extensions: a library for composing asynchronous and event-based programs

Слайд 30Rxjava. Simple. What?

Rxjava. Simple. What?

Слайд 31Rxjava. Observable is a stream.

Rxjava. Observable is a stream.

Слайд 32
https://rxmarbles.com
Rxjava. Операторы на marble диаграммах

https://rxmarbles.comRxjava. Операторы на marble диаграммах

Слайд 33Schedulers - особые операторы RxJava, предназначенные для выполнения операций над

Observable на разных потоках Schedulers.io() Schedulers.computation() Schedulers.newThread() Schedulers.single() Schedulers.from(Executor executor) AndroidSchedulers.mainThread() RxAndroid — библиотека для RxJava, реализующая AndroidScheduler

для выполнения задач на основном потоке андроид приложения https://github.com/ReactiveX/RxAndroid

Rxjava shedulers. rxandroid

getItemsFromRemoteSource() .doOnNext { item -> Log.d(TAG, "Emitting item $item on thread ${currentThread().name}") } .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .doOnNext { item -> Log.d(TAG, "Consuming item $item on thread ${currentThread().name}") } .subscribe { item -> showItem(item) }


Слайд 34Проблемы:
Утечка SampleActivity при повороте экрана
Пересоздание презентера при повороте экрана
Rxjava и

жизненный цикл activity/fragment
class SampleActivity: AppCompatActivity() { private val presenter:

SamplePresenter = SamplePresenter() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) presenter.observeModel() .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.main()) .subscribe( { model -> bindModel(model) }, { th -> bindError(th) } ) } private fun bindModel(model: Model) { ... } private fun bindError(th: Throwable) { ... } }

Проблемы:Утечка SampleActivity при повороте экранаПересоздание презентера при повороте экранаRxjava и жизненный цикл activity/fragmentclass SampleActivity: AppCompatActivity() {

Слайд 35Иньекция презентера и отписка на onStop() решают проблему
Rxjava и

жизненный цикл activity/fragment
class SampleActivity: AppCompatActivity() { @Inject lateinit

var presenter: SamplePresenter private var modelSubscription: Subscription? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState, persistentState) ComponentManager.mainComponent.inject(this) } override fun onStart() { super.onStart() modelSubscription = presenter.observeModel() .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.main()) .subscribe( { model -> bindModel(model) }, { th -> bindError(th) } ) } override fun onStop() { super.onStop() modelSubscription?.unsubscribe() } }

Иньекция презентера и отписка на onStop() решают проблему Rxjava и жизненный цикл activity/fragmentclass SampleActivity: AppCompatActivity() {

Слайд 36RxLifecycle позволяет автоматически завершать rx подписки по событиям жизненного цикла

компонентов андроида
https://github.com/trello/RxLifecycle
Rxjava и жизненный цикл activity/fragment. rxlifecyrcle
class SampleActivity: RxActivity() {

@Inject lateinit var presenter: SamplePresenter override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) ComponentManager.mainComponent.inject(this) presenter.observeModel() .subscribeOn(Schedulers.io()) .compose(bindToLifecycle()) .subscribe( { userInfo -> bindUserInfo() }, { th -> bindError() } ) } }

RxLifecycle позволяет автоматически завершать rx подписки по событиям жизненного цикла компонентов андроида https://github.com/trello/RxLifecycleRxjava и жизненный цикл activity/fragment.

Слайд 37Поход в сеть

Маппинг запросов

Горячие подписки на обновление модели

Временные отсчеты (debounce,

таймер)

Ретраи запроса (поллинг)


Rxjava. Типичные варианты применения

Поход в сетьМаппинг запросовГорячие подписки на обновление моделиВременные отсчеты (debounce, таймер)Ретраи запроса (поллинг)…Rxjava. Типичные варианты применения

Слайд 38Retrofit — Type-safe HTTP client for Android and Java by Square,

Inc.
https://square.github.io/retrofit/

Rxjava и Retrofit. Реактивный поход в сеть
interface ScalaApi {

@GET("magazine/articles/snippets") fun getJournalArticles( @Query("category") articleCategory: Array, @Query("mark") mark: String, @Query("model") model: String, @Query("super_gen_id") superGen: String?, @Query("page_size") pageSize: Int ): Single @GET("user/offers/{category}") fun getUserOffers( @Path("category") category: String = "all", @Query("page") page: Int, @Query("sort") sort: String?, @Query("page_size") pageSize: Int, @Query("with_daily_counters") withDailyViews: Boolean = false, @Query("moto_category") motoCategory: List? = null, @Query("truck_category") truckCategory: List? = null, @Query("section") state: String? = null, @Query("status") status: String? = null, @Query("mark_model") markModel: String? = null, @Query("price_from") priceFrom: Int? = null

implementation "com.squareup.retrofit2:retrofit:$retrofit" implementation "com.squareup.retrofit2:converter-gson:$retrofit" implementation("com.squareup.retrofit2:converter-protobuf:$retrofit") { transitive = false; } implementation "com.squareup.retrofit2:adapter-rxjava:$retrofit"

Retrofit — Type-safe HTTP client for Android and Java by Square, Inc.https://square.github.io/retrofit/Rxjava и Retrofit. Реактивный поход в сетьinterface

Слайд 39Rxjava. Маппинг запросов
class OfferDetailsInteractor( private val offersRepository: IOffersRepository,

private val userRepo: IUserOffersRepository, private val geoRepository: IGeoRepository,

private val recentBadgesRepository: IRecentBadgesRepository ) : IOfferDetailsInteractor { override fun getOffer( category: String, offerId: String, isUserOffer: Boolean, rids: List?, geoRadius: Int? ): Single = Single.zip( recentBadgesRepository.observeBadges().take(1).toSingle(), getOffer(isUserOffer, category, offerId, rids, geoRadius), { badges, offer -> offer.enrichWithRecentBadges(badges) } ) .doOnSuccess { cacheOffer(it) } private fun getOffer( isUserOffer: Boolean, category: String, offerId: String, rids: List?, geoRadius: Int? ): Single = when { isUserOffer -> offersRepository.getUserOffer(category, offerId) else -> offersRepository.getOffer(category, offerId, rids, geoRadius) } }

Rxjava. Маппинг запросовclass OfferDetailsInteractor(   private val offersRepository: IOffersRepository,   private val userRepo: IUserOffersRepository,

Слайд 40Rxjava. Горячие подписки на обновление модели
class FavoriteOfferInteractor(...): IFavoriteInteractor {

private val eventsSubj = PublishSubject.create().toSerialized() override fun switchFavorite(favorite: Offer):

Completable = when { favoriteRepo.idsCache.contains(favorite.id) -> removeFavorite(favorite) else -> addFavorite(favorite) } override fun favoriteSwitchEvents(): Observable> = eventsSubj }

Rxjava. Горячие подписки на обновление моделиclass FavoriteOfferInteractor(...): IFavoriteInteractor {    private val eventsSubj = PublishSubject.create().toSerialized()

Слайд 41Спасибо
Даниэл Сергеев

СпасибоДаниэл Сергеев

Обратная связь

Если не удалось найти и скачать доклад-презентацию, Вы можете заказать его на нашем сайте. Мы постараемся найти нужный Вам материал и отправим по электронной почте. Не стесняйтесь обращаться к нам, если у вас возникли вопросы или пожелания:

Email: Нажмите что бы посмотреть 

Что такое TheSlide.ru?

Это сайт презентации, докладов, проектов в PowerPoint. Здесь удобно  хранить и делиться своими презентациями с другими пользователями.


Для правообладателей

Яндекс.Метрика