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

Добрый день, использую LinearLayout, как контейнер для хранения TextView, и хочу, чтобы расстояние между элементами было поменьше, но не понимаю, как это сделать.
- Вопрос задан более года назад
- 180 просмотров
Комментировать
Решения вопроса 1

ох, ты типа все методом тыка делаешь? ну не прокатит так.
не нужно LinearLayout вкладывать в RelativeLayout
так разнесло кнопки потому что не понимаешь что делаешь, из за layout_weight так произошло.
буквально по второй ссылке чувак разбирает и объясняет все твои косяки
Как linearlayout может размещать объекты
Контейнер LinearLayout представляет простейший контейнер — объект ViewGroup , который упорядочивает все дочерние элементы в одном направлении: по горизонтали или по вертикали. Все элемены расположены один за другим. Направление разметки указывается с помощью атрибута android:orientation .
Если, например, ориентация разметки вертикальная ( android:orientation=»vertical» ), то все элементы располагаются в столбик — по одному элементу на каждой строке. Если ориентация горизонтальная ( android:orientation=»horizontal» ), то элементы располагаются в одну строку. Например, расположим элементы в горизонтальный ряд:

Если бы мы указали для LinearLayout атрибут android:orientation=»vertical» , то элементы размещались бы по вертикали:

Вес элемента
LinearLayout поддерживает такое свойство, как вес элемента, которое передается атрибутом android:layout_weight . Это свойство принимает значение, указывающее, какую часть оставшегося свободного места контейнера по отношению к другим объектам займет данный элемент. Например, если один элемент у нас будет иметь для свойства android:layout_weight значение 2, а другой — значение 1, то в сумме они дадут 3, поэтому первый элемент будет занимать 2/3 оставшегося пространства, а второй — 1/3.
Если все элементы имеют значение android:layout_weight=»1″ , то все эти элементы будут равномерно распределены по всей площади контейнера:
В данном случае LinearLayout имеет вертикальную ориентацию, поэтому все элементы будут располагаться сверху вниз. Все три элемента имеют значение android:layout_weight=»1″ , поэтому сумма весов всех элементов будет равна 3, а каждый элемент получит по трети пространства в LinearLayout:

При этом так как у нас вертикальный стек, то нам надо также установить для свойства layout_height значение 0dp . Если бы LinearLayout имел горизонтальную ориентацию, то для свойства layout_width надо было бы установить значение 0dp .
Еще один атрибут android:weightSum позволяет указать сумму весов всех элементов. Например:
LinearLayout здесь задает сумму весов равную 7. То есть все пространство по вертикали (так как вертикальная ориентация) условно делится на семь равных частей.
Первый TextView имеет вес 1, то есть из этих семи частей занимает только одну. Второй TextView имеет вес 3, то есть занимает три части из семи. И третий имеет вес 2. Итоговая сумма составляет 6. Но так как LinearLayout задает вес 7, то одна часть будет свободна от всех элементов.

Программное создание LinearLayout
Создание LinearLayout в коде java:
package com.example.viewapp; import androidx.appcompat.app.AppCompatActivity; import android.os.Bundle; import android.widget.LinearLayout; import android.widget.TextView; public class MainActivity extends AppCompatActivity < @Override protected void onCreate(Bundle savedInstanceState) < super.onCreate(savedInstanceState); //setContentView(R.layout.activity_main); LinearLayout linearLayout = new LinearLayout(this); // горизонтальная ориентация linearLayout.setOrientation(LinearLayout.HORIZONTAL); TextView textView = new TextView(this); textView.setText("Hello"); textView.setTextSize(30); // создаем параметры позиционирования для элемента LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams (LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT); // устанавливаем отступы layoutParams.setMargins(100, 100, 0, 0); textView.setLayoutParams(layoutParams); // добавляем элемент в LinearLayout linearLayout.addView(textView); setContentView(linearLayout); >>

