How to set margin of ImageView using code, not xml - android

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)

Related

Different tab width for TabLayout

I'm using TabLayout & ViewPager.
I am trying to change the size of the Tab, like Whatsapp (camera icon).
The size of the three Tabs is equal, but the Tab of the camera is smaller.
In every attempt I make the size of the Tabs remains the same (equal across all tabs).
Thanks.
You need to lower the weight of the LinearLayout of the corresponding tab.
LinearLayout layout = ((LinearLayout) ((LinearLayout) tabLayout.getChildAt(0)).getChildAt(YOUR_TAB_NUMBER));
LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) layout.getLayoutParams();
layoutParams.weight = YOUR_WEIGHT; // e.g. 0.5f
layout.setLayoutParams(layoutParams);
Hope that helps!
#digger's answer is working. However, if you want the tab which has an icon only wraps its content, you can set weight to 0 and width to LinearLayout.LayoutParams.WRAP_CONTENT. It worked for me.
fun TabLayout.setTabWidthAsWrapContent(tabPosition: Int) {
val layout = (this.getChildAt(0) as LinearLayout).getChildAt(tabPosition) as LinearLayout
val layoutParams = layout.layoutParams as LinearLayout.LayoutParams
layoutParams.weight = 0f
layoutParams.width = LinearLayout.LayoutParams.WRAP_CONTENT
layout.layoutParams = layoutParams
}
Here I have taken 5 tabs and made 1st tab width is 12% of screen width and rest 4 are sharing remaining width. Doing it after some delay of 400 msec after inflating the views.
DisplayMetrics displaymetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
int width= displaymetrics.widthPixels;
int widthOtherThanFirst= (int) ((float)width*(8.80f/10f));
int allOther=widthOtherThanFirst/4;
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
LinearLayout layout1 = ((LinearLayout) ((LinearLayout)tabLayout.getChildAt(0)).getChildAt(0));
LinearLayout.LayoutParams layoutParams1 = (LinearLayout.LayoutParams) layout1.getLayoutParams();
layoutParams1.width = width-widthOtherThanFirst;
layout1.setPadding(0,0,0,0);
layout1.setLayoutParams(layoutParams1);
LinearLayout layout2 = ((LinearLayout) ((LinearLayout)tabLayout.getChildAt(0)).getChildAt(1));
LinearLayout.LayoutParams layoutParams2 = (LinearLayout.LayoutParams) layout2.getLayoutParams();
layoutParams2.width = allOther;
layout2.setLayoutParams(layoutParams2);
LinearLayout layout5 = ((LinearLayout) ((LinearLayout)tabLayout.getChildAt(0)).getChildAt(2));
LinearLayout.LayoutParams layoutParams5 = (LinearLayout.LayoutParams) layout5.getLayoutParams();
layoutParams5.width = allOther;
layout5.setLayoutParams(layoutParams5);
LinearLayout layout3 = ((LinearLayout) ((LinearLayout)tabLayout.getChildAt(0)).getChildAt(3));
LinearLayout.LayoutParams layoutParams3 = (LinearLayout.LayoutParams) layout3.getLayoutParams();
layoutParams3.width = allOther;
layout3.setLayoutParams(layoutParams3);
LinearLayout layout4 = ((LinearLayout) ((LinearLayout)tabLayout.getChildAt(0)).getChildAt(4));
LinearLayout.LayoutParams layoutParams4 = (LinearLayout.LayoutParams) layout4.getLayoutParams();
layoutParams4.width = allOther;
layout4.setLayoutParams(layoutParams4);
tabLayout.invalidate();
}
},400);
Check this for dynamic width with wrap_content background
private fun setTabwidth(tabposition: Int, weight: Float) {
val layout: LinearLayout = tabLayout?.getChildAt(0) as LinearLayout).getChildAt(tabpos) as LinearLayout
val layoutParams: LinearLayout.LayoutParams = layout.getLayoutParams() as LinearLayout.LayoutParams
layoutParams.weight = weight
layoutParams.width = LinearLayout.LayoutParams.WRAP_CONTENT
layout.setLayoutParams(layoutParams)
val tablayoutParams: ViewGroup.LayoutParams? = tabLayout?.layoutParams
tablayoutParams?.width=ViewGroup.LayoutParams.WRAP_CONTENT
tabLayout?.layoutParams=tablayoutParams
}
Usage:
setTabwidth(0,0.4f) // first tab 0.4 weight
setTabwidth(1,0.6f) // second tab 0.6 weight

Changing WRAP_CONTENT to a set number using LinearLayout.LayoutParams

