ImageView disappears after LayoutParams Change - java

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.

Related

Create custom compass on map or move native button

I have tried to change position of compass button from top-left to bottom-left, but can't.
As I seen there are many suggestions to create a custom one and disable native button, but no one complete and normal example.
How to add custom compass button on android map?
You can change the position of built in Compass. Try this code:
ViewGroup parent = (ViewGroup) mapView.findViewById(Integer.parseInt("1")).getParent();
View compassButton = parent.getChildAt(4);
/* now set position compass */
RelativeLayout.LayoutParams rlp = (RelativeLayout.LayoutParams) compassButton.getLayoutParams();
rlp.addRule(RelativeLayout.ALIGN_PARENT_END, 0);
rlp.addRule(RelativeLayout.ALIGN_PARENT_TOP);
rlp.addRule(RelativeLayout.ALIGN_PARENT_START);
rlp.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, 0);
Resources r = context.getResources();
float px = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 50, r.getDisplayMetrics());
rlp.setMargins(0, (int)px,0, 0); // 160 la truc y , 30 la truc x
px = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 30, r.getDisplayMetrics());
rlp.setMarginEnd((int)px);
compassButton.setLayoutParams(rlp);
Just play with RelativeLayout params and set it on desired location

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)

Get width of ImageView returning 0

I realize there is a question similar to this on stack overflow (getWidth() and getHeight() of View returns 0) that has gotten much attention. It seems like I may be calling getWidth too early, but how can I be sure that it does have an actual width though? I'm worried because I believe I may be getting a size of zero because of how I'm implementing an imageBitmap and not an imageResource.
My onCreate:
// Byte array to bitmap
BitmapFactory.Options options = new BitmapFactory.Options();
options.inMutable = true;
mainImageBitmap = BitmapFactory.decodeByteArray(byteArray, 0,
byteArray.length, options);
// Set bitmap
mainImageView.setImageBitmap(mainImageBitmap);
Log.e("", mainImageView.getWidth() + " ");
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(400, 400); //Want to use getWidth and getHeight here, just hardcoding to 400 for now
layout.setLayoutParams(params);
use GlobalLayout
example :
Global Layout Example
attach the Global layout to the view u want
when the view will be ready it will callback to this function with width and height
in your case try using the next Code
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);

setMargins() won't work - Android

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);

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