Samsung Galaxy S4 смещает значок панели действий

#android #android-actionbar

#Android #android-панель действий

Вопрос:

Я внедряю визуальный дизайн для приложения, и оказывается, что Galaxy S4 смещает значок actionbar home, как показано на скриншоте:

введите описание изображения здесь

Скриншоты были сделаны с использованием одного и того же файла APK на обоих устройствах. Фиолетовая направляющая расположена на 16dp слева, и это очень важно для остальной части макета экрана. S4 добавляет еще 8dp или около того. Из-за этого дополнительного поля значок home действительно выглядит неуместно.

Я пробовал кучу других телефонов Samsung с разными разрешениями / плотностями (Galaxy S3, Galaxy S4 Mini, Galaxy Ace), и все они правильно выравнивают значок при 16dp.

Я бы списал это на фрагментацию Android и двигался дальше, но рыночная доля Galaxy S4 настолько велика, что я не могу игнорировать проблему. Кто-нибудь еще сталкивался с этим и нашел исправление?

Комментарии:

1. Подтверждена та же проблема на Galaxy S3 с обновлением 4.4.2. Действительно, действительно раздражает.

2. Это может быть проблемой с вашими стилями, ActionBar иногда это может быть немного сложно в этом отношении, но, скорее всего, Samsung просто ActionBar все испортил. Сначала я бы проверил, устраняет ли проблему отрицательный запас.

3. Шерлок делегирует «родную» панель действий, если она есть в версии ОС.

4. Просто мысль: если у кого-то есть корневой S3 / S4, возможно, сравнение иерархий представлений может дать некоторое представление. Т.Е. Есть ли какие-либо различия в иерархиях? Если нет, как насчет различных значений свойств просмотра и т. Д.? В качестве альтернативы, может быть интересно определить, страдают ли пользовательские ПЗУ от той же проблемы?

5. Я не понимаю, почему все комментируют, что это не происходит на их S4. Я действительно надеялся найти решение этой проблемы, но я вижу, что каждое отдельное приложение на S4 делает это. Передо мной Moto G, Nexus 7 и S4, только S4 облажается. Думаю, мне придется оставить это так.

Ответ №1:

Этот код довольно понятен. Сначала проверяется, является ли текущее устройство моделью Samsung Galaxy S4, на основе списка, найденного здесь. Если это так, затем он ищет соответствующие View элементы на основе ActionBar макета и home ImageView относительного положения в иерархии. Затем он сдвигает их влево на (положительный) offset параметр. Он также проверяет, отображается ли пользовательский View параметр, и также сдвигает его. Единственное изменение View x это координаты s, поэтому оно должно работать с любой темой или стилем.

 private static final String SAMSUNG = "SAMSUNG";
private static final String[] S4_MODELS = {
    "GT-I9506", "GT-I9505G", "SGH-I337", "SGH-M919",
    "SCH-I545", "SPH-L720", "SCH-R970", "GT-I9508",
    "SCH-I959", "GT-I9502", "SGH-N045", "SGH-I337M",
    "SGH-M919V", "SCH-R970X", "SCH-R970C"
};

private void adjustGalaxyS4(int offset)
{
    if (isGalaxyS4())
        shiftHomeView(offset);
}

private boolean isGalaxyS4()
{
    String manufacturer = Build.MANUFACTURER.toUpperCase();
    String model = Build.MODEL.toUpperCase();

    if (SAMSUNG.equals(manufacturer) amp;amp; !TextUtils.isEmpty(model))
    {
        for (String m : S4_MODELS)
            if (model.contains(m))
                return true;
    }

    return false;
}

private void shiftHomeView(float offset)
{
    try
    {
        View grandParentView = (View) ((View) findViewById(android.R.id.home).getParent()).getParent();
        View upView = ((ViewGroup) ((ViewGroup) grandParentView).getChildAt(0)).getChildAt(0);

        grandParentView.setX(grandParentView.getX() - offset);
        upView.setX(upView.getX()   offset);

        if ((getActionBar().getDisplayOptions() amp; ActionBar.DISPLAY_SHOW_CUSTOM) != 0)  
            getActionBar().getCustomView().setX(getActionBar().getCustomView().getX() - offset);
    }
    catch (Exception e)
    {
        // Fail silently
    }
}
  

Комментарии:

1. Я предпочел что-то менее тупое, но это достаточно эффективно в качестве обходного пути. Мне придется сделать его немного более общим, потому что смещение не только Galaxy S4, поэтому я попытаюсь обнаружить смещение по фактической координате X против ожидаемая координата X. Забавно, я написал нечто подобное ранее, но я попытался настроить параметры макета представления и не смог заставить его работать с requestLayout() или без него. Иногда более простой подход — просто вызвать setX() — явно более убедителен.

2. в итоге мы использовали библиотеку MaterialMenu с открытым исходным кодом в качестве пользовательского представления на панели действий, полностью обойдя проблему.