Android: Размеры в Custom Dialog неточные - PullRequest
0 голосов
/ 16 апреля 2020

Я пытаюсь создать собственный диалог для моего приложения. При запуске программы результат сильно отличается от ожидаемого.

XML файл:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="@color/colorPrimaryDark">

<LinearLayout
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="200dp"
    android:background="@color/colorAccent">
</LinearLayout>

<LinearLayout
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@color/colorPrimary">

    <Button
        android:id="@+id/button10"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Button" />
</LinearLayout>
</LinearLayout>

Класс java:

public class SinglePSettings extends AppCompatDialogFragment {
@Override
public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
    AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
    LayoutInflater inflater = getActivity().getLayoutInflater();

    View view = inflater.inflate(R.layout.layout_singlepsettings, null);
    builder.setView(view)
            .setTitle("Settings");

    return builder.create();
}
public void onResume()
{
    super.onResume();
    Window window = getDialog().getWindow();
    Point size = new Point();
    Display display = window.getWindowManager().getDefaultDisplay();
    display.getSize(size);
    int width = (int)(size.x * 0.90);
    int height = (int)(size.y * 0.90);
    window.setLayout(width, height);
    window.setGravity(Gravity.CENTER);
}

Expectation and result

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

1 Ответ

1 голос
/ 16 апреля 2020

Это связано с тем, что макет root вашего диалога имеет высоту match_parent, а общий размер содержимого составляет 200 дп для первого ребенка Linearlayout + ~ 24 дп для второго ребенка Linearlayout, что меньше общего размера диалога.

Вы должны либо изменить высоту родительского LinearLayout на wrap_content, либо добавить android:weight=1 к любому из дочерних LinearLayouts


update : Позвольте я пытаюсь объяснить, как работает линейный макет. обратите внимание, что все это из опыта, и вам следует прочитать официальные документы для лучшего понимания.

Измерение, которое соответствует orientation, играет решающую роль для детей линейного макета. таким образом, если ориентация горизонтальная, все дочерние элементы будут складываться горизонтально, и их атрибут width необходимо будет контролировать.

Представьте горизонтальную линейную планировку дома. В настоящее время предположим, что вы всегда должны сохранять свой важный атрибут как match_parent в родительском линейном макете. таким образом, наш линейный макет / дом имеет width=match_parent. Существует три основных способа добавления дочерних элементов:

Сохранение каждого дочернего элемента в виде wrap_content

  • Это означает, что каждый дочерний элемент будет занимать пространство экрана, равное его собственный размер.
  • если нет. Этот пункт работает меньше, или размер экрана достаточно велик.
  • Но , если их много больших предметов, то общее требуемое им пространство = сумма всех их отдельных ширин. Если эта сумма больше, чем размер экрана, то некоторые элементы будут go исчезать с экрана.

  • В нашей домашней аналогии это похоже на то, что мы складывают все столы, стулья, кровати и т. д. c по прямой линии. если они занимают меньше места, чем пространство между 2 торцевыми стенками, то это здорово, но если им нужно больше горизонтального пространства, то мы должны сломать стену, чтобы их отрегулировать.

  • Таким образом, не рекомендуется хранить все ваши элементы как wrap content

enter image description here

Сохранение 1 / более детей как match_parent

  • Это очень неправильный подход. Когда вы сохраняете ширину дочернего элемента как match_parent, вы в основном говорите компилятору предоставить полное пространство экрана для этого единственного представления.

  • И компилятор определенно сделает это. Даже если это кнопка, она будет вытянута на весь экран, и другие виды не будут видны, потому что они фактически находятся вне экрана.

  • Когда их несколько видов с width=match_parent, он просто выделит все пространство экрана для первого просмотра слева.

  • В нашей домашней аналогии это похоже на то, как только вы изменили атрибут ширины вашего стула на match_parent, комната волшебным образом расширила его, чтобы занять все пространство, и, таким образом, вашу кровать, table, et c теперь все раздавлены сбоку комнаты.

enter image description here

содержание layout_weight=x для 1 или более детей

  • Это лучший подход для линейного размещения. Я думаю, что назначает процентное соотношение экрана для вида.

  • Если ваш дочерний вид имеет weight=x, то на него не повлияет значение, присутствующее в вашем представлении crucial attribute. это означает, что вы можете иметь width= match_parent или wrap_content или даже 1000000dp, если он имеет weight=x, он будет отображаться в полноэкранном режиме. Обратите внимание, что речь идет только о критически важном атрибуте, то есть ширине в данном случае.

  • Также очень интересно знать, как вид с весом будет влиять на другие виды.

    • если в другом представлении есть width = match_parent (и без атрибута веса), это представление займет все пространство экрана, но на этот раз наше представление с весом не будет вытеснено . вместо этого, это get - это минимальное пространство, которое он должен получить (т.е. либо wrap_content, либо фиксированное значение, которое мы передали для width=x).
      Это как если бы мы добавили атрибут weight к нашему стулу и атрибут match_parent к нашей кровати. Кровать раздавила все остальные предметы, но кресло все равно заняло необходимое место.

enter image description here

  • Нечто подобное происходит, когда другие элементы имеют wrap_content в качестве значений их важный атрибут (но не весовой атрибут). На этот раз представление с весом будет занимать все пространство, кроме пространства, требуемого другим видом (сравните изображение ниже с первым случаем и обратите внимание, как круг теперь занимает все оставшееся пространство, не раздавливая другие виды)
    enter image description here

  • Когда у каждого атрибута есть вес, тогда это становится забавной игрой процентов. если у нас есть 2 элемента и каждый элемент имеет layout_weight=1, то независимо от их ширины, оба будут занимать 50% пространства. Если один из них имеет layout_weight=2, то распределение будет 2: 1, то есть 66%: 33%. это делает взгляды отзывчивыми при разных размерах экрана и ориентации

enter image description here


Таким образом, лучший способ для использования дочерних представлений в линейном макете означает wrap_content в качестве атрибута критического измерения и layout_weight=x. это сделает его более отзывчивым и более простым в управлении. Кроме того, я не много говорил о наличии фиксированных весов в критическом атрибуте измерения, потому что они всегда беспорядок. Не буду вдаваться в подробности (вы можете попробовать сами), но они всегда будут либо раздавлены, либо раздавлены другими взглядами

...