Дополнительная версия конструктора LinearLayout.LayoutParams() в качестве третьего параметра позволяет указать вес элемента:
package com.example.viewapp; import androidx.appcompat.app.AppCompatActivity; import android.os.Bundle; import android.widget.LinearLayout; import android.widget.TextView; public class MainActivity extends AppCompatActivity < @Override protected void onCreate(Bundle savedInstanceState) < super.onCreate(savedInstanceState); LinearLayout linearLayout = new LinearLayout(this); linearLayout.setOrientation(LinearLayout.VERTICAL); // первое текстовое поле TextView textView1 = new TextView(this); textView1.setText("Hello"); textView1.setTextSize(30); // textView1 имеет вес 3 linearLayout.addView(textView1, new LinearLayout.LayoutParams (LinearLayout.LayoutParams.MATCH_PARENT, 0, 3)); // второе текстовое поле TextView textView2 = new TextView(this); textView2.setText("Android"); textView2.setBackgroundColor(0xFFBDBDBD); textView2.setTextSize(30); // textView2 имеет вес 2 linearLayout.addView(textView2, new LinearLayout.LayoutParams (LinearLayout.LayoutParams.MATCH_PARENT, 0, 2)); setContentView(linearLayout); >>

Layout_gravity
Атрибут layout_gravity позволяет устанавливать позиционирование относительно LinearLayout. Он принимает следуюшие значения:
- top : выравнивает элемент по верхней границе контейнера
- bottom : выравнивает элемент по нижней границе контейнера
- left : выравнивает элемент по левой границе контейнера
- right : выравнивает элемент по правой границе контейнера
- center_vertical : выравнивает элемент по центру по вертикали
- center_horizontal : выравнивает элемент по центру по горизонтали
- center : элемент позиционируется в центре
- fill_vertical : элемент растягивается по вертикали
- fill_horizontal : элемент растягивается по горизонтали
- fill : элемент заполняет все пространство контейнера
- clip_vertical : обрезает верхнюю и нижнюю границу элемента
- clip_horizontal : обрезает правую и левую границу элемента
- start : элемент позиционируется в начале (в верхнем левом углу) контейнера
- end : элемент позиционируется в конце контейнера (в верхнем правом углу)
В данном случае первый элемент TextView будет позиционироваться по левой стороне контейнера ( android:layout_gravity=»left» ), второй TextView по центру ( android:layout_gravity=»center» ), третий — по правой стороне ( android:layout_gravity=»right» ) и четвертый — по центру ( android:layout_gravity=»center» )

