How to set a view at specific position on screen? - java

How to can I set a view at a specific point on the screen programmatically? I want use a Point like x and y. I don't want it to translateX or translateY. I want for example to set a view to the Point x: 0 and y: 0 that means it needs to be at the top left of the screen. How can I achieve that?
I was trying this but the view translates X and Y what I don't want.
val layoutInflater = LayoutInflater.from(context)
val inflatedView: View = layoutInflater.inflate(R.layout.fragment_change_font_size_right, null, false)
inflatedView.popup_xml_view.x = 0f
inflatedView.popup_xml_view.y = 0f

Android had a layout that would support this requirements, but I think that it was pretty bad in regards to performance and it was deprecated (I hope that I am not wrong making this affirmation). However, the same behaviour can be implemented using a FrameLayout and add the views in that layout.
To add a view at a particular position, you create its layout params to set a width and a height, then set the margins which will position your view as absolute coordinates (the dimension is in pixels):
val imageView = ImageView(this)
imageView.setBackgroundResource(android.R.color.holo_red_dark)
imageView.layoutParams = FrameLayout.LayoutParams(width, height).apply {
setMargins(left, top, right, bottom)
}
root.addView(imageView)
For a height/width of 200 and margins of (100, 100, 0, 0), it will look something like the image below (run on an emulated Pixel 3).
NOTE: Here is a talk where they talk about this approach to emulate the AbsoulteLayout and why they "killed" it.

I found this to work:
ViewGroup.MarginLayoutParams margins = (ViewGroup.MarginLayoutParams) layout.getLayoutParams();
margins.topMargin = 100;
margins.leftMargin = 200;
Alternatively use animate:
view.animate().x(x).y(y).setDuration(0).start();

Related

place images inside a layout android

I want to place some images (triggered on click action) inside a layout. I have to place them such that they don't get out of the parent layout.
Code I'm using to add a new image on clicking the layout:
LinearLayout layout = (LinearLayout) findViewById(R.id.layout);
ImageView image = new ImageView(this);
LinearLayout.LayoutParams coordinates = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
image.setLayoutParams(coordinates);
image.setImageResource(R.drawable.image);
layout.addView(image);
If I press on the layout , I must see my imageView put randomly.
Random random = new Random();
int x = random.nextInt(layout.getWidth());
int y = random.nextInt(layout.getHeight());
image.setX(x);
image.setY(y);
But this won't do it. And I see those images outside my layout too.
You are setting x & y which are upper left-top corner - starting point of image to display it. As x/y value can be right/bottom corner, therefore, your image goes out of layout in that case.
Please note - x, y are starting point from where your image will be drawn.
You need to make sure that layoutWidth - x >= imageWidth and layoutHeight - y >= imageHeight.

Android how to resize (scale) an xml vector icon programmatically

This is driving me crazy. I would like to be able to resize an xml vector drawable icon programmatically in order to use it in an ImageView.
This is what I've done so far which is not working
Drawable drawable = ResourcesCompat.getDrawable(getResources(),R.drawable.ic_marker,null);
drawable.setBounds(0,0,512,512);
imageVenue.setImageDrawable(drawable);
The vector icon ic_marker is not resized. It just keeps the hardcoded width and height values every time.
Any ideas?
You can change the width and height of your imageview programmatically. Since vector drawables will preserve the original quality of the image, this will make the desired output happen.
ImageView iv = (ImageView) findViewById(R.id.imgview);
int width = 60;
int height = 60;
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(width,height);
iv.setLayoutParams(params);
I'm currently facing the same problem.
I'm trying something like this, cause ViewParent has actually height set explicitly, so I use match_parent and set margins. It doesn't work all the time though, cause I simply use this view in a viewholder for RecyclerView... Also I've noticed that sometimes I see scaled up version with artifacts, sometimes full size, sometimes there are margins, and bigger margins... But it still might work for you, if you use it in a simpler scenario.
mImageViewFront.setImageDrawable(vectorDrawable);
final int paddingLR = mImageViewFront.getWidth() / 4;
final int paddingTB = mImageViewFront.getHeight() / 4;
LayoutParams params = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
params.setMargins(paddingLR, paddingTB, paddingLR, paddingTB);
mImageViewFront.setLayoutParams(params);

Creating a View programmatically according to screen resolution

