Форум программистов, компьютерный форум, киберфорум
Наши страницы
Программирование Android
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.60/5: Рейтинг темы: голосов - 5, средняя оценка - 4.60
mrgaric
1 / 0 / 1
Регистрация: 22.09.2016
Сообщений: 13
1

Программно задавать layout_gravity для custom view

04.04.2017, 13:34. Просмотров 883. Ответов 8

Добрый день. Сделал кастомную вьюху следующим образом.

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
public class CustomView extends LinearLayout {
 
private LinearLayout containerBackground;
 
private int type;
 
public static final int TYPE_IN = 0x00000000;
public static final int TYPE_OUT = 0x00000001;
 
public CustomView (Context context) {
    super(context);
}
 
public CustomView (Context context, @Nullable AttributeSet attrs) {
    super(context, attrs);
    initAttrs(attrs);
}
 
public CustomView (Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    initAttrs(attrs);
}
 
private void initAttrs(AttributeSet attrs){
    LayoutInflater.from(getContext()).inflate(R.layout.widget, this);
 
    containerBackground = (LinearLayout) findViewById(R.id.container_background);
 
    final TypedArray typedArray = getContext().obtainStyledAttributes(attrs, R.styleable.CustomView);
    if (typedArray != null) {
 
        setType(typedArray.getInteger(R.styleable.CustomView_type, 0x00000000));
        typedArray.recycle();
    }
}
 
public void setType (int type){
    this.type = type;
    if (type == TYPE_IN){
        containerBackground.setBackgroundResource(R.drawable.in);
    } else if (type == TYPE_OUT){
        containerBackground.setBackgroundResource(R.drawable.out);
    } else throw new IllegalArgumentException("Unknown type" + type);
}
 
public int getType() {
    return type;
}
}
В зависимости от параметра type хочу задавать layout_gravity RIGHT или LEFT в методе setType. Пробовал сделать следующим образом, но ничего не сработало.

Java
1
2
3
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
    params.gravity = Gravity.RIGHT;
    setLayoutParams(params);
Как можно программно выставлять layout_gravity внутри кастомной вьюхи?
0
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
04.04.2017, 13:34
Ответы с готовыми решениями:

Программно установить android:layout_gravity="bottom"
android:layout_gravity="bottom" Не могу из кода вызвать этот метод,...

Gallery and custom view
Пытаюсь разобраться с функционалом Gallery. Несмотря на то, что документация...

Программно задать цвет фона для View
Возникла проблема с установкой фона для View. Получаю цвет через класс Color...

Custom view . is missing constructor used by tools
Здравствуйте! В общем, такая проблема: после того, как в конструкторе класса...

Многократное использование Custom View - как
Привет всем, я новичок в андроид с опытом Java и Flash, и после пары дней бития...

8
Pablito
2810 / 2235 / 753
Регистрация: 12.05.2014
Сообщений: 7,819
Завершенные тесты: 1
04.04.2017, 13:45 2
LayoutParams не получится задавать внутри вьюхи
эти параметры создаются и указываются при добавлении вьюхи куда-то в GroupView

если добавлять без LayoutParams то создадутся дефолтные
0
mrgaric
1 / 0 / 1
Регистрация: 22.09.2016
Сообщений: 13
04.04.2017, 14:29  [ТС] 3
А каким образом тогда можно указывать расположение вьюхи внутри ViewGroup, без использования LaoutParams ?
0
Pablito
2810 / 2235 / 753
Регистрация: 12.05.2014
Сообщений: 7,819
Завершенные тесты: 1
04.04.2017, 14:47 4
если эта вьюха (которая на самом деле Linearlayout) будет создаваться в xml то проще всего там и указывать гравити через атрибут
XML
1
android:gravity="end"
так например

если надо менять уже после создания то точно так же
Java
1
2
        LinearLayout.LayoutParams lp = (LayoutParams) customView.getLayoutParams();
        lp.gravity = Gravity.END;
Добавлено через 52 секунды
ну и если код перенести в сам класс CustomView то
получится
Java
1
2
        LinearLayout.LayoutParams lp = (LayoutParams) getLayoutParams();
        lp.gravity = Gravity.END;
