Страницы

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

пятница, 7 февраля 2020 г.

Почему отступ считается по разному на разных девайсах?

#java #android #android_layout


Мне нужно поднять активити вверх на 15% от высоты экрана(вне зависимости от того
какой экран, элемент должен подняться на 15%) за пределы видимости экрана... Я делаю
это таким образом 

Вот у меня есть кастомная вьюха




/.../







/.../





вот здесь я устанавливаю параметры, чтоб это сделать

private void initVar() {
//  Margin set in % of the screen
    int marginLeft = 0;

------>   int marginTop = 15; вот здесь я указываю процент от высоты экрана

    int marginRight = 0;
    int marginBottom = 0;

//      Здесь мы получаем высоту и ширину экрана
    Display display = getWindowManager().getDefaultDisplay();
    Point size = new Point();
    display.getSize(size);
    screenWidth = size.x;
    screenHeight = size.y;

//      Здесь мы устанавливаем параметры для нашего вью
    RelativeLayout.LayoutParams param = new RelativeLayout.LayoutParams(
            ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);

    param.setMargins((screenHeight * marginLeft) / 100, -((screenHeight * marginTop)
/ 100),
            (screenHeight * marginRight) / 100, (screenHeight * marginBottom) / 100);

    mTextureView = (AutoFitTextureView) findViewById(R.id.texture);
    mTextureView.setLayoutParams(param);


и вот что получается, когда я загружаю это все дело на телефон Samsung S5 1980x1080
то это выглядит как я и рассчитываю, ровно 15% занято(белая полоса снизу это дефолтный
цвет экрана который открывается когда мы поднимаем вью)



Но когда я тот же проект загружаю на эмулятор 1280x800 то почему то экран поднимается
не на 15% а на 25-30%(точно не на 15%)



А если попробовать на эмуляторе с разрешением 1440*2560, то получается вот так



На первом скриншоте белая полоса  не доходит до надписи "Front picture", а на втором
захватывает его и даже больше а на а на третьем это вообще 50% экрана... 

Очень странно получается потому что формула по которой идет расчет подразумевает,
что я беру высоту экрана и получаю от нее ровно 15%... 

Почему на одном устройстве это 15%, а на другом  это больше а на третьем это вообще
50% экрана??

Что я делаю не так??

Вот скриншот на котором margin установлены на 0 и на экране не должно быть белой
полосы, но она есть, хотя на реальном девайсе ее нет...


    


Ответы

Ответ 1



Вам нужно учитывать плотность экрана. Данные (ширина и высота) дисплея из системы вам выдают в пиксилях и они реальны. Но когда вы указываете в коде дополнительные цифры, их нужно пересчитывать под плотность экрана. К примеру, вы хотите добавить 15 пикселей высоты для вьюшки. Вы берете view.getHeight() и получаете размер в пикселях и когда прибавите просто число view.getHeight() + 15, на экранах с разной плотностью эффект быдет выглядеть по разному, где нормально, где меньше. Но выполнив view.getHeight() + dpToPx(getActivity(), 15). Ваши 15 пикселей пересчитаются в реальные пиксели для вашего экрана. public static int dpToPx(Context context, float dp) { // add 0.5 to round up return (int) ((dp * context.getResources().getDisplayMetrics().density) + 0.5); } public static int pxToDp(Context context, int px) { // add 0.5 to round up return (int) ((px / context.getResources().getDisplayMetrics().density) + 0.5); } UPD Технически у вас расчеты правильны. За исключением того, что вы берете расчет высоту всего экрана. У вас не учитывается высота софтварных кнопок (бек\хом\таск) берите высоту вашего контейнера, а не высоту экрана. Так как высота контейнера известна только после ее создания, вешайте лайоут обсервер (к примеру в onCreate). ViewTreeObserver viewTreeObserver = mViewRoot.getViewTreeObserver(); viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { int viewHeight = mViewRoot.getHeight(); mViewRoot.getViewTreeObserver().removeGlobalOnLayoutListener(this); // тут все ваши расчеты } }); mViewRoot - это Ваш рутовый контейнер. И все равно при расчетах в % у вас будут отличаться цифры, а значит оно не будет выглядеть одинаково на всех устройствах(я правильно понимаю? что кнопка фото у вас статичного размера :)). Я бы рекомендовал выставить в xml нужную высоту в для нижней view (mTextureView) , и изменять в пропорциях размер превью камеры (на остаток высоты) ;)

Ответ 2



Попробуйте вот так высоту/ширину экрана получать: public static int getWidth(AppCompatActivity act) { DisplayMetrics displaymetrics = new DisplayMetrics(); act.getWindowManager().getDefaultDisplay().getMetrics(displaymetrics); return displaymetrics.widthPixels; } public static int getHeight(AppCompatActivity act) { DisplayMetrics displaymetrics = new DisplayMetrics(); act.getWindowManager().getDefaultDisplay().getMetrics(displaymetrics); return displaymetrics.heightPixels; }

Ответ 3



На вашем месте, я бы наверно начал действовать так же. Но сейчас уже есть готовое решение из коробки appcompat. Это PercentRelativeLayout который позволяет задавать размеры дочерних вью в процентах.

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

Отправить комментарий