I created a BaseAdapter that implements ListAdapter. This BaseAdapter reads a JSON file and populate my ListView inflating a custom layout.
In this JSON file I have a boolean value (active = true or active = false). If active is true, I inflate the custom layout and everything is fine, but if active is false, I need to create a new View in this custom layout. Here's my code:
if (!active) {
JSONObject notifications = jsonData.getJSONObject("notifications");
String message = notifications.getString("message");
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
params.addRule(RelativeLayout.ALIGN_PARENT_TOP);
params.height = 70;
TextView warning = new TextView(Controller.getContext());
warning.setText(message);
warning.setTextColor(Color.WHITE);
warning.setBackgroundColor(Color.RED);
warning.setGravity(Gravity.CENTER);
warning.setPadding(10, 0, 10, 0);
warning.setLayoutParams(params);
// contentFrame is a RelativeLayout where the view is created;
viewHolder.contentFrame.getLayoutParams().height = 320;
viewHolder.contentFrame.addView(warning);
}
My problem here is this:
params.height = 70;
viewHolder.contentFrame.getLayoutParams().height = 320;
I'm saying that my TextView is 70 pixels higher and my RelativeLayout is now 320 pixeis high.
It looks nice on my phone, but if I test on a phone with other resolution it will not look the same right?
Is there any way to create a View and define is Height or Width according to the screen resolution? Maybe create the View 10% the size of the screen resolution? Is that a good pratice? What's the best aproach for something like this?
Instead of using hardcoded pixel values, use DPs. DPs account for the device density so views look pretty much the same regardless of which device the app runs on.
See this for additional info.
So, define this in your dimens.xml:
<resources>
<dimen name="my_width">320dp</dimen>
</resources>
Then read it like this:
int width = getResources().getDimensionPixelSize(R.dimen.my_width);
You have to scale your size values according to the screen density:
float density = getResources().getDisplayMetrics().density;
That means you have to multiply all size values with density:
params.height = (int)(70 * density);
viewHolder.contentFrame.getLayoutParams().height = (int)(320 * density);
and the same with padding values:
warning.setPadding((int)(10 * density), 0, (int)(10 * density), 0);
You can define dimensions in XML like any other resource, and have those resources automatically selected by Android based on the current device configuration.
So you have two definitions, one for "normal" circumstances, and another for "bigger screen":
src/main/res/values/dimens.xml
src/main/res/values-sw600dp/dimens.xml
Each resource file can have the same dimension defined in dp. Android will pick the appropriate one. If you need to read the values programmatically as raw pixel sizes, you can do that with Resources.getDimensionPixelSize().
I would recommend against trying to define list items in terms of percentage of the size of the screen.

Arc Shape Background Android

I wanna create a view with Arc Shape background.. my view has weight of .3.. which makes it fill one third of my layout..
I try to set its background to an arc shape (I want it to be half oval) like this:
ArcShape shape = new ArcShape(270, 180);
ShapeDrawable shapeDrawable = new ShapeDrawable(shape);
shapeDrawable.getPaint().setColor(getResources().getColor(R.color.primary_color));
leftPathView.setBackgroundDrawable(shapeDrawable);
this generates the shape I need but it doesn't fill the space of my view.. It only takes half of it.. But when I create a completed circle it takes all the space..
Any Idea ?
After a bit of research I found this to be the best answer. Especially if you want to do this in your onCreate function, bacause when the onCreate function hasn't ended the layout does not yet have a width and height (more info here).
final LinearLayout leftPathView= (LinearLayout) findViewById(R.id.left_path_view);
layout.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
leftPathView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
leftPathView.setX(-layout.getWidth());
leftPathView.getLayoutParams().width = layout.getWidth() * 2;
leftPathView.requestLayout();
}
});
ArcShape shape = new ArcShape(270, 180);
ShapeDrawable shapeDrawable = new ShapeDrawable(shape);
shapeDrawable.getPaint().setColor(getResources().getColor(R.color.primary_color));
layout.setBackground(shapeDrawable);
This code does make your View go out of the bounds of your screen, so when adding other items to this View you need to take that into account. A solution for that could be to put the View in a RelativeLayout and put another view on top of the leftPathView.

Moving Android ImageView by setting its coordinates

I am trying to do something fairly simple: move an image view by incrementing either the X or Y coordinates.
Initially I used the functions getX, getY, setX and setY on the image view, which worked in the emulator. However, when using it with the phone I had an error called NoSuchMethodError on these functions.
Here's the exact error I am getting (I get this for each of the functions I listed above):
java.lang.NoSuchMethodError: android.widget.ImageView.getX
According to my research this was caused by the fact that setX and setY are only implemented on the API11, in which case we are using API10. I have tried various other ways, such as using setMatrix, changePos() and a few other functions to change the ImageView's position.
My question is, what can I use to move the ImageViews like this, if I am using the API10?
You could try playing with layout parameters. Assuming you are using FrameLayout, or any other layout that supports margins
private ImageView myView;// populated in onCcreate
private void moveImage(int x, int y) {
ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams)myView.getLayoutParams();
lp.leftMargin = x;
lp.rightMargin = y;
requestLayout();
}
Here is a example for you:
LinearLayout.LayoutParams lp = (android.widget.LinearLayout.LayoutParams) logoImage
.getLayoutParams();
lp.setMargins(0, 28, 0, 0);
logoImage.setLayoutParams(lp);
if your layout is a relativelayout ,then change the type LinearLayout.LayoutParams .

Categories