Страницы

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

вторник, 25 декабря 2018 г.

Пиксельная линейка в chrome

После переустановки Chrome пропала пиксельная линейка. Говорят, что ее как-то можно включить, если не врут, подскажите как. Спасибо.


Ответ

F12 → сочетание клавиш Ctrl+Shift+M F12 → вторая сверху слева кнопка панельки (Toggle Device Mode):


Чтобы включить также показ линий, ограничивающих элемент на этой линейке нужно включить опцию "Show Rulers". Жмём F12 → F12 и ставим галку в пункте General → Elements → Show Rulers:


Вот что получается:

Можно не включать "Device Mode", тогда пиксельные линейки будут появляться только при инспектировании элемента.

Нестандартный вывод текста в TextView

Необходимо вписать текст в TextView ограниченный кругом. пример Подскажите, в какую сторону копать


Ответ

Написал код onDraw(Canvas canvas) своего класса наследника TextViewрешающий задачу для меня. Комментарии описываю последовательность действий:
@Override protected void onDraw(Canvas canvas) { // круг, в который вписан текст canvas.drawCircle(mRadius, mRadius, mRadius, mGlowPaint); // высота строки float textHeight = mTextPaint.getFontSpacing(); // измеряем длинну текста float widthText = mTextPaint.measureText(mText); if(widthText <= mRadius*2) { // всего одна строка помещается - рисуем ее и выходим canvas.drawText(mText, mRadius, mRadius, mTextPaint); return; } // 1 Делим строку на два, сдвигаем к ближайшему пробелу. получаем индекс пробела, близкого к середине текста int centerSpace = calcCenterSpace(mText); // 2 Сначала рисуем текст вверх : String leftString = mText.substring(0, centerSpace); int cnt = 0; // количество прорисованных строк вверх float widthLine; int n; while (true) { // измеряем длинну строки widthLine = calcWidthLine(mRadius, textHeight * cnt++); // считаем сколько символов поместится в новой строке n = mTextPaint.breakText(leftString, false, widthLine, null); if (n == 0) // прерываем, так как строка слишком длинная break; // создаем строку int rest = leftString.length() - n; // проверка на последнюю строку if (rest != 0) { String s = leftString.substring(leftString.length() - n); // обрезаем до первого пробела int fixed = s.indexOf(' '); // создаем новую аккуратную строку s = s.substring(fixed + 1); // рисуем ее на высоте соответствующую данной строке canvas.drawText(s, mRadius, mRadius - textHeight * cnt + textHeight, mTextPaint); // сокращаем левый кусок текста на длинну отрисованной строки leftString = leftString.substring(0, leftString.length() - s.length()); } else { // последняя строка canvas.drawText(leftString, mRadius, mRadius - textHeight * cnt + textHeight, mTextPaint); break; } } // 3. Теперь рисуем вниз String rightString = mText.substring(centerSpace); cnt = 0; // количество прорисованных строк вверх while(true){ widthLine = calcWidthLine(mRadius, textHeight * cnt++); n = mTextPaint.breakText(rightString, false, widthLine, null); if (n == 0) // прерываем если весь текст не поместился break; int rest = rightString.length() - n; if(rest != 0) { String s = rightString.substring(0, n); int fixed = s.lastIndexOf(' '); s = s.substring(0, fixed); canvas.drawText(s, mRadius, mRadius + textHeight * cnt, mTextPaint); rightString = rightString.substring(s.length(), rightString.length()); } else { canvas.drawText(rightString, mRadius, mRadius + textHeight * cnt, mTextPaint); break; } } }
private static int calcWidthLine(float r, float b){ double a = Math.sqrt(r * r - b * b); return (int)(2*a); }
private static int calcCenterSpace(String text){ int index = text.length()/2; if(text.charAt(index) == ' ') return index; String subLeft = text.substring(0, index); int indexSpaceLeft = subLeft.lastIndexOf(' '); String subRight = text.substring(index + 2); int indexSpaceRight = subRight.indexOf(' '); if(index - indexSpaceLeft <= indexSpaceRight) return indexSpaceLeft; else return indexSpaceRight; }
Алгоритм не идеален, на поставленную задачу выполняет. Еще в планах сделать растягивание строки. Оптимизация и недочеты приветствую. Вот скриншоты:

Как заблокировать всплывание клавиатуры в элементе EditText?

При уставновке фокуса в EditText, на экране появляется клавиатура. Как реализовать её блокировку (убрать всплывание)?


Ответ

Сам уже нашёл. Нужно установить свойство:
editText.setInputType(InputType.TYPE_NULL);

Програмно снять выделение с TreeView

Необходимо снять выделение с TreeView при удалении элемента. По умолчанию выделяется первый элемент, а задать SelectedItem = null не получается так как это свойство только для чтения. Как это реализовать?


Ответ

В обычном случае вы не создаёте элементы TreeView вручную, а генерируете их автоматически, используя ItemsSource + ItemTemplate
При этом treeView.SelectedItem будет не TreeViewItem, а элемент коллекции, привязанной к ItemsSource. Так что приведение к типу TreeViewItem не сработает.
Чтобы получить из этого собственно визуальный элемент, обычно применяется конструкция list.ItemContainerGenerator.ContainerFromItem(selectedItem);. Но в случае TreeView она, к сожалению, работает лишь на верхнем уровне: каждый TreeViewItem рекурсивно сам является TreeView, и заботится сам о своих контейнерах, так что list.ItemContainerGenerator ничего не знает о вложенных частях дерева.
Неплохое универсально работающее (но многословное) решение — следить за изменением выделенного элемента, и запоминать его в code behind.
Пример:


public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); DataContext = new[] { new DataHolder("Привет-привет", null), new DataHolder("Пока-пока", null), new DataHolder(null, new[] { new DataHolder("Я очень", null), new DataHolder("буду ждать", new[] { new DataHolder("звонка", null) }), }), };
TreeViewItem selectedItemTV = null; TV.AddHandler(TreeViewItem.SelectedEvent, (RoutedEventHandler)((sender, args) => selectedItemTV = (TreeViewItem)args.OriginalSource));
TreeViewItem selectedItemTV2 = null; TV2.AddHandler(TreeViewItem.SelectedEvent, (RoutedEventHandler)((sender, args) => selectedItemTV2 = (TreeViewItem)args.OriginalSource));
var dt = new DispatcherTimer() { Interval = TimeSpan.FromSeconds(5) }; dt.Tick += (sender, args) => { if (selectedItemTV != null) { selectedItemTV.IsSelected = false; selectedItemTV = null; } if (selectedItemTV2 != null) { selectedItemTV2.IsSelected = false; selectedItemTV2 = null; } }; dt.Start(); } }

