setMargins() won't work - Android - java

I've been looking for solutions for this problem for more than one hour now, but none is working. :/
I want to set the top margin of my TextView to a value depending on the integer position.
But somehow the margins won't show up...
public void addElements(int position, String title,int colour, RelativeLayout ld){
int px = (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP,
1,
res.getDisplayMetrics()
);
int pos = 168*px;
LayoutParams params;
params = new LayoutParams(LayoutParams.MATCH_PARENT,144*px);
params.setMargins(0, 168, 0, 0);
TextView tv = new TextView(activity);
tv.requestLayout();
tv.setBackgroundResource(colour);
tv.setText(title);
tv.setSingleLine(false);
ld.addView(tv, params);
}

Try this:
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, 144);
params.setMargins(0, 168, 0, 0);

LayoutMargins are reserved for ViewGroup's such as RelativeLayout, LinearLayout, etc. Most common Views such as a TextView use padding in order to add additional spacing.
This should work:
tv.setPaddingRelative(0,168,0,0);

Related

How can I set a textview's style programmatically?

How can I add a style to a textview in java? I am trying to add one under my values/styles.xml, not to add each attribute individually.
LinearLayout messagesLayout = (LinearLayout) findViewById(R.id.messages_layout);
TextView sentOne = new TextView(this);
sentOne.setText(sentMessage);
messagesLayout.addView(sentOne);
You may find this answer by Benjamin Piette handy. To change this into working code for a TextView just change it up a bit:
TextView tv = new TextView (new ContextThemeWrapper(this, R.style.mystyle), null, 0);
EDIT: to set other things like margins, height & width and others, use LayoutParams. To set the params throrin19's answer can be helpful.
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT
);
params.setMargins(left, top, right, bottom);
tv.setLayoutParams(params);
There is an answer for this already: https://stackoverflow.com/a/7919203/5544859
textview.setTypeface(Typeface.DEFAULT_BOLD);
to preserve the previously set typeface attributes you can use:
textview.setTypeface(textview.getTypeface(), Typeface.DEFAULT_BOLD);
Credit to: #Raz

Android: calling setPadding() on a view doesn't work when I also set the layoutParams on the view

If I call setPadding() on a view, I can successfully set the padding, however, if I first set the layoutParams and then the padding, or set the padding and then set the layoutParams, the padding is not applied.
Demonstration:
//This doesn't work
textView.setLayoutParams(linearLayoutParams);
textView.setPadding(0, 100, 0 , 0);
//This doesn't work either
testView.setPadding(0, 100, 0 , 0);
textView.setLayoutParams(linearLayoutParams);
//This does work
textView.setPadding(0, 100, 0 , 0);
Does anyone know how to use setLayoutParams() and setPadding() at the same time, or why setLayoutParams() is stopping setPadding() from working?
Edit:
More detail:
I call this method in onCreate()
public void initTextView(){
Textview textView = (TextView) findViewById(R.id.textView);
LinearLayout.LayoutParams linearLayoutParams = new LinearLayout.LayoutParams(myWidth, myHeight);
textView.setLayoutParams(linearLayoutParams);
//This doesn't work
textView.setPadding(0, 100 ,0 , 0);
}
but if I comment out this line from above:
// textView.setLayoutParams(linearLayoutParams);
Then the setPadding() method does work.
Thanks in advance.
I don't believe there's anything wrong with the code, rather just not understanding what it's doing.... if your myHeight value is smaller than the padding, you're just simply not going to notice the effect.
In the attached series of screenshots, the first screenshot is the default TextView containing a price (it has no layout params other than what's set in xml).
In the 2nd screenshot I set the textview to the following (height=30, top padding = 100:
LinearLayout.LayoutParams linearLayoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, 30);
textview.setLayoutParams(linearLayoutParams);
textview.setPadding(0, 100, 0, 0);
The text is there, the top padding is there, but it's all forced to "crop" to the set height of 30 (note I also lost all my original xml parameters (gravity, margins, etc) because setting LayoutParams cancels all of that and only applies whatever I set in those LayoutParams).
In the 3rd screenshot I set the textview to the following (height=150, top padding = 100:
LinearLayout.LayoutParams linearLayoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, 150);
textview.setLayoutParams(linearLayoutParams);
textview.setPadding(0, 100, 0, 0);
Voila! Since I've given the view ample height, it can fully display the text and the top padding (though again, I lost all my xml parameters).. If you go back to your source, try it out: replace myHeight with some fixed value (try at least 150) and see if things display as they should.
object ScreenUtils {fun dpToPixel(dp: Int): Int {
return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp.toFloat(), Resources.getSystem().displayMetrics).toInt()}}
in Kotlin
setPadding(ScreenUtils.dpToPixel(8), 0, ScreenUtils.dpToPixel(8), 0)

