Wrap activity_main.xml в макете координатора, так что это будет его родительский макет.
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<android.support.design.widget.AppBarLayout
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:theme="@style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="@style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<include layout="@layout/content_main" />
</android.support.design.widget.CoordinatorLayout>
Ответ Хармена довольно хороший, но позвольте мне немного рассказать о том, где это делается компилятором CoffeeScript и почему.
Когда вы что-то компилируете с помощью coffee -c foo.coffee
, вы всегда получите foo.js
, который выглядит следующим образом:
(function() {
...
}).call(this);
Почему это так? Хорошо, предположим, что вы поставили назначение, например
x = 'stringy string'
в foo.coffee
. Когда он видит это, компилятор спрашивает: существует ли x
в этой области или внешней области? Если нет, он помещает объявление var x
в начало этой области в выводе JavaScript.
Теперь предположим, что вы пишете
x = 42
в bar.coffee
, компилируете и объединяете foo.js
с bar.js
для развертывания. Вы получите
(function() {
var x;
x = 'stringy string';
...
}).call(this);
(function() {
var x;
x = 42;
...
}).call(this);
Таким образом, x
в foo.coffee
и x
в bar.coffee
полностью изолированы друг от друга. Это важная часть CoffeeScript: Переменные никогда не просачиваются из одного файла .coffee в другой, если явно не экспортированы (при подключении к общему глобальному файлу или к exports
в Node.js).
Вы можете переопределить это, используя флаг -b
(«bare») для coffee
, но это следует использовать только в очень особых случаях. Если бы вы использовали его в приведенном выше примере, вы получите результат
var x;
x = 'stringy string';
...
var x;
x = 42;
...
. Это может иметь ужасные последствия. Чтобы проверить это самостоятельно, попробуйте добавить setTimeout (-> alert x), 1
в foo.coffee
. И обратите внимание, что вам не нужно объединять два файла JS самостоятельно - если вы используете два отдельных тега <script>
для включения их на страницу, они все равно эффективно работают как один файл.
Изолируя области действия разных модулей, компилятор CoffeeScript избавляет вас от головной боли от беспокойства о том, могут ли разные файлы в вашем проекте использовать одни и те же имена локальных переменных. Это обычная практика в мире JavaScript (см., Например, источник jQuery или почти любой плагин jQuery) - CoffeeScript просто позаботится об этом за вас.
Хорошая особенность этого подхода в том, что он создает частные переменные, поэтому не будет никакого конфликта с именами переменных:
(function() {
var privateVar = 'test';
alert(privateVar); // test
})();
alert(typeof privateVar); // undefined
Добавление .call(this)
делает ключевое слово this
ссылкой к тому же значению, на которое ссылаются за пределами функции. Если он не добавлен, ключевое слово this
будет автоматически ссылаться на глобальный объект.
Вот небольшой пример, показывающий разницу:
function coffee(){
this.val = 'test';
this.module = (function(){
return this.val;
}).call(this);
}
var instance = new coffee();
alert(instance.module); // test
function coffee(){
this.val = 'test';
this.module = (function(){
return this.val;
})();
}
var instance = new coffee();
alert(typeof instance.module); // undefined
Синтаксис аналогичен следующему:
(function() {
}());
, который называется непосредственной функцией. функция определяется и выполняется немедленно. Преимущества этого в том, что вы можете поместить весь свой код в этот блок и назначить функцию одной глобальной переменной, тем самым уменьшая загрязнение глобального пространства имен. это обеспечивает хороший ограниченный объем внутри функции.
Это типичная схема, которую я использую при написании модуля:
var MY_MODULE = (function() {
//local variables
var variable1,
variable2,
_self = {},
etc
// public API
_self = {
someMethod: function () {
}
}
return _self;
}());
не уверен, какие именно минусы могут быть, если кто-то еще знает о них, я был бы рад узнать о них. ]