Страницы

Поиск по вопросам

вторник, 23 октября 2018 г.

Как растянуть картинку на всю доступную ширину

Есть ImageView которое находится внутри LinearLayout. Т.к. у картинки может быть как вертикальная так и горизонтальная ориентация выглядят они соответственно тоже по разному, можно ли как то вставить картинку (растянуть ее) на всю доступную ширину, при этом зафиксировав значение высоты. Т.е. что бы в прямоугольнике с фиксированной высотой и шириной равной размерам контейнера в котором находится ImageView можно было установить картинку (либо ее фрагмент), что бы при любой ориентации картинки они смотрелись одинаково?
вот что у меня получилось

image_view.xml


Ответ


Параметр scaleType отвечает за размер самой картинки, установленной при помощи src (для background не будет работать!). Размер самого объекта ImageView не зависит от размера изначальной картинки.
scaleType="centerCrop" означает, что картинка будет увеличена (сохраняя пропорции) до тех пор, пока хотя бы одно измерение не будет равно размеру ImageView. Все, что будет вылезать, видно не будет (от англ. crop - обрезать).

что такое android N и как его будет поддерживать Android Studio?

Сейчас устанавливаю Studio 2.1 и читая описание понял, что одним из преимуществ является то, что она может работать с android N. В котором можно применять принципы Java8... Как то так я понял
Почитал про android N и не понял это версия 7.0 после Marshmallow ? Новая 2.1 полностью совместима с предыдущими версиями? Не получиться так, что эта версия только для android N? И насчет канала обнослений посоветуйте какой нужно использовать? Согласно офф. документации написано, что уже доступны обновления Canary channel
Предварительная версия Android Studio 2.1 в настоящее время доступна на канале обновлений Canary.
У меня сейчас студия обновляется по Stable channel я почитал про Canary и написано, что она не рекомендуется...


Ответ

Android N - следующая версия после Android M, у которого версия 6.0 (API 23). Релиз будет скорее всего осенью, как обычно и происходит - выход "мажорных" обновлений раз в год.
В данный момент выпускаются бета прошивки для Nexus устройств, как раз для разработчиков, с целью теста и перевода своих приложений на новую версию API к релизу Android N. API уже доступно сейчас через SDK Manager, можно попробовать новые фишки.
Теперь про Android Studio 2.1: у меня, если не ошибаюсь, она обновилась с версии 2.0, которая вышла в апреле, причем на канале обновлений Stable.
И API N версии, и студия версии 2.1 полностью обратно совместимы с предыдущими версиями API.
Канал обновления лучше выбирать Stable, как понятно из названия - стабильный. Далее идут каналы Beta, Dev и Canary, где Canary является самым нестабильным.

Что понимается под пространством имён в спецификации HTML5?

Выдержка из спецификации:
In HTML documents, elements in the HTML namespace may have an xmlns attribute specified, if, and only if, it has the exact value "http://www.w3.org/1999/xhtml". This does not apply to XML documents.
Переводится примерно: "В HTML документах элементы в HTML-пространстве имён могут иметь атрибут xmlns, если он имеет точное значение "http://www.w3.org/1999/xhtml". "
И тут я понял, что вообще ничего не понимаю. Я думал, что для html нет понятия пространство имен.
Ссылка HTML пространство имен в спецификации ведет на список:
Пространство имён HTML это: http://www.w3.org/1999/xhtml Пространство имён MathML это: http://www.w3.org/1998/Math/MathML Пространство имён SVG это: http://www.w3.org/2000/svg Пространство имён XLink это: http://www.w3.org/1999/xlink Пространство имён XML это: http://www.w3.org/XML/1998/namespace Пространство имён XMLNS: http://www.w3.org/2000/xmlns/
И я совсем не могу понять, что такое имеется ввиду под пространством имен в данной спецификации? Пространство имен html ведет вообще на xhtml спецификацию. Причем тут html5 и xhtml? И как это связано с пространством имен?
Что значит фраза "элементы в HTML-пространстве имён могут иметь атрибут xmlns"? В html пространстве имен это где? И как работает этот атрибут в html5?


Ответ

