android:fitsSystemWindows="true"
Это твоя проблема. Ваш FrameLayout начинает раздуваться под строкой состояния, высота которой ~ 25dp, поэтому AppCompatImageView немного выше.
Первое решение: удалить android:fitsSystemWindows="true"
из activity_start_onboarding.xml
FrameLayout.
Второе решение: Добавьте <item name="android:windowDrawsSystemBarBackgrounds">true</item>
к вашему ColdstartSplashTheme
. Фон начинает рисоваться под строкой состояния, и растровое изображение будет выше.
Для тех, кто обращается к виду, существует ли optgroup:
/**
* Sorting options
* and optgroups
*
* @param selElem select element
* @param optionBeforeGroup ?bool if null ignores, if true option appear before group else option appear after group
*/
function sortSelect(selElem, optionBeforeGroup = null) {
let initialValue = selElem.tagName === "SELECT" ? selElem.value : null;
let allChildrens = Array.prototype.slice.call(selElem.childNodes);
let childrens = [];
for (let i = 0; i < allChildrens.length; i++) {
if (allChildrens[i].parentNode === selElem && ["OPTGROUP", "OPTION"].includes(allChildrens[i].tagName||"")) {
if (allChildrens[i].tagName == "OPTGROUP") {
sortSelect(allChildrens[i]);
}
childrens.push(allChildrens[i]);
}
}
childrens.sort(function(a, b){
let x = a.tagName == "OPTGROUP" ? a.getAttribute("label") : a.innerHTML;
let y = b.tagName == "OPTGROUP" ? b.getAttribute("label") : b.innerHTML;
x = typeof x === "undefined" || x === null ? "" : (x+"");
y = typeof y === "undefined" || y === null ? "" : (y+"");
if (optionBeforeGroup === null) {
if (x.toLowerCase().trim() < y.toLowerCase().trim()) {return -1;}
if (x.toLowerCase().trim() > y.toLowerCase().trim()) {return 1;}
} else if (optionBeforeGroup === true) {
if ((a.tagName == "OPTION" && b.tagName == "OPTGROUP") || x.toLowerCase().trim() < y.toLowerCase().trim()) {return -1;}
if ((a.tagName == "OPTGROUP" && b.tagName == "OPTION") || x.toLowerCase().trim() > y.toLowerCase().trim()) {return 1;}
} else if (optionBeforeGroup === false) {
if ((a.tagName == "OPTGROUP" && b.tagName == "OPTION") || x.toLowerCase().trim() < y.toLowerCase().trim()) {return -1;}
if ((a.tagName == "OPTION" && b.tagName == "OPTGROUP") || x.toLowerCase().trim() > y.toLowerCase().trim()) {return 1;}
}
return 0;
});
if (optionBeforeGroup !== null) {
childrens.sort(function(a, b){
if (optionBeforeGroup === true) {
if (a.tagName == "OPTION" && b.tagName == "OPTGROUP") {return -1;}
if (a.tagName == "OPTGROUP" && b.tagName == "OPTION") {return 1;}
} else {
if (a.tagName == "OPTGROUP" && b.tagName == "OPTION") {return -1;}
if (a.tagName == "OPTION" && b.tagName == "OPTGROUP") {return 1;}
}
return 0;
});
}
selElem.innerHTML = "";
for (let i = 0; i < childrens.length; i++) {
selElem.appendChild(childrens[i]);
}
if (selElem.tagName === "SELECT") {
selElem.value = initialValue;
}
}
У меня была такая же проблема. Вот решение jQuery , которое я придумал:
var options = jQuery.makeArray(optionElements).
sort(function(a,b) {
return (a.innerHTML > b.innerHTML) ? 1 : -1;
});
selectElement.html(options);
Не так красиво, как пример JQuery от Marco, но с прототипом (мне может не хватать более элегантного решения) это будет:
function sort_select(select) {
var options = $A(select.options).sortBy(function(o) { return o.innerHTML });
select.innerHTML = "";
options.each(function(o) { select.insert(o); } );
}
А затем просто передайте ему элемент выбора:
sort_select( $('category-select') );