I have set up some LinearLayout.LayoutParams to set up some buttons just using java. But I want to change it from WRAP_CONTENT to a height and width of my choice.
//LinearLayout.LayoutParams top;
//this is declared at the top as it is used by different bits of the code.
top = new LinearLayout.LayoutParams
(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
top.topMargin = 100;
top.leftMargin = 120;
top = new LinearLayout.LayoutParams
(90, 80);
// whatever u like
this is from documentation:
public LayoutParams(int width, int height) {
super(width, height);
weight = 0;
}
According to ViewGroup.MarginLayoutParams.html#setMargins you have to use this:
LinearLayout layout = (LinearLayout)findViewById(R.id.yourLinear_Layout);
LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
params.setMargins(120, 100, 0, 0); //Here your custom margin (int left, int top, int right, int bottom)
layout.setLayoutParams(params);
Have you tried?
top.getLayoutParams().height = 256;
top.getLayoutParams().width= 256;
top.requestLayout();
try like this..
LinearLayout layout = (LinearLayout)findViewById(R.id.numberPadLayout);
// Gets the layout params that will allow you to resize the layout
LayoutParams params = layout.getLayoutParams();
// Changes the height and width to the specified *pixels*
params.height = 100;
params.width = 100;
layout.setLayoutParams(params);

Android: how to use code to change layout_marginTop of textview?

After setContentView(R.layout.activity_main), I want to use code to change only layout_marginTop of textview(android:layout_centerHorizontal="true").
tvcity = (TextView) findViewById(R.id.city);
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT,RelativeLayout.LayoutParams.WRAP_CONTENT);
lp.setMargins(0, 20, 0, 0);
tvcity.setLayoutParams(lp);
Centered changed to left-aligned.
setMargins(int left, int top, int right, int bottom) contains 4 parameters, but I only want to change the second parameter!
Try replacing
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT,RelativeLayout.LayoutParams.WRAP_CONTENT);
with this:
RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams)tvcity.getLayoutParams();
Try using the existing margins:
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT,RelativeLayout.LayoutParams.WRAP_CONTENT);
lp.setMargins(lp.leftMargin, 20, lp.rightMargin, lp.bottomMargin);
tvcity.setLayoutParams(lp);

RelativeLayout.LayoutParams.WRAP_CONTENT make ImageView smaller in loop

I add ImageView to layout in runtime, But ImageView is smaller after every loop. This is my code:
layout = (RelativeLayout)findViewById(R.id.layout_main);
width = getWindowManager().getDefaultDisplay().getWidth();
height = getWindowManager().getDefaultDisplay().getHeight(
for(int i=0; i< fruit.size();i++) {
int id = getApplicationContext().getResources().getIdentifier(fruit.get(i).file, "drawable",
getApplicationContext().getPackageName());
int h = random.nextInt(height);
int w = random.nextInt(width);
Logger.debug(TAG, "drawable/"+fruit.get(i).file+":"+id+":X="+w+":Y="+h);
ImageView imageView =new ImageView(getApplicationContext());
imageView.setImageResource(id);
imageView.setScaleX(0.3f);
imageView.setScaleY(0.3f);
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
layoutParams.setMargins(w,h,0,0);
imageView.setLayoutParams(layoutParams);
layout.addView(imageView);
And this is my result:
Please help me why and how to fix it?
Thank you very much
More information:
If I replace code
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
layoutParams.setMargins(w,h,0,0);
imageView.setLayoutParams(layoutParams);
By
imageView.setY(h);
imageView.setX(w);
Result will
may be this create problem
layoutParams.setMargins(w,h,0,0);
setmargin put margin as
setMargins(int left, int top, int right, int bottom)
I believe it's because of the Random class. You are already bounding the random number. You can shift the generated number, if you don't want it to approach to zero.
int h = random.nextInt(height) + height;
Or you can change the seed if you are providing any. Please see the link below.
How the random numbers are calculated.

How to place ImageButton at x, y location?

I want to place ImageButton at x, y location of my view.
The problem is that Android adds padding around image.
Because I don't know exact size of padding, I cannot place image button at exact location.
So, I want to remove padding.
How can I remove padding around image programmatically?
button.setPadding(0, 0, 0, 0) makes button width shorter and height longer than bitmap.
button.getLayoutParams().width gives minus value.
What I tried so far is like this.
protected class MyLayout extends RelativeLayout {
Bitmap img;
ImageButton button;
public MyLayout(Context context) {
button = new ImageButton(context);
img = BitmapFactory.decodeResource(getResources(), R.drawable.img);
button.setImageBitmap(img);
params = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
button.setLayoutParams(params);
params.setMargins(x, y, 0, 0);
button.setBackgroundDrawable(null);
addView(button, params);
}
}
EDIT
Use this...
MarginLayoutParams marginParams = new MarginLayoutParams(image.getLayoutParams());
int left = someValue;
int top = someValue;
marginParams.setMargins(left, top, 0, 0);
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(marginParams);
image.setLayoutParams(layoutParams);

Categories

Resources