Стоит учитывать ориентацию контейнера. Например, при вертикальной ориентации все элементы будут представлять вертикальный стек, идущий сверху вниз. Поэтому значения, которые относятся к позиционированию элемента по вертикали (например, top или bottom) никак не будут влиять на элемент. Также при горизонтальной ориентации LinearLayout не окажут никакого влияния значения, которые позиционируют элемент по горизонтали, например, left и right.
Для установки программно параметра layout_gravity надо задать поле gravity у объекта LinearLayout.LayoutParams :
package com.example.viewapp; import androidx.appcompat.app.AppCompatActivity; import android.os.Bundle; import android.view.Gravity; import android.widget.LinearLayout; import android.widget.TextView; public class MainActivity extends AppCompatActivity < @Override protected void onCreate(Bundle savedInstanceState) < super.onCreate(savedInstanceState); LinearLayout linearLayout = new LinearLayout(this); linearLayout.setOrientation(LinearLayout.VERTICAL); LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams (LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT); // установка layout_gravity layoutParams.gravity = Gravity.CENTER; // первое текстовое поле TextView textView1 = new TextView(this); textView1.setText("Hello"); textView1.setTextSize(30); linearLayout.addView(textView1, layoutParams); setContentView(linearLayout); >>
В качестве значения передается одна из констант класса Gravity, которые аналогичны значениям атрибута.
Размещении двух объектов в строку в LinearLayout
Как я могу разместить два ImageButton в одну строку в LinearLayout? Я бы использовал RelativeLayout, но в RelativeLayout объекты не размещаются в один столбик. Если и использовать RelativeLayout, то я не знаю, как сделать так, чтобы объекты в relativeLayout размешались в один столбик. Код:
private void potatoFunc() < LinearLayout mainLayout = findViewById(R.id.mainmain); final ImageButton imageView = new ImageButton(Main2Activity.this); LinearLayout.LayoutParams imageViewLayoutParams = new LinearLayout.LayoutParams(450, 150); LinearLayout.LayoutParams imageParamsDeleteBtn = new LinearLayout.LayoutParams(50, 75); final ImageButton deleteButton = new ImageButton(Main2Activity.this); deleteButton.setImageResource(R.drawable.delete); deleteButton.setScaleType(ImageView.ScaleType.FIT_XY); deleteButton.setLayoutParams(imageParamsDeleteBtn); deleteButton.setBackgroundColor(Color.TRANSPARENT); imageParamsDeleteBtn.setMargins(50,40,0,0); mainLayout.addView(deleteButton); imageView.setImageResource(R.drawable.product); imageView.setScaleType(ImageView.ScaleType.FIT_XY); imageView.setLayoutParams(imageViewLayoutParams); imageView.setBackgroundColor(Color.TRANSPARENT); imageViewLayoutParams.setMargins(15,10,0,0); mainLayout.addView(imageView); SharedPreferences sharedPref = getPreferences(Context.MODE_PRIVATE); SharedPreferences.Editor editor = sharedPref.edit(); editor.putInt("int", 25); editor.apply(); >private void ogyrecFunc()
- android
- android-button
- android-linearlayout
Layout интерфейса приложения Android
В приложении Android контейнер компонентов имеет тип ViewGroup. Существует несколько разновидностей классов, наследующих свойства ViewGroup и определяющих структуру расположения компонентов в интерфейсе : LinearLayout, RelativeLayout, FrameLayout, TableLayout, ConstraintLayout и т.д. Отличия этих классов связаны с упорядочиванием компонентов :
| • ConstraintLayout | позволяет привязывать компонент к границам экрана или к другим компонентам. |
| • LinearLayout | позволяет размещать View-компоненты в виде одной строки (horizontal) или одного столбца (vertical). |
| • RelativeLayout | настраивает положение каждого компонента относительно других. |
| • AbsoluteLayout | использует для каждого компонента явную позицию на экране в системе координат X, Y. |
| • TableLayout | отображает элементы в виде таблицы, по строкам и столбцам. |
Рассмотрим вопрос привязки компонентов в ConstraintLayout. Для этого создадим новое приложение p02layout по типу и подобию, описанному на странице Модули Android.
Привязка компонента в ConstraintLayout
Во вновь созданном проекте p02layout откроем модуль activity_main.xml в режиме Design и удалим включаемый по умолчанию компонент TextView с текстом «Hello World!», поскольку ему не требуется привязка; она создана студией. После этого добавим новый компонент TextView из палитры (Pallete) в интерфейс окна.

Если переключиться на текстовое представление модуля activity_main.xml, то можно сразу же увидить, что :

- в качестве контейнера компонентов студия использовала при создании приложения ConstraintLayout;
- компонент TextView подчеркнут красной линией.
При наведении на TextView мышкой во всплывающей подсказке Android Studio покажет ошибку :
This view is not constrained, it only has designtime positions, so it will jump to (0,0) unless you add constraints.
Этим сообщением IDE подсказывает нам, что компонент не «привязан», и его текущее положение в интерфейсе актуально только на время разработки. А при старте приложения положение компонента будет проигнорировано, и View переместится в точку (0,0), т.е. в верхний левый угол. Чтобы зафиксировать положение View в определенном месте ConstraintLayout необходимо добавить привязки (constraints). Они будут задавать положение View на экране относительно каких-либо других элементов или относительно родительского View.
Как добавить привязки?
Если выделить на экране TextView, то можно увидеть 4 круга по его сторонам. Эти круги используются для привязки компонента по горизонтали и вертикали. Напоминаю, что контейнер ConstraintLayout занимает весь экран и его края совпадают с краями экрана, а также он является родителем TextView.

Чтобы привязать компонент к левой стороне экрана по горизонтали выделите его левой кнопкой мыши, после этого тащите левый круг к левой границе экрана. Как только стрелка коснется левой границы экрана, то компонент также сразу же переместиться к левой стороне экрана. Изображение курсора меняется в зависимости от нахождения курсора на компоненте, перемещения круга или перемещения компонента.

После этого необходимо «схватить» компонент левой клавишей мыши и переместить вправо на требуемую величину (нижний скриншот). Обратите внимание на число под стрелкой, которое меняется при перемещении компонента. Это величина отступа TextView от объекта, к которому он привязан; в нашем случае от левой границы родителя ConstraintLayout.

