Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get the width of the parent layout

Android Studio 2.0 beta 6

I am trying to use ViewPropertyAnimator to move a ImageView (ivSettings) inside a toolbar so that it is 20dp from the right and 20dp from the top, from is current location. And move the ImageView (ivSearch) 20dp from the left and top.

The imageViews are contained in a Toolbar.

This is the initial state and I want to move the icons into the upper corners inside the toolbar.

enter image description here

The code I am using is this to get the width and then subtract a value to get the ivSettings to be 20dp from the right.

final DisplayMetrics displayMetrics = new DisplayMetrics();
getActivity().getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
final float widthPx = displayMetrics.widthPixels;

ivSearch.animate()
    .setInterpolator(new AccelerateInterpolator())
    .x(20)
    .y(20)
    .setDuration(250)
    .start();

ivSettings.animate()
    .setInterpolator(new AccelerateInterpolator())
    .x(widthPx - 160)
    .y(20)
    .setDuration(250)
    .start();

However, having tried this on different screen size I can't get the exact width calculation. Is there a better way of doing this?

Many thanks for any suggestions

like image 445
ant2009 Avatar asked Mar 08 '16 16:03

ant2009


People also ask

How do you find the width of a layout?

If you wanted to get the actual width of your view you would have to call getWidth() on your view once the layout has been inflated and displayed. Calling getWidth() before your layout has been displayed will result in 0.

How do you find the parent width in react native?

To get the parent height and width in React: Set the ref prop on the element. In the useEffect hook, update the state variables for the height and width. Use the offsetHeight and offsetWidth properties to get the height and width of the element.

What is Android layout width?

android:layout_width Specifies the basic width of the view. This is a required attribute for any view inside of a containing layout manager.


2 Answers

You should be able to use the translationX and translationY properties to achieve the effect you want. These properties act as offsets from the original X and Y coordinates of the View.

Essentially translationX will displace the a View towards the right for a positive value and left for a negative value from it's X coordinate. Similarly translationY displaces the View towards the bottom for positive and top for negative values from it's Y coordinate.

Coming to your question, I am assuming that the final position you want to reach is the top left corner for the search icon, and the top right corner for the settings icon with zero padding for each view.

For the search icon I suggest you start by placing it in the top left corner of the toolbar. Then set both the translationX and translationY to 20p. That should place the search icon in the same place as your image. To move your search icon to the top left all you have to do is animate translationX & Y from 20dp to 0 dp.

Repeat the same for the settings icon, but set translationX to -20dp and translationY to 20dp. This way it'll be placed at the same position as your image. Animate both values to 0 to achieve your desired animation.

Here's the animation code for reference.

ivSearch.animate()
    .setInterpolator(new AccelerateInterpolator())
    .translationX(0) // Takes value in pixels. From 20dp to 0dp
    .translationY(0) // Takes value in pixels. From 20dp to 0dp
    .setDuration(250)
    .start();

ivSettings.animate()
    .setInterpolator(new AccelerateInterpolator())
    .translationX(0) // Takes value in pixels. From -20dp to 0dp
    .translationY(0) // Takes value in pixels. From 20dp to 0dp
    .setDuration(250)
    .start();

// To get pixels from dp
float px = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, getResources().getDisplayMetrics());

The great thing about this approach is that you no longer need to know the dimensions of the parent. All you care about is the offsets that you have specified via translationX and translationY.

like image 144
aashreys Avatar answered Oct 18 '22 21:10

aashreys


I believe the problem is that the Animator methods are expecting the values to be in raw pixel values. It looks like the code would only work as you intend on a medium density screen. E.g. A hdpi screen would require 30px instead of 20px to be located at the same location. On higher density screens the code as it exists would push the icons closer to the edges...

That means we need to translate the expected dp value into raw pixel values and use those for animation. There is a handy method for converting dp to px so that it's correct on every device. I'm assuming that you want the left side of the gear to be 160dp from the right(Note I'm specifically saying the left side of the gear because the 160dp value should also include the width of the gear image as the x property is from the left of the image). So 160dp = gear image width + desired right margin distance. Say you have a resource called ic_gear: Drawable drawable = getResources().getDrawable(R.drawable.ic_gear); float bitmapWidth = getIntrinsicWidth();

float rawPX20DPValue = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 20, getResources().getDisplayMetrics());

float rawPXLeftOffset = rawPX20DPValue + bitmapWidth;

ivSearch.animate()
    .setInterpolator(new AccelerateInterpolator())
    .x(rawPX20DPValue)
    .y(rawPX20DPValue)
    .setDuration(250)
    .start();


ivSettings.animate()
    .setInterpolator(new AccelerateInterpolator())
    .x(widthPx - rawPXLeftOffset)
    .y(rawPX20DPValue)
    .setDuration(250)
    .start();

Also check on the offsets(padding) of the gear and search icon before the move as that will likely affect the end result as well.

like image 22
Jim Baca Avatar answered Oct 18 '22 22:10

Jim Baca