Про атрибут xmlns
По поводу xmlns, в том же тексте, сразу после приведённой в вопросе цитате сказано следующее:
Note: In HTML, the xmlns attribute has absolutely no effect. It is basically a talisman. It is allowed merely to make migration to and from XHTML mildly easier. Заметка: В HTML, xmlns атрибут не имеет никакого эффекта. Это просто талисман. Он лишь позволяет проще выполнить преобразования в и из XHTML документов.
С этим разобрались, xmlns в HTML нам не потребуется. Его конечно можно использовать для HTML-элементов, но это не имеет смысла, так как для всех структур в HTML документе уже есть предустановленные значения "пространства имён", список которых приведён в вопросе, и изменить их на другие значения никто не позволит. Проще говоря, нижепревидённые примеры равнозначны:

А вот так уже не получится, так как xmlns попросту игнорируется, и html всё равно будет располагаться в пространстве имён "http://www.w3.org/1999/xhtml", как было сказано выше.
Про пространство имён
По аналогии с именами классов, пакетов и т.п из языков программирования, пространство имён позволяет отличить один элемент от другого, когда они имеют одинаковое название, но принадлежат разным пространствам имён. Где это может произойти в HTML? Например когда мы используем svg в html:
Ссылка в SVG Ссылка в HTML
И нам потребовалось изменить размер шрифта у ссылки в svg. Просто написать в стилях a { font-size: 1.5em } уже не получится, так как это правило применится и к обычной ссылки тоже. Вот здесь на помощь приходят возможности CSS по работе с пространствами имён. Для этого в CSS выполним такие действия:
1) Используя ключевое слово @namespace указываем наименование "приставки" пространства имён, с каким мы будем иметь дело:
@namespace svg url(http://www.w3.org/2000/svg);
Заметка: адрес пространства имён для SVG взят из спецификации, а вместо svg можно использовать другое наименование.
2) Теперь с помощью приставки svg можно обратиться непосредственно к метке , которая расположена в , с помощью специального синтаксиса CSS:
svg|a { font-size: 1.5em; }
Итог
Атрибут xmlns в HTML не нужен. Спецификация за нас определила названия пространств имён для конкретных структур HTML, XML, SVG и их элементов. Для того чтобы в CSS получить доступ к конкретному элементу с использованием пространства имён необходимо использовать форму namespace|css-selector, предварительно дав наименование для пространства имён с помощью @namespace.

Как корректно перейти с Jade на Pug?

Здравствуйте. Я создал чистый проект при помощи express-generator'а и проверив его на устаревшие зависимости при помощи npm-check, начал их обновлять. Всё обновилось успешно, кроме jade, который недавно сменил имя. NPM пишет по этому поводу следующее:
npm WARN deprecated jade@1.11.0: Jade has been renamed to pug, please install the latest version of pug instead of jade
Я выполнил следующие команды:
npm uninstall --save jade npm install --save pug npm start
Сервер запустился, но при переходе на localhost:3000 упал с ошибкой 'Error: Cannot find module 'jade'. Тогда я обновил в коде app.js
app.set('view engine', 'jade');
на
app.set('view engine', 'pug');
и сервер падает с новой ошибкой: Error: Failed to lookup view "error" in views directory "~/documents/projects/node/template/views"
Подскажите пожалуйста, что я делаю не так?


Ответ

Всё, спасибо, разобрался методом тыка! :) Нужно было в папке views переименовать все файлы *.jade на *.pug!

Задача на логику

Вот столкнулся с таким заданием на собеседовании. Лично я не разобрался, что тут к чему, и интересно было бы всё таки услышать ответ.
Мастеру дали восемь цепей по 6 звеньев в каждой. Его попросили соединить их в одну непрерывную цепь. Он выполнил просьбу, при этом он разъединил и обратно соединил всего 6 звеньев. Как ему это удалось?


Ответ

Полностью разобрал одну цепь и соединил остальные с помощью её элементов? (догадка за 10 секунд) (из моего комментария)

Механизм работы таймера в qt