0
mrgaric
1 / 0 / 1
Регистрация: 22.09.2016
Сообщений: 13
04.04.2017, 15:48  [ТС] 5
Третий способ как раз то что я хотел сделать, только он не работает почему то(

вот разметка самой кастомной вьюхи

XML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/container_background"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical">
 
    <TextView
        android:id="@+id/text_view_sender"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:paddingTop="@dimen/padding_vertical_item_message"
        android:paddingBottom="@dimen/padding_vertical_item_message"
        android:paddingLeft="@dimen/padding_horizontal_item_message"
        android:paddingRight="@dimen/padding_horizontal_item_message"
        android:textSize="@dimen/text_size_sender"
        android:textColor="@color/colorAccent"
        android:maxLines="1"
        android:ellipsize="end"
        tools:text="Test Test Test Test"/>
 
    <TextView
        android:id="@+id/text_view_message"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:paddingBottom="@dimen/padding_vertical_item_message"
        android:paddingLeft="@dimen/padding_horizontal_item_message"
        android:paddingRight="@dimen/padding_horizontal_item_message"
        android:textSize="@dimen/text_size_message"
        android:textAppearance="@style/Base.TextAppearance.AppCompat.Large"
        android:autoLink="web|phone|map|email"
        tools:text="Test Test Test "/>
 
</LinearLayout>
а вот здесь я пытаюсь ее применить

XML
1
2
3
4
5
6
7
8
9
10
11
12
13
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
 
    <com.widgets.ItemMessage
        android:id="@+id/item_message"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:maxWidth="@dimen/max_width_item_message"
        app:message_type="outgoing"/>
    
</FrameLayout>
если здесь у com.widgets.ItemMessage прописать атрибут android:layout_gravity="right" вьюха будет рисоваться с правой стороны. Но я хочу достичь этого же эффекта указывая нужный app:message_typе. Например, если app:message_typе="outgoing" то отрисовывать вьюху справа, а если app:message_typе="incoming" то слева.
0
Pablito
2810 / 2235 / 753
Регистрация: 12.05.2014
Сообщений: 7,819
Завершенные тесты: 1
04.04.2017, 16:03 6
ItemMessage это и есть тот класс CustomView ?
тогда в разметке и надо писать CustomView

и вместо
Java
1
LayoutInflater.from(getContext()).inflate(R.layout.widget, this);
все таки
Java
1
inflate(getContext, R.layout.widget, this);
Добавлено через 2 минуты
Цитата Сообщение от mrgaric Посмотреть сообщение
Например, если app:message_typе="outgoing" то отрисовывать вьюху справа, а если app:message_typе="incoming" то слева.
это масло-масляное
почеум там сразу не писать например
XML
1
                android:gravity="left"
0
mrgaric
1 / 0 / 1
Регистрация: 22.09.2016
Сообщений: 13
04.04.2017, 16:34  [ТС] 7
Да это он и есть. Просто изначально думал что обойдусь просто накидав только скелет класса относящегося к вопросу, но это мой косяк. Прошу прощения. Вот полный класс вьюхи.

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
public class ItemMessage extends LinearLayout {
 
    private TextView message;
    private TextView sender;
    private LinearLayout containerBackground;
 
    private int type;
 
    public static final int TYPE_IN = 0x00000000;
    public static final int TYPE_OUT = 0x00000001;
 
    public ItemMessage(Context context) {
        super(context);
    }
 
    public ItemMessage(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        initAttrs(attrs);
    }
 
    public ItemMessage(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initAttrs(attrs);
    }
 
    private void initAttrs(AttributeSet attrs){
        LayoutInflater.from(getContext()).inflate(R.layout.widget_item_message, this);
        message = (TextView) findViewById(R.id.text_view_message);
        sender = (TextView) findViewById(R.id.text_view_sender);
        containerBackground = (LinearLayout) findViewById(R.id.container_background);
 
        final TypedArray typedArray = getContext().obtainStyledAttributes(attrs, R.styleable.ItemMessage);
        if (typedArray != null) {
            if (typedArray.getString(R.styleable.ItemMessage_message_text) != null) {
                setTextMessage(typedArray.getString(R.styleable.ItemMessage_message_text));
            }
            if (typedArray.getString(R.styleable.ItemMessage_sender_name) != null) {
                setSender(typedArray.getString(R.styleable.ItemMessage_sender_name));
            }
            setType(typedArray.getInteger(R.styleable.ItemMessage_message_type, TYPE_IN));
            typedArray.recycle();
        }
    }
 
    public void setTextMessage(String textMessage){
        message.setText(textMessage);
    }
 
    public void setSender (String senderName){
        sender.setText(senderName);
    }
 
    public void setType (int type){
        this.type = type;
        if (type == TYPE_IN){
            sender.setVisibility(VISIBLE);
            containerBackground.setBackgroundResource(R.drawable.in_message);
        } else if (type == TYPE_OUT){
            sender.setVisibility(GONE);
            containerBackground.setBackgroundResource(R.drawable.out_message);
        } else throw new IllegalArgumentException("Unknown type" + type);
    }
 
    public int getType() {
        return type;
    }
}
Цитата Сообщение от Паблито Посмотреть сообщение
и вместо
LayoutInflater.from(getContext()).inflate(R.layout.widget, this);
все таки
inflate(getContext, R.layout.widget, this);
Почему так?

Цитата Сообщение от Паблито Посмотреть сообщение
это масло-масляное
почеум там сразу не писать например
android:gravity="left"
я потом использую созданную разметку как итем в адаптере RecyclerView и таким образом установив только setType можно полностью определить внешний вид вьюхи.
0
Pablito
2810 / 2235 / 753
Регистрация: 12.05.2014
Сообщений: 7,819
Завершенные тесты: 1
04.04.2017, 17:13 8
Лучший ответ Сообщение было отмечено mrgaric как решение

Решение

так я и пытаюсь объяснить - при создании вьюшки не получится задать гравити, то есть его задать можно, но layoutParams "слетят" после того как эту вьюшку заинфлейтит адаптер

поэтому в разметку вьюшки добавить сразу Framelayout и тогда можно будет назначать гравити на containerBackground

разметка ItemMessage
Кликните здесь для просмотра всего текста
XML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
 
    <LinearLayout
        android:id="@+id/container_background"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical">
 
        <TextView
            android:id="@+id/text_view_sender"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:ellipsize="end"
            android:maxLines="1"
            android:textColor="@color/colorAccent"
            tools:text="Test Test Test Test" />
 
        <TextView
            android:id="@+id/text_view_message"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:autoLink="web|phone|map|email"
            android:textAppearance="@style/Base.TextAppearance.AppCompat.Large"
            tools:text="Test Test Test " />
 
    </LinearLayout>
 
</FrameLayout>

покоцаный класс, что-бы у себя я мог запустить
Кликните здесь для просмотра всего текста
XML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
public class ItemMessage extends LinearLayout {
 
    private TextView message;
    private TextView sender;
    private LinearLayout containerBackground;
 
    private int type;
 
    public static final int TYPE_IN = 0x00000000;
    public static final int TYPE_OUT = 0x00000001;
 
    public ItemMessage(Context context) {
        super(context);
    }
 
    public ItemMessage(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        initAttrs(attrs);
    }
 
    public ItemMessage(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initAttrs(attrs);
    }
 
    private void initAttrs(AttributeSet attrs){
        LayoutInflater.from(getContext()).inflate(R.layout.widget_item_message, this);
        message = (TextView) findViewById(R.id.text_view_message);
        sender = (TextView) findViewById(R.id.text_view_sender);
        containerBackground = (LinearLayout) findViewById(R.id.container_background);
 
        final TypedArray typedArray = getContext().obtainStyledAttributes(attrs, R.styleable.ItemMessage);
        if (typedArray != null) {
            if (typedArray.getString(R.styleable.ItemMessage_message_text) != null) {
                setTextMessage(typedArray.getString(R.styleable.ItemMessage_message_text));
            }
            if (typedArray.getString(R.styleable.ItemMessage_sender_name) != null) {
                setSender(typedArray.getString(R.styleable.ItemMessage_sender_name));
            }
            setType(typedArray.getInteger(R.styleable.ItemMessage_message_type, TYPE_IN));
            typedArray.recycle();
        }
    }
 
    public void setTextMessage(String textMessage){
        message.setText(textMessage);
    }
 
    public void setSender (String senderName){
        sender.setText(senderName);
    }
 
    public void setType (int type){
        this.type = type;
        if (type == TYPE_IN){
            sender.setVisibility(VISIBLE);
//            containerBackground.setBackgroundResource(R.drawable.in_message);
            FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) containerBackground.getLayoutParams();
            lp.gravity = Gravity.END;
            containerBackground.setLayoutParams(lp);
        } else if (type == TYPE_OUT){
            sender.setVisibility(GONE);
//            containerBackground.setBackgroundResource(R.drawable.out_message);
        } else throw new IllegalArgumentException("Unknown type" + type);
    }
 
    public int getType() {
        return type;
    }
}


Добавлено через 13 минут
я большой любитель писать кастомные вьюшки, но в этом случае лично я бы не делал это все
много лишних телодвижений - атрибуты, методы в кастомной вьюхе

эти два текстовых поля и фон на вьюшку сеттятся в адаптере в три строки + условие-проверка на тип вьюшки
и от типа вьюшки назначаем гравити на containerBackground (три строки)

все, PROFIT
1
mrgaric
1 / 0 / 1
Регистрация: 22.09.2016
Сообщений: 13
04.04.2017, 17:19  [ТС] 9
Спасибо за ответы, первоначально так и было сделано как вы предлагаете, но потом я почему то решил создать кастомную вьюху для этого дела, заодно и потренироваться их создавать)
0
04.04.2017, 17:19
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
04.04.2017, 17:19

Warning: Custom view overrides onTouchEvent but not performClick
У меня есть кастомный view который перегружает onTouchEvent следующим образом....

Как создавать custom view компоненты с функционалом и присваивать им id?
Доброго времени суток) В моём приложении присутствует кнопка, для которой я...

Как программно менять View?
Вечер добрый. Есть слой, в нём список. Как сделать, чтобы при нажатии на...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Рейтинг@Mail.ru