Android sliding tabs - set width of tabs programmatically

With my sliding tabs project, how can I programmatically set the width of the tabs so that they use the whole space of the sliding tab strip and are each equal in width size? I've tried using the code below but the tabs won't stretch as desired.
SlidingTabLayout.java
protected TextView createDefaultTabView(Context context) {
TextView textView = new TextView(context);
textView.setGravity(Gravity.CENTER);
textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, TAB_VIEW_TEXT_SIZE_SP);
textView.setTypeface(Typeface.DEFAULT_BOLD);
textView.setTextColor(context.getResources().getColor(R.color.black));
textView.setWidth(0);
int padding = (int) (TAB_VIEW_PADDING_DIPS * getResources().getDisplayMetrics().density);
textView.setPadding(padding, padding, padding, padding);
return textView;
}
Text weight error
Add this in your method
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
Point size = new Point();
display.getSize(size);
textView.setWidth(size.x / count); // Where count is number of textviews
Also if you are supporting older version
Use this
if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB_MR2)
{
display.getSize(size);
}
else
{
size.set(display.getWidth(), display.getHeight());
}
In a update these you can now use,
mSlidingTabLayout.setDistributeEvenly(true);
within the onViewCeated,
More can be found here.
I have a different problem, wherein I had to customize each of the tabs' width:
I was using setDistributeEvenly function. Instead I needed to set each of the textviews' weight.
Add this variable on your SlidingTabLayout.java:
private int[] mTabWeights;
This method should set the tab weights:
public void setTabWeights(int[] weights){
mTabWeights = weights;
}
Look for the method populateTabStrip() and add an else statement:
if (mDistributeEvenly) {
LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) tabView.getLayoutParams();
lp.width = 0;
lp.weight = 1;
}else{
LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) tabView.getLayoutParams();
lp.width = 0;
lp.weight = mTabWeights[i];
}
You can refactor the code to make it cleaner. Here it is when used:
stNews = (SlidingTabLayout) findViewById(R.id.stNews);
stNews.setDistributeEvenly(false);
stNews.setTabWeights(new int[]{2,3,3});
Here's the end result:
Hope it helps!

ImageView disappears after LayoutParams Change

I added a ImageView to my LinearLayout in the onCreate method programmatically and it worked as it should.
img = new ImageView(this);
img.setImageResource(R.drawable.source);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
params.setMargins(0, 50, 0, 0);
img.setLayoutParams(params);
layout = (LinearLayout) findViewById(R.id.index_view);
layout.addView(img);
And the I want to change it's x and y coordinates when the user touches the screen.
onTouch method - case ACTION_MOVE:
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
params.setMargins(newX, newY, 0, 0);
img.setLayoutParams(params);
the newX and newY are calculated based on the users touch-coordinates
But this code doesn't seem to work correctly.
I created toasts to show me the Image width after every touch and it showed me that the width is set to zero after first touch. This tells me: ImageView disappeared.
Any guesses?
I am assuming that you made sure that you are getting newX, newY values in onTouch().
I feel that your aim is to edit the Layout parameters but instead of doing that what you are doing is, you are assigning a new set of parameters with width and height as LayoutParams.WRAP_CONTENT and then setting the margins.
You might try to first get the existing parameters as follows:
LinearLayout.LayoutParams params =
( LinearLayout.LayoutParams) img.getLayoutParams();
Then change the margin:
params.setMargins(newX, newY, 0, 0);
img.setLayoutParams(params);
Try it and notify if it helps. If not then we can talk further.