Теперь, Вам не составит труда привязать компонент к верхней границе экрана. Для этого необходимо повторить предыдущую операцию, но только уже с верхней стороной компонента.
Примечание : привязка компонента изображается на экране в виде прямой сплошной линии. Но если сделать двустороннюю привязку по горизонтали или вертикали, т.е. привязать компонент, например, к левой и правой сторонам экрана, то привязки будут изображены на экране в виде пружины.
«Привязка» компонентов между собой
Компоненты можно привязывать не только к границам родителя, но и к другим View. Связанные между собой компоненты перемещаются по экрану вместе. То есть, перемещение главного компонента в новую позицию формы автоматически переместит и связанные с ним другие компоненты.
Давайте разместим в интерфейсе новый компонент типа PlainText и привяжем его к компоненту TextView. Компоненты связываются между собой также соответствующими кругами на сторонах. Как только вы подводите стрелку «дочернего» компонента к «родительскому», то студия подсветит у родителя его круги. Останется только совместить стрелку с кругом. После этого можно привязанный компонент перетаскивать и менять его относительное удаление.

Удаление привязки
Чтобы удалить привязку, необходимо просто нажать на соответствующий кружок компонента.
Исходный текст activity_main.xml
Исходный текст включает описания двух компонентов. Главный тег описания макета интерфейса представлен типом android.support.constraint.ConstraintLayout. Идентификатор компонента в описании обозначается атрибутом android:id. Остальные параметры (атрибуты) определяют размеры, относительные положения и специфические свойства компонента.
На следующем скриншоте представлен интерфейс работающего приложения. При вводе в текстовую строку PlainText символов устройство Android (эмулятор) открыл панель клавиатуры и высветил подсказки.

Шаблон LinearLayout
Прежде чем переходить к линейному макетированию компонентов заглянем в основной класс приложения MainActivity.java.
import android.support.v7.app.AppCompatActivity; import android.os.Bundle; public class MainActivity extends AppCompatActivity < @Override protected void onCreate(Bundle savedInstanceState) < super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); >>
Класс MainActivity.java имеет метод onCreate, который вызывается, когда приложение создает и отображает Activity. В первой строке метода происходит обращение к суперклассу. А вот во второй строке метод setContentView(int) фоормирует интерфейс Activity из layout-файла. В качестве аргумента методу передается не путь к layout-файлу (res/layout/activity_main.xml), а идентификатор файла ID.
setContentView(R.layout.activity_main)
Создадим новый layout. Для этого выберем пункт меню New => XML => Layout XML file. Любители горячих клавиш могут использовать второй способ : при выделенной папке res/layout нажать ALT+Insert, и там уже клавишами выбрать соответствующий пункт.

Во вновь открывшемся окне необходимо определить наименование XML-файла макетирования интерфейса и выбрать тип (Root Tag).

После определения имени linear в папке layout должна появиться новая запись (linear.xml). Все файлы XML, связанные с настройкой интерфейса, размещаются в директории приложения res/layout.

Теперь откроем файл linear.xml в режиме Design и разместим в интерфейсе три кнопки. При перетаскивании первой кнопки, Вы увидете, что она заняла весь экран по ширине. После перетаскивания второй кнопки размер первой уменьшился наполовину. И так далее. На скриншоте можно увидеть положения кнопок в интерфейсе. Кроме этого, в панели дерева (Component Tree) родителем кнопок является контейнер LinearLayout.

В исходном коде файла linear.xml (вкладка Text) можно посмотреть описание интерфейса :
Положение с горизонтального без каких-либо проблем можно изменить на вертикальное. Для этого следует либо в тексте файла linear.xml переопределить атрибут «android:orientation» на «vertical», либо в панели атрибутов установить соответствующее значение, как это представлено на скриншоте.

Чтобы стартовать приложение с шаблоном интерфейса linear.xml необходимо в метод onCreate класса MainActivity.java внести изменения во вторую строку : setContentView(R.layout.linear). Интерфейс работающего приложения с линейным контейнером расположения компонентов LinearLayout представлен на скриншоте.

Если Вы полностью самостоятельно повторили все действия, связанные с привязками компонентов в контейнерах типа ConstraintLayout и LinearLayout, то Вам не составит труда выполнить подобные действия с контейнерами RelativeLayout и AbsoluteLayout.
Продолжение статьи с табличным расположением компонентов TableLayout представлено здесь.