2012-01-20 1 views
11

Если я объявлю LinearLayout linearLayout и посмотрю linearLayout.getLayoutParams(), он дает мне ViewGroup.LayoutParams, а не LinearLayout.LayoutParams.Почему у LinearLayout instance.getLayoutParams есть неправильный класс?

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

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

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

Является ли это моим непониманием для Android или Java, или того и другого?

ответ

20

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

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

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

+1

К сожалению, тип, возвращаемый методом linearLayout.getLayoutParams, не имеет ничего общего с классом макета, который содержит этот linearLayout. Что касается удобства, предоставление родительского класса «LayoutParams» бессмысленно - если мне это нужно, я мог бы наложить linearLayout на ViewsGroup и взять его getLayputParams и сделать их универсальными. Но Android дает мне * только * ViewsGroup.LayoutParams. – Gangnus

+1

Потому что он неоднозначен, его нельзя возвращать определенный тип LayoutParams, хотя он не является общим типом. Система не может знать, какой тип. Ваш вопрос бессмыслен для меня. – lulumeya

+0

Если linearLayout имеет класс LinearLayout, функция linearLayout.getLayoutParams - это класс LinearLayout и может легко вернуть класс LinearLayout.LayoutParams. Где ошибка? – Gangnus

1

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

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

+0

В классе я использую ViewGroups.getLayoutParams и LinearLayout.getLayoutParams. Я не могу установить импорт android.widget.LinearLayout.LayoutParams вместо импорта android.view.ViewGroup.LayoutParams. Могу ли я как-то использовать оба? – Gangnus

2

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

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

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

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

EDIT

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

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

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

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

+0

@ Gangnus, я не знаю, о чем вы говорите. Нет такой вещи, как LinearLayout.LayoutParams.rightMargin. Вы просто вызываете params.setMargins (int, int, int, int). – LuxuryMode

+0

Извините, я пропустил три буквы в имени функции – Gangnus

+0

+1 за помощь в поиске ошибок в стартовом варианте вопроса. Спасибо. Но, пожалуйста, если вы поможете с вопросом дальше, сделайте другой ответ - вопрос значительно изменился. – Gangnus

0

Вам не нужно получать объект 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); 
+0

Если вы хотите прочитать leftMargin, вам не нужно устанавливать новые параметры. Более того, даже если вам нужно * установить * leftMargin, вам не нужно действительно удалять все остальные параметры макета. – Gangnus

6

Просто поставить его в очень прямой путь:

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

Это предполагает один очень важный факт:

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


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

+0

Защищенное поле mLayoutParams, которое используется для получения результата этой функции, принадлежит самому представлению, а не его родительскому элементу. Возвращаемые значения, например, поля, относятся к этому самому представлению. Родитель может любым типом, результат функции всегда относится к классу ViewsGroup.LayoutParams, не зависящему от класса родителя. Функция существует и для корневого макета, и у нее нет родителей, экран является ее родительским. Почему вы думаете, что их класс определяется родителем? Я не вижу смысла в этой мысли - все против. – Gangnus

+0

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

+0

Теперь я вижу. И потому, что для разных родителей поля могут быть разными, я получаю ссылку на параметры самого примитивного родителя и позже передаю его классу, который, как я знаю, будет содержать все поля, в которых я нуждаюсь. Плохо сложен, но имеет смысл. --- lulumeia сказал это мне раньше, но ваше объяснение было понятным. Спасибо, и у вас есть джекпот :-) – Gangnus