Android center view with SetMargins programmatically? [duplicate]

I want to add an unknown number of ImageView views to my layout with margin. In XML, I can use layout_margin like this:
<ImageView android:layout_margin="5dip" android:src="#drawable/image" />
There is ImageView.setPadding(), but no ImageView.setMargin(). I think it's along the lines of ImageView.setLayoutParams(LayoutParams), but not sure what to feed into that.
Does anyone know?
android.view.ViewGroup.MarginLayoutParams has a method setMargins(left, top, right, bottom). Direct subclasses are: FrameLayout.LayoutParams, LinearLayout.LayoutParams and RelativeLayout.LayoutParams.
Using e.g. LinearLayout:
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
lp.setMargins(left, top, right, bottom);
imageView.setLayoutParams(lp);
MarginLayoutParams
This sets the margins in pixels. To scale it use
context.getResources().getDisplayMetrics().density
DisplayMetrics
image = (ImageView) findViewById(R.id.imageID);
MarginLayoutParams marginParams = new MarginLayoutParams(image.getLayoutParams());
marginParams.setMargins(left_margin, top_margin, right_margin, bottom_margin);
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(marginParams);
image.setLayoutParams(layoutParams);
All the above examples will actually REPLACE any params already present for the View, which may not be desired. The below code will just extend the existing params, without replacing them:
ImageView myImage = (ImageView) findViewById(R.id.image_view);
MarginLayoutParams marginParams = (MarginLayoutParams) image.getLayoutParams();
marginParams.setMargins(left, top, right, bottom);
Kevin's code creates redundant MarginLayoutParams object. Simpler version:
ImageView image = (ImageView) findViewById(R.id.main_image);
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(image.getLayoutParams());
lp.setMargins(50, 100, 0, 0);
image.setLayoutParams(lp);
If you want to change imageview margin but leave all other margins intact.
Get MarginLayoutParameters of your image view in this case: myImageView
MarginLayoutParams marginParams = (MarginLayoutParams) myImageView.getLayoutParams();
Now just change the margin you want to change but leave the others as they are:
marginParams.setMargins(marginParams.leftMargin,
marginParams.topMargin,
150, //notice only changing right margin
marginParams.bottomMargin);
I use simply this and works great:
ImageView imageView = (ImageView) findViewById(R.id.image_id);
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) imageView.getLayoutParams();
layoutParams.setMargins(left, top, right, bottom);
imageView.setLayoutParams(layoutParams);
setMargins()'s unit is pixel not dp. If you want to set margin in dp, just inside your values/dimens.xml file create your dimensions like:
<resources>
<dimen name="right">16dp</dimen>
<dimen name="left">16dp</dimen>
</resources>
and access like:
getResources().getDimension(R.dimen.right);
If you use kotlin, this can be simplified by creating an extension function
fun View.setMarginExtensionFunction(left: Int, top: Int, right: Int, bottom: Int) {
val params = layoutParams as ViewGroup.MarginLayoutParams
params.setMargins(left, top, right, bottom)
layoutParams = params
}
Now all you need is a view, and this extension function can be used anywhere.
val imageView = findViewById(R.id.imageView)
imageView.setMarginExtensionFunction(0, 0, 0, 0)
You can use this method, in case you want to specify margins in dp:
private void addMarginsInDp(View view, int leftInDp, int topInDp, int rightInDp, int bottomInDp) {
DisplayMetrics dm = view.getResources().getDisplayMetrics();
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
lp.setMargins(convertDpToPx(leftInDp, dm), convertDpToPx(topInDp, dm), convertDpToPx(rightInDp, dm), convertDpToPx(bottomInDp, dm));
view.setLayoutParams(lp);
}
private int convertDpToPx(int dp, DisplayMetrics displayMetrics) {
float pixels = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, displayMetrics);
return Math.round(pixels);
}
Answer from 2020 year :
dependencies {
implementation "androidx.core:core-ktx:1.2.0"
}
and cal it simply in your code
view.updateLayoutParams<ViewGroup.MarginLayoutParams> {
setMargins(5)
}
create layout dynamically and set its parameter as setmargin() will not work directly on an imageView
ImageView im;
im = (ImageView) findViewById(R.id.your_image_in_XML_by_id);
RelativeLayout.LayoutParams layout = new RelativeLayout.LayoutParams(im.getLayoutParams());
layout.setMargins(counter*27, 0, 0, 0);//left,right,top,bottom
im.setLayoutParams(layout);
im.setImageResource(R.drawable.yourimage)
For me this worked:
int imgCarMarginRightPx = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, definedValueInDp, res.getDisplayMetrics());
MarginLayoutParams lp = (MarginLayoutParams) imgCar.getLayoutParams();
lp.setMargins(0,0,imgCarMarginRightPx,0);
imgCar.setLayoutParams(lp);
sample code is here ,its very easy
LayoutParams params1 = (LayoutParams)twoLetter.getLayoutParams();//twoletter-imageview
params1.height = 70;
params1.setMargins(0, 210, 0, 0);//top margin -210 here
twoLetter.setLayoutParams(params1);//setting layout params
twoLetter.setImageResource(R.drawable.oo);
In Kotlin you can write it in more pleasant way
myView.layoutParams = LinearLayout.LayoutParams(
RadioGroup.LayoutParams.MATCH_PARENT, RadioGroup.LayoutParams.WRAP_CONTENT
).apply {
setMargins(12, 12, 12, 12)
}
Using a method similar to this might save you some headaches in some situations.
If you have two passes of programmatical tinkering with margins it is safer to check if there are already some layoutParams set. If there are some margins already one should increase them and not replace them:
public void addMargins(View v, int left, int top, int right, int bottom) {
LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) v.getLayoutParams();
if (params == null)
params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
int oldLeft = params.leftMargin;
int oldTop = params.topMargin;
int oldRight = params.rightMargin;
int oldBottom = params.bottomMargin;
params.setMargins(oldLeft + left, oldTop + top, oldRight + right, oldBottom + bottom);
v.setLayoutParams(params);
}
Here is an example to add 8px Margin on left, top, right, bottom.
ImageView imageView = new ImageView(getApplicationContext());
ViewGroup.MarginLayoutParams marginLayoutParams = new ViewGroup.MarginLayoutParams(
ViewGroup.MarginLayoutParams.MATCH_PARENT,
ViewGroup.MarginLayoutParams.WRAP_CONTENT
);
marginLayoutParams.setMargins(8, 8, 8, 8);
imageView.setLayoutParams(marginLayoutParams);
We can create Linear LayoutParams & use resources.getDimensionPixelSize for dp value.
val mContext = parent.context
val mImageView = AppCompatImageView(mContext)
mImageView.setBackgroundResource(R.drawable.payment_method_selector)
val height = mContext.resources.getDimensionPixelSize(R.dimen.payment_logo_height)
val width = mContext.resources.getDimensionPixelSize(R.dimen.payment_logo_width)
val padding = mContext.resources.getDimensionPixelSize(R.dimen.spacing_small_tiny)
val margin = mContext.resources.getDimensionPixelSize(R.dimen.spacing_small)
mImageView.layoutParams = LinearLayout.LayoutParams(width, height).apply {
setMargins(margin, margin, 0, 0)
}
mImageView.setPadding(padding, padding, padding, padding)

Categories