Чтобы представить большую картину, я собираюсь объяснить как динамическое, так и лексическое связывание.
this
относится к объекту, . Это регулярно читаемое предложение на SO. Но это все еще только фраза, довольно абстрактная. Есть ли соответствующий шаблон кода для этого предложения?
Да, есть:
const o = {
m() { console.log(this) }
}
// the important patterns: applying methods
o.m(); // logs o
o["m"](); // logs o
m
- это метод, потому что он полагается на this
. o.m()
или o["m"]()
означает m
применяется к o
. Эти шаблоны - это перевод Javascript на нашу знаменитую фразу.
Существует еще один важный шаблон кода, на который вы должны обратить внимание:
"use strict";
const o = {
m() { console.log(this) }
}
// m is passed to f as a callback
function f(m) { m() }
// another important pattern: passing methods
f(o.m); // logs undefined
f(o["m"]); // logs undefined
Он очень похож на предыдущий шаблон, только скобки отсутствуют. Но последствия значительны: когда вы передаете m
функции f
, вы вытаскиваете m
своего объекта / контекста o
.
Функции стрелок не имеют собственных this
/ super
/ arguments
. Они наследуют их от родительской лексической области:
const toString = Object.prototype.toString;
const o = {
foo: () => console.log("window", toString.call(this)),
bar() {
const baz = () => console.log("o", toString.call(this));
baz();
}
}
o.foo() // logs window [object Window]
o.bar() // logs o [object Object]
Помимо глобальной области (Window
в браузерах) только функции способны сформировать область видимости в блоках Javascript (и {}
в ES2015). Когда вызывается функция стрелки o.foo
, нет никакой окружающей функции, из которой baz
может наследовать ее this
. Следовательно, он фиксирует привязку this
глобальной области действия, привязанную к объекту Window
.
Когда baz
вызывается o.bar
, функция стрелки окружена o.bar
( o.bar
формирует родительскую лексическую область) и может наследовать привязку o.bar
this
. o.bar
был вызван на o
, и поэтому его this
привязан к o
.
Отрицательные поля официально не поддерживаются Android. Они никогда не должны были работать, но из-за ошибки в некоторых макетах они сделали. Google решил, что он достаточно полезен, они никогда не исправляли ошибку, но они также заявляют, что это не обязательно то, что они всегда поддерживают.
Правильный способ сделать эту работу - установить высоту этого представления 0, тогда, когда вы хотите, чтобы он отображал анимацию в представлении, увеличивая ее высоту до тех пор, пока она не достигнет нужного размера.
Я сделал такие вещи, когда контейнер верхнего уровня - ConstraintLayout
(вместо LinearLayout
, который у вас есть сейчас). В этом случае вы можете установить для скрытого FrameLayout ограничение top_ToBottomOf="parent"
, которое будет размещать его на экране внизу, а затем оживить его вверх, чтобы показать его, с чем-то вроде этого
myFrameLayout.animate().translationY(-myFrameLayout.getHeight()).setInterpolator(
new DecelerateInterpolator()).setListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
// do anything you need to do once the animation is done
}
}).setDuration(1000);