Всем привет! Может кто-то пояснить механизм работы таймера qt. Он формирует сообщение в очереди сообщений или влияет на процесс обработки этой очереди?
Например: Допустим у нас есть функция которая создает сигнал и кладет его в очередь потока. Это вызывает слот потока в котором мы вызываем ту же функцию. По идее получается как только мы закончили отрабатывать слот мы выходим в очередь обработки, там видим новый сигнал, и опять заходим в слот.
Теперь если в том же потоке есть таймер. Он будет параллельно со слотом класть в очередь сообщения о таймауте, как бы из другого потока? Сможет ли он прервать мой вечный цикл указанный выше? Или он просто ставит где-то в обработчики очереди сообщений флажочек и в нужное время вызывается сигнал таймера?
UPD: Спасибо за оба ответа, отдал предпочтение второму ответу, так как он все же более полный и ближе, как мне показалось к тому что спрашивал.
Резюмирую понимание устройства таймера: Сигнал таймаута рождается в момент возврата к разбору очереди сообщения, именно там добываются необходимые сообщения от операционной среды и определяется что таймер свое отработал. Поэтому без возврата к разбору очереди событий таймера не появиться, ровно как их невозможно заблокировать если есть возвраты к очереди сообщений. Важно что возврат формирует именно рождение сигнала, а не только его обработку, до возврата сигнал не родится.


Ответ

Немного издали... Если сигнал подключается к слоту с флагом Qt::AutoConnection (используется по умолчанию) или Qt::DirectConnection, и вызываемый слот принадлежит объекту, находящемуся в том же потоке, что и объект, от которого исходит сигнал, то никакой обработчик очереди событий не вызывается. Производится вызов слота прямо на месте. Если этот слот посредством прямого подключения через сигнал будет вызывать сам себя, то случится бесконечная рекурсия, вплоть до переполнения стека, ну и конечно неизбежного краха приложения.
Для того, чтобы связка сигнал-слот срабатывала через очередь в рамках одного и того же потока необходимо всегда явно указывать флаг Qt::QueuedConnection. Только в этом случае создаётся соответствующий наследник класса события, который и помещается в очередь событий.
Внутренняя реализация QTimer пользуется методами регистрации таймеров операционной системы, на которой выполняется приложение (это позволяет указывать таймеру дополнительные флаги, в случае, если требуется, например, повышенная точность). Соответственно, именно она формирует события о том, что время такого-то таймера в очередной раз истекло. Точно такие же события поступают при движении курсора мыши и нажатии клавиш. Эти нативные события попадают в очередь событий приложения одно за другим.
Все события обрабатываются строго по очереди. Здесь как никогда верно правило: "Кто первый встал, того и тапки". Это означает, что если таймер создан с точностью, допускающей определённую погрешность в интервале, то события таймера будут поступать на обработку с непредсказуемым (в рамках погрешности, разумеется) интервалом и могут попасть в очередь до или после любого другого события.
Если объект таймера существует в отдельном потоке, у которого имеется своя собственная очередь событий, и при этом будет пытаться вызывать слот объекта, находящегося в другом потоке, то событие о вызове слота попадёт в очередь событий целевого потока. В этом случае будет действовать ровно то же самое правило про тапки: если перед поступившим событием уже имеются какие-то события, то будут выполнены сначала они, а событие таймера на вызов слота подождёт своей очереди.
Однако существуют подводные камни, возможность появления которых стоит иметь в виду. Предположим, имеется следующая схема:
Событие А: слот СЛОТ вызывает сам себя через очередь событий;
Событие Б: таймер вызывает СЛОТ с неким интервалом;
Получится следующее:
Вызовы А будут идти друг за другом, как и положено. Поскольку каждое новое событие всегда встаёт вконец очереди, то вызов Б через какое-то время без проблем вклинится в порядок вызовов А. Однако каждый вызов слота СЛОТ всегда порождает новый вызов А. Таким образом, после каждого Б будет порождаться не один новый А, а второй, третий (и т.д.) бесконечные циклы из А

Почему идет ошибка like.addEventListener is not a function?

Есть такой код и он работает:
function openLikeBlock() { var like = document.getElementById("like"); like.addEventListener('click', function (e) { e.preventDefault(); if (!this.classList.contains('open')) this.classList.add('open'); else this.classList.remove('open'); }); }
Но если добавить ClassName то будет ошибка:
var like = document.getElementsByClassName("like");
Uncaught TypeError: like.addEventListener is not a function
Мне нужно именно класс, так как таких блоков несколько на странице (поэтому использую this)
Вопрос: как сделать, что бы я мог получать элемент по классу, а не ID?


Ответ

Потому что getElementsByClassName возвращает коллекцию элементов, а у коллекции нет метода addEventListener
для решение можно просто пробежаться по возвращенной коллекции. например так:
[].forEach.call(like,function(el){ el.addEventListener('click', function (e) {...}) });