16

In my application, I want to set top and bottom margin of 8 dip to a textview. So if I do it like -

<TextView
android:id="@+id/tv_text1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/settings_plain_text"/>

it works fine where the style contents are -

<style name="settings_plain_text">
    <item name="android:layout_marginTop"> 8dip </item>
    <item name="android:layout_marginBottom"> 8dip </item>
    <item name="android:textSize"> 18sp </item>
</style>

But when I apply the same style to that textview programmatically like -

textview.setTextAppearance(context, R.style.settings_plain_text);

it does not show the top and bottom margin that I've set in style. Please help.

Rob
  • 2,243
  • 4
  • 29
  • 40
Rajkiran
  • 15,845
  • 24
  • 74
  • 114
  • 1
    possible duplicate of [android set style in code](http://stackoverflow.com/questions/3142067/android-set-style-in-code); `setTextAppearance()` only changes the text appearance as the name suggests, which doesn't include margins. Setting the style of the View is more complicated and linked in the question I mentioned here as a duplicate (because it's basically the same underlying question). –  Feb 28 '12 at 11:48
  • possible duplicate of [Inflate style on android View on Runtime](http://stackoverflow.com/questions/29437095/inflate-style-on-android-view-on-runtime#comment47067374_29437095) – corsair992 Apr 04 '15 at 19:56
  • @corsair992 You should actually comment on that question as a possible duplicate since this question was asked 3 years before that question. :) – Rajkiran Apr 04 '15 at 20:45
  • Style is applied during inflation of a view (very simplified) so what you're asking in full extent is not possible. – Eugen Pechanec Apr 04 '15 at 23:49
  • 1
    @Rajkiran: The other question is more generic, and has some potential suggestions provided. See the meta answer on [Opinions on closing an older question as a duplicate of a newer question](http://meta.stackexchange.com/questions/55251/opinions-on-closing-an-older-question-as-a-duplicate-of-a-newer-question/55253#55253) – corsair992 Apr 05 '15 at 01:24

4 Answers4

1

setTextAppearence(..) only setups xml attributes with the prefix android:text_* but you can still write you own method that reads other attributes and sets them programmatically knowing the underlying LayoutParams implementation.

Please mind that you can use a ContextThemeWrapper for obtaining specific theme values or pass a syle resource id in .obtainStyledAttributes(..)

As an example:

int[] attrs= new int[] {
  android.R.attr.layout_marginTop,     // 0
  android.R.attr.layout_marginLeft,    // 1
  android.R.attr.layout_marginRight,   // 2 (used in example)
  android.R.attr.layout_marginBottom}; // 3
final TypedArray arr = context.obtainStyledAttributes(attrs);
try {
  // ...
  layoutParams.rightMargin = arr.getDimensionPixelSize(2);
  // ...
} finally {
  arr.recycle();
}
Gianluca P.
  • 1,536
  • 15
  • 15
1

More simplified version of answered by Gianluca P.

public void applyTextStyle(TextView v, int styleResId)
{
    int[] attrs= new int[] {
            android.R.attr.layout_marginTop,     // 0
            android.R.attr.layout_marginLeft,    // 1
            android.R.attr.layout_marginBottom,   // 2 
            android.R.attr.layout_marginRight}; // 3 (used in example)
    final TypedArray arr =  this.obtainStyledAttributes(styleResId,attrs);
    try {
        ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams) v.getLayoutParams();
        lp.topMargin = arr.getDimensionPixelSize(0,lp.topMargin);
        lp.leftMargin = arr.getDimensionPixelSize(1,lp.leftMargin);
        lp.bottomMargin = arr.getDimensionPixelSize(2,lp.bottomMargin);
        lp.rightMargin = arr.getDimensionPixelSize(3,lp.rightMargin);

        v.requestLayout();
    } finally {
        arr.recycle();
    }
}
0
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(textView.getLayoutParams());
    lp.setMargins(10, 20, 10, 20);
    textView.setLayoutParams(lp);

// in xml my parent layout for textView is RelativeLayout.

<RelativeLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:background="@color/colorPrimary">
   <TextView
    android:id="@+id/test"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@color/bg_gradient_end"
    android:text="zdfhzfdh"/>
</RelativeLayout
Akkss
  • 3
  • 1
  • 6
-1

You can achieve it by using this code.

TextView tv = (TextView)findViewById(R.id.tv_text1);
LinearLayout.LayoutParams params = (LinearLayout.LayoutParams)tv.getLayoutParams();
params.setMargins(0, 8, 0, 8); //substitute parameters for left, top, right, bottom
tv.setLayoutParams(params);

Hope it helps!

EDIT:

public final class Values {
    public static final int MARGIN_TOP = 8;
    public static final int MARGIN_BOTTOM = 8;
}

TextView tv = (TextView)findViewById(R.id.tv_text1);
LinearLayout.LayoutParams params = (LinearLayout.LayoutParams)tv.getLayoutParams();
params.setMargins(0, Values.MARGIN_TOP, 0, Values.MARGIN_BOTTOM); //substitute parameters for left, top, right, bottom
tv.setLayoutParams(params);
Nacho
  • 2,057
  • 2
  • 23
  • 32
  • Please read the question completely. The question clearly suggests that it needs margin in styles.. so that I don't have to define it for every textView all the time. P.S. What happens to your answer if the margin is supposed to be changed to 10px instead of 8? Shoudl I find all the lines and make that change everywhere? :) – Rajkiran Apr 04 '15 at 20:48
  • @Rajkiran you can get it by making a static class with the values. If you want to change the value, just change it in Values class – Nacho Apr 04 '15 at 20:53
  • Expected this answer. What about rest of the styles? You can not (even if you do, you should not) do all the UI stuff in java files instead of XMLs. Styles would suit the best. Thanks for the answer though. – Rajkiran Apr 04 '15 at 22:05
  • 1
    @Rajkiran: You asked just for this...i answer how you could solve it. This is a valid answer. Your choice to use it or not. Good luck! – Nacho Apr 04 '15 at 23:36