Почему у LinearLayout instance.getLayoutParams есть неправильный класс?

Если я объявляю LinearLayout linearLayout и смотрю linearLayout.getLayoutParams(), он дает мне ViewGroup.LayoutParams, а не LinearLayout.LayoutParams.

Поэтому я должен использовать повторяющуюся (и, следовательно, плохую) конструкцию стиля:

int lm = ((LinearLayout.LayoutParams) linearLayout.getLayoutParams()).leftMargin?

Нужно ли мне это использовать, если я хочу, например, достичь полей?

Это мое недопонимание Android или Java, или и то, и другое?

Ответ 1

Я думаю, что ваше понимание "LayoutParams" неверно. Представление (или макет) LayoutParams должно быть экземпляром "родительского представления LayoutParams".

Например, здесь LinearLayout в RelativeLayout. Это LinearLayout LayoutParams должно быть RelativeLayout.LayoutParams. Это позволяет нам правильно устанавливать атрибуты, такие как "centerInParent" и т.д.

Когда вы вызываете getLayoutParams(), это возвращает различные экземпляры LayoutParams, которые соответствуют родительскому типу ViewGroup. В результате нам нужно повторно указать тип представления LayoutParams при вызове getLayoutParams().

Ответ 2


Просто, чтобы выразить это очень прямо:

Помните, что когда вы получаете LayoutParams представления, их класс определяется классом родительского представления этого представления.

Это означает один очень важный факт:

Вам нужно отбросить LayoutParams View, потому что вы не можете заранее знать, что такое класс родителя. Итак, если родителем представления является LinearLayout, то LayoutParams будет иметь тип LinearLayout.LayoutParams и STILL, вы должны отдать его этому типу!


Я не уверен в исходном коде и как он идет. Но это очень логично, так как RelativeLayout.LayoutParams, например, обладает такими свойствами, как ABOVE и BELOW, которые не найдены в LinearLayout.LayoutParams. И эти параметры на самом деле зависят от родителя.

Ответ 3

Вы не используете LinearLayout.LayoutParams для LinearLayout.LayoutParams. Это бессмысленно. Также неясно, если linearLayout в вашем коде является переменной экземпляра... В любом случае вы можете просто ссылаться на LayoutParams внутри представления, который простирается от некоторого типа представления, чтобы получить этот вид LayoutParams. Например, если вы находитесь внутри класса, который простирается от RelativeLayout, то

LayoutParams params = new LayoutParams(200, LayoutParams.WRAP_CONTENT);

получает вас RelativeLayout.LayoutParams. В противном случае вам потребуется квалифицировать LayoutParams, который вы ищете. Чтобы получить/применить LinearLayout LayoutParams, вам просто нужно

LinearLayout.LayoutParams params = new LinearLayout.LayoutParams();

ИЗМЕНИТЬ

linearLayout.getLayoutParams() возвращает LayoutParams, который вы указали при вызове setLayoutParams, поэтому сначала убедитесь, что вы это сделали. Затем, как только вы это сделали, вам просто нужно отбросить LayoutParams, которые были возвращены в LayoutParams, который вы установили. поэтому

LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) linearLayout.getLayoutParams() 

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

По сути, ответ на ваш вопрос: ДА, вам нужно отбросить LayoutParams, который вы получаете от getLayoutParams, потому что это метод, полученный из класса View, который возвращает суперкласс LayoutParams, который является ViewGroup.LayoutParams, который из-за полиморфизма, может быть применена к типу, который вы знаете.

Ответ 4

Используете ли вы Eclipse и используете параметр "Упорядочить импорт" Eclipse для импорта Android-библиотек? Если это так, существует несколько разных библиотек, называемых LayourParams, Eclipse, похоже, импортирует файл framelayout, а не linearlayout, как вам нужно.

Итак, просто измените импорт в верхней части вашего класса.

Ответ 5

Вам не нужно получать объект LinearLayout Params из самого LinearLayout. Вы можете создать новый самостоятельно.

// Set up the height and width of the layout, you can set FILL_PARENT 
// or even WRAP_CONTENT
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(width, height);
// Set up your margins
lp.setMargins(left, top, right, bottom);

Теперь используйте этот объект lp в экземпляре объекта LinearLayout

linearLayout.setLayoutParams(lp);