public class DataHolder { public string Key { get; private set; } public IEnumerable Value { get; private set; }
public DataHolder(string key, IEnumerable value) { Key = key; Value = value; } }
Ну или вы можете подписаться обычным способом в XAML'е: TreeViewItem.Selected="TVItemSelected"

Ещё есть решение с полным рекурсивным обходном дерева, и поиском TreeViewItem'а, как описано здесь. Но оно мне кажется слишком уж неэффективным, и наверняка плохо дружит с виртуализацией.

Postgresql Выборка по строке ФИО

Есть строка фильтра. Пользователь вводит в нее часть имени или фамилии или отчества, отображается список частичных совпадений, пользователь вводит польностью фимилию Иванов, отображаются Ивановы, далее он ставит пробел и вводит С, поиск должен найти всех Ивановых, чьи имена или отчества начинаются на С.
В список не должны попадать фамилии на С., в БД ФИО хранятся отдельными полями. Как привильнее всего построить текст запроса? Я разбивал строку на слова и для каждого слова я добавлял условия, получалось следующее:
SELECT * FROM users WHERE (name ILIKE word1 OR surname ILIKE word1 OR patronymic ILIKE word1) AND (name ILIKE word2 OR surname ILIKE word2 OR patronymic ILIKE word2) AND (name ILIKE word3 OR surname ILIKE word3 OR patronymic ILIKE word3)


Ответ

А почему вы не хотите фамилии на С ? Если считать, что пользователь вводит сначала имя Иван, а потом вводит букву С было бы логично показать Ивана Сидорова, а Сидора Иванова наверное не надо. А если он вводит две буквы, то уже начинать искать ? как ему найти "Гевара Че" ?
Предлагаю такую логику: пока слово одно - ищем его во всех трех полях по частичному совпадению. Но возможно надо ограничить минимальный размер слова, если оно из одной буквы, то боюсь результатов слишком много будет. Если слов более одного - то первое слово ищем во всех полях по точному совпадению, а остальные слова - то частичному совпадению.
Запрос, реализующий вышеуказанную логику:
select distinct users.* from ( select split_part(S,' ',N.column1) w1,split_part(S,' ',N.column2) w2, split_part(S,' ',N.column3) w3, substr('%%',2-N.column1/2) p1,substr('%%',2-N.column2/2) p2, substr('%%',2-N.column3/2) p3,(rtrim(S) like '% _')::int+1 np from (values(1,2,3),(1,3,2),(2,1,3),(2,3,1),(3,2,1),(3,1,2)) N, (select Cast('Пушкин А С' as varchar) S) S ) A join users on name LIKE w1||substr(p1,np,1) and surname LIKE w2||substr(p2,np,1) and patronymic LIKE w3||substr(p3,np,1)
Единственный параметр передаваемый в запрос - ваша строка "Пушкин С А". Перед передачей строки из нее надо удалить лишние пробелы, т.е. слова должны быть разделены строго одним пробелом. Если нужен регистронезависимый поиск - приведите строку к нужному регистру в самом запросе
По работе запроса: цифры в подзапросе N - весь набор расположения слов. w1-w3 - выделенные компоненты из строки, согласно номерам в N. p1-p3 - один % для первого слова строки, и %% для остальных. np - признак поиска полного соответствия (когда слов более 1). substr в самом низу по этому признаку берут или не берут % для like.

Android. Как сделать активным касание в любую часть экрана?

У меня на экране есть несколько edit кнопок. После их заполнения нужно, чтобы весь экран стал активным и при нажатии на любую часть экрана переходило на следующий экран. Как это сделать?


Ответ

MainActivity.class
public class MainActivity extends AppCompatActivity{
EditText et; EditText et_2; LinearLayout main_layout;
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main_layout);
et = (EditText) findViewById(R.id.editText); et_2 = (EditText) findViewById(R.id.editText2); main_layout = (LinearLayout) findViewById(R.id.main_layout);
main_layout.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { if (et.getText().length() > 0 && et_2.getText().length() > 0) { Toast.makeText(getApplicationContext(), "onTouch работает", Toast.LENGTH_SHORT).show(); } return false; } }); } }
main_layout.xml


Нахождение положительных пиков функции


Требуется программно найти количество и местоположение положительных пиков на графике. Известно, что количество пиков нечетное. Обычно 3, 5 или 7. В данном случае 3. Также известно, что за каждым положительным пиком следует отрицательный. Как лучше решить такую проблему на Python? Желательно без подбора коэффициентов Дополнение: Данные всегда начинаются с положительного пика и заканчиваются отрицательным. Данные представляют собой вертикальную проекцию изображения, обработанную функцией np.gradient(projection)/projection. То есть отношение второй производной функции к её высоте.


Ответ

Поскольку просто локальный экстремум не устраивает, надо добавить проверку превышения порога для отбраковки мелких пиков и артефактов. Порог можно вычислить как СКО выборки, умноженное на некоторую константу, соответствующую доверительному интервалу для математического ожидания. На практике эту константу принимают равной 2.5
UPD С учётом дополнительных условий задачи пиком следует считать максимум на отрезке от "верха" (начальной точки или первого значения выше q) до "низа" (первого значения ниже -q). При этом для массива размерности n возможен следующий алгоритм:
Найти СКО выборки и вычислить порог q Положить top=0 Найти координату bottom первой точки отрезка [top, n-1] со значением меньше -q. Если такой точки нет, перейти к п.7. Найти координату максимума на отрезке [top, bottom-1]. Если значение максимума больше q, записать его в массив пиков. Найти координату top первой точки отрезка [bottom+1, n-1] со значением больше q. Если такой точки нет, перейти к п.7. Перейти к п.3. Использовать массив пиков.