imageView return getWidth zero - android

My imageView in xml:
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/ivManagePhoto"
android:layout_marginTop="10dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp" />
My code:
ImageView ivManagePhoto;
ivManagePhoto = (ImageView)findViewById(R.id.ivManagePhoto);
double ivw = ivManagePhoto.getWidth();
When i try to get ivManagePhoto.getWidth(); that return 0, but i need to get mathparent size.

You can try this:
imageView.post(new Runnable() {
#Override
public void run() {
imageView.getWidth();
}
});
or, try this:
ViewTreeObserver viewTreeObserver = rootLayout.getViewTreeObserver();
if (viewTreeObserver.isAlive()) {
viewTreeObserver.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
rootLayout.getViewTreeObserver().removeOnGlobalLayoutListener(this);
viewWidth = view.getWidth();
}
});
}
Hope this code will help you.

You can wait to onwindowfocuschanged event. At this time UI items are already loaded
#Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (hasFocus) {
//get sizes you want
Point screen_size=new Point();
getWindowManager().getDefaultDisplay().getSize(screen_size);
int width = screen_size.x;
int height = screen_size.y;
//...
}
//...
}

Related

Share Image element transition display incorrect size

I have a recycle view to show all photo thumbnail items. When click on item, I use transition for imageview in this item to Detail activity. The problem is that image source is gotten from internet by UIL. And sometime (not always) the images not reload correct size like this:
// on view holder item click
final Pair<View, String>[] pairs = TransitionHelper.createSafeTransitionParticipants(this, false,
new Pair<>(((ItemViewHolder) viewHolder).thumbnail, getString(R.string.TransitionName_Profile_Image)),
new Pair<>(((ItemViewHolder) viewHolder).tvName, getString(R.string.TransitionName_Profile_Name)));
ActivityOptionsCompat transitionActivityOptions = ActivityOptionsCompat.makeSceneTransitionAnimation(this, pairs);
startActivityForResult(intent, requestCode, transitionActivityOptions.toBundle());
Detail activity
// try to post pone transition until UIL load finish
ActivityCompat.postponeEnterTransition(this);
getSupportFragmentManager().beginTransaction().replace(R.id.layoutContent, new DetailFragment()).commit();
Fragment Detail
ImageLoader.getInstance().displayImage(url, imageViewDetail, new ImageLoadingListener() {
#Override
public void onLoadingStarted(String imageUri, View view) {
}
#Override
public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
finishAnimation();
}
#Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
finishAnimation();
}
#Override
public void onLoadingCancelled(String imageUri, View view) {
finishAnimation();
}
});
private void finishAnimation(){
ActivityCompat.startPostponedEnterTransition(getActivity());
imageViewDetail.invalidate();
}
fragment_detail.xml
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<ImageView
android:transitionName="#string/TransitionName.Profile.Image"
android:id="#+id/imageViewDetail"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:adjustViewBounds="true"
android:scaleType="centerCrop"/>
</FrameLayout>
I even wait views are laid out before load image but still not work:
imageViewDetail.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
#Override
public boolean onPreDraw() {
// code load image from UIL
return false;
}
});
Is there any way to avoid this issue?
this xml can handle diferent image size
<ScrollView
android:id="#+id/vScroll"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="51dp"
android:scrollbars="none" >
<HorizontalScrollView
android:id="#+id/hScroll"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scrollbars="none"
android:layout_gravity="center">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<ImageView
android:id="#+id/imgFullscreen"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="fitXY" />
</LinearLayout>
</HorizontalScrollView>
</ScrollView>
in java
fullImageView = (ImageView) findViewById(R.id.imgFullscreen);
selectedPhoto = (FeedItem) i.getSerializableExtra(TAG_SEL_IMAGE);
zoom = 1;
if (selectedPhoto != null) {
fetchFullResolutionImage();
} else {
Toast.makeText(getApplicationContext(),
getString(R.string.msg_unknown_error), Toast.LENGTH_SHORT)
.show();
}
private void fetchFullResolutionImage() {
try {
final URL url = new URL(selectedPhoto.getImge());
new Thread(new Runnable() {
#Override
public void run() {
try {
Bitmap bmp = BitmapFactory.decodeStream(url
.openStream());
if (bmp != null)
setImage(bmp);
else {
showToast("Error fetching image!");
}
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
} catch (IOException e) {
e.printStackTrace();
}
}
private void setImage(final Bitmap bmp) {
runOnUiThread(new Runnable() {
public void run() {
fullImageView.setImageBitmap(bmp);
adjustImageAspect(selectedPhoto.getWidth(),
selectedPhoto.getHeight());
}
});
}
private void adjustImageAspect(int bWidth, int bHeight) {
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
if (bWidth == 0 || bHeight == 0)
return;
int swidth;
if (android.os.Build.VERSION.SDK_INT >= 13) {
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
swidth = size.x;
} else {
Display display = getWindowManager().getDefaultDisplay();
swidth = display.getWidth();
}
int new_height = 0;
new_height = swidth * bHeight / bWidth;
params.width = swidth;
params.height = new_height;
saveW = swidth;
saveH = new_height;
fullImageView.setLayoutParams(params);
}

Intersecting two images in different Layouts

How it looks
I want to check intersection between ImageView to ImageView2 as LinearLayout slides towards ImageView2.
I used Rect but it is not working, ImageView2 Just passed throught it without getting intersect.
Please help me!!
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="true" >
<ImageView
android:id="#+id/tile"
android:layout_width="30dp"
android:layout_height="30dp"
android:src="#drawable/tile" />
<LinearLayout
android:id="#+id/l1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:weightSum="100" >
<ImageView
android:id="#+id/b1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="50"
android:background="#000"
android:src="#drawable/b" />
<ImageView
android:id="#+id/b2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="70dp"
android:layout_weight="50"
android:background="#000"
android:src="#drawable/b" />
</LinearLayout>
#SuppressLint("NewApi")
public class MainActivity extends Activity {
Rect tileRect = new Rect();
Rect b1Rect = new Rect();
Rect b2Rect = new Rect();
ImageView tile,b1,b2;
RelativeLayout layout;
LinearLayout l1;
final Handler h = new Handler();
Boolean tileRight=false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
move();
}
private void init() {
// TODO Auto-generated method stub
b1 = (ImageView)findViewById(R.id.b1);
b2 = (ImageView)findViewById(R.id.b2);
tile = (ImageView)findViewById(R.id.tile);
layout = (RelativeLayout)findViewById(R.id.layout);
l1 = (LinearLayout)findViewById(R.id.l1);
tile.setX(320);
tile.setY(800);
l1.setVisibility(View.VISIBLE);
}
public void move()
{
final int delay = 45;
h.postDelayed(new Runnable()
{
#Override
public void run() {
// TODO Auto-generated method stub
layout.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View arg0, MotionEvent event) {
// TODO Auto-generated method stub
if(event.getAction() == MotionEvent.ACTION_UP)
{
if(tileRight==true)
tileRight=false;
else
tileRight=true;
return true;
}
return false;
}
});
if(tileRight==true)
{
if(tile.getX()>600f)
{
tile.setX(tile.getX());
}
else{
tile.setX(tile.getX()+speedTile);
}
}
else{
if(tile.getX()<40f)
{
tile.setX(tile.getX());
}
else{
tile.setX(tile.getX()-speedTile);
}
}
tile.getHitRect(tileRect);
b1.getHitRect(b1Rect);
b2.getHitRect(b2Rect);
if(Rect.intersects(tileRect, b1Rect) || Rect.intersects(tileRect, b2Rect))
{
gameOver();
}
l1.setY(l1.getY()+10f);
h.postDelayed(this, delay);
}
},delay);
}
private void gameOver() {
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
Android's View has getLocationOnScreen() method that shows absolute position of your view.
https://developer.android.com/reference/android/view/View.html#getLocationOnScreen(int[])
The issue occurs because view.getHitRect() is used before the layouts are inflated.
Any of the view's position or measurement APIs like getWidth(), getTop(), getRight() etc. will return 0 (getHitRect() initializes the Rect with (0,0,0,0)) in onCreate() or onResume() before the views are inflated.
In your case, it appears that the Handler's delay period executes the intersection logic earlier than view inflation.
You could post from the view and the run() method will execute after the view inflates and then obtain the view's measurement parameters or a Rect .
Here is an example:
public class MyTestActivity extends AppCompatActivity{
int mNumberOfViewsInitialized = 0;
ImageView mImageViewRight, mImageViewLeft;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.sliding_image_activity);
mImageViewLeft = (ImageView) findViewById(R.id.image_view_left);
mImageViewRight = (ImageView) findViewById(R.id.image_view_right);
// calling method here will log that the views do not intersect
// which happens because they haven't been inflated yet.
// doViewsOverlap();
mImageViewLeft.post(new Runnable(){
#Override
public void run() {
mNumberOfViewsInitialized++;
intersectionLogic();
}
});
mImageViewRight.post(new Runnable(){
#Override
public void run() {
mNumberOfViewsInitialized++;
intersectionLogic();
}
});
}
private void intersectionLogic(){
/* the constant could be something else, depending
on the number of views you'd like to test intersection for*/
if(mNumberOfViewsInitialized == 2){
doViewsOverlap(mImageViewLeft,mImageViewRight);
}
}
private void doViewsOverlap(final View firstView, final View secondView){
Rect leftRect = new Rect();
firstView.getHitRect(leftRect);
Rect rightRect = new Rect();
secondView.getHitRect(rightRect);
if(Rect.intersects(leftRect,rightRect) || Rect.intersects(rightRect,leftRect))
Log.v("intersects","views intersect");
else
Log.v("intersects","views do not intersect");
}
}
I used a layout which does not animate / move the images, but the same issue should occur when the images are moved as well
<ImageView
android:id="#+id/image_view_left"
android:layout_width="300dp"
android:layout_height="300dp"
android:layout_alignParentLeft="true"
android:background="#android:color/holo_blue_dark"
android:src = "#mipmap/ic_launcher"/>
<ImageView
android:id="#+id/image_view_right"
android:layout_width="300dp"
android:layout_height="300dp"
android:layout_alignParentRight="true"
android:background="#android:color/holo_green_dark"
android:gravity="end"
android:src="#mipmap/ic_launcher"/>
Images contained in a RelativeLayout.
Here is a screenshot of the UI:
This problem is related to this: If I call getMeasuredWidth() or getWidth() for layout in onResume they return 0
Hope this helps.

ImageView height always returns zero in android

I know this is kind of a duplicate but the answers for other question didn't help me. always my ImageView height returns zero. here is what I tried:
dart.getViewTreeObserver().addOnPreDrawListener(
new ViewTreeObserver.OnPreDrawListener() {
public boolean onPreDraw() {
int finalHeight = dart.getMeasuredHeight();
int finalWidth = dart.getMeasuredWidth();
Toast.makeText(MainActivity.this," "+finalHeight,Toast.LENGTH_SHORT).show();
return true;
}
});
ALSO -
#Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
height = dart.getHeight();
width = dart.getWidth();
Toast.makeText(MainActivity.this," "+height,Toast.LENGTH_SHORT).show();
}
And I also tried dart.getHeight() inside the onCreate but I understood it can't work. What can I do?
Add addonPreDrawListener to ViewTreeObserver and call dart.getViewTreeObserver().removeOnPreDrawListener(this); in your onPreDraw() method
ViewTreeObserver vto = iv.getViewTreeObserver();
vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
public boolean onPreDraw() {
dart.getViewTreeObserver().removeOnPreDrawListener(this);
finalHeight = dart.getMeasuredHeight();
finalWidth = dart.getMeasuredWidth();
Toast.makeText(MainActivity.this," "+finalHeight,Toast.LENGTH_SHORT).show();
return true;
}
});

Set Pivot for Rotate animation (ObjectAnimator) , not working?

I've applied a Rotate animation to a button using ObjectAnimator, while the rotation seems to work; the pivot point still remains the top left corner of the button.
MainActivity
Button bt1;
float pivotX=0f;
float pivotY=0f;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bt1 = (Button) findViewById(R.id.button1);
pivotX = bt1.getX() + (float)bt1.getWidth();// 500;// bt1.getHeight() ;
pivotY = bt1.getY() + (float)bt1.getHeight();// 500;// bt1.getWidth();
bt1.setPivotX(pivotX);
bt1.setPivotY(pivotY);
bt1.setOnClickListener(this);
}
private void rotate()
{
ObjectAnimator rotate = ObjectAnimator.ofFloat(bt1, View.ROTATION_X,360);
rotate.setDuration(2000);
AnimatorSet aSet = new AnimatorSet();
aSet.play(rotate);
aSet.start();
}
#Override
public void onClick(View v)
{
switch(v.getId())
{
case R.id.button1:
rotate();
break;
}
}
Edit:
bt1.getX and bt1.getY return 0. Will update once I know why.
Edit: This doesnt seem to work either.
#Override
public void onWindowFocusChanged(boolean hasFocus)
{
// TODO Auto-generated method stub
super.onWindowFocusChanged(hasFocus);
//Here you can get the size!
width = bt1.getWidth();
height = bt1.getHeight();
}
yea bt1.getWidth() can't get result but 0 in onCreate, because bt1 was not measured yet.you can have a try follow below:
button.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout(){
//here you can get size
width = button.getWidth();
height = button.getHeight();
}
});
getX() in OnCreate always give you a zero - it is not "implemented" on view
you have to wait for it. I use this loop to wait for definitely non-zero values:
new Thread(new Runnable() {
public void run() {
int count = 0;
do {
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.d(TAG, "checkin... count="+count);
count++;
} while (!(playStopButton.getWidth() > 0) && count < 100);
runOnUiThread(new Runnable() {
public void run() {
//here get X, get width etc
}
});
}
}).start();

View's getWidth() and getHeight() returning 0

I have looked at the similar questions and tried their solutions, but it didn't work for me. I'm trying to read width of an imageView, but it is returning 0. Here is the code:
public class MainActivity extends Activity {
private ImageView image1;
float centerX,centerY;
private ImageView image2;
private boolean isFirstImage = true;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.rotate);
image1 = (ImageView) findViewById(R.id.ImageView01);
image2 = (ImageView) findViewById(R.id.ImageView02);
image2.setVisibility(View.GONE);
if (isFirstImage) {
applyRotation(0, 90);
isFirstImage = !isFirstImage;
}
}
private void applyRotation(float start, float end) {
centerX=image1.getWidth()/2.0f;
centerY=image1.getHeight()/2.0f;
final Flip3dAnimation rotation =
new Flip3dAnimation(start, end,centerX , centerY);
rotation.setDuration(500);
rotation.setFillAfter(true);
rotation.setInterpolator(new AccelerateInterpolator());
rotation.setAnimationListener(new DisplayNextView(isFirstImage, image1,
image2));
if (isFirstImage)
{
image1.startAnimation(rotation);
} else {
image2.startAnimation(rotation);
}
}
}
Can anyone help me with this? Thanks
You need to use the onSizechanged() method.
This is called during layout when the size of this view has changed
You should use: image1.getLayoutParams().width;
You are either accessing the ImageViews width and height before it has been measured, or after you set its visibility to GONE.
image2.setVisibility(View.GONE);
Then getWidth() or getHeight() will return 0.,
You can also have a look at onWindowFocusChanged(), onSizeChanged() and onMeasure():
#Override
public void onWindowFocusChanged(boolean focus) {
super.onWindowFocusChanged(focus);
// get the imageviews width and height here
}
public class GETImageView extends ImageView {
public GETImageView (Context context, AttributeSet attrs) {
super(context, attrs);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
Drawable d = getDrawable();
if (d != null) {
int width = MeasureSpec.getSize(widthMeasureSpec);
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
The ImageView have not yet draw the image, so no width or height return.
You may use a subclass to get the imageview width.
Here is some link provide you another easy methods:
How to get the width and height of an android.widget.ImageView?
How to get the width and height of an Image View in android?
Android ImageView return getWidth, getHeight zero
Hope this help you.
you can use OnGlobalLayoutListener for the ImageView image1 so you can get exact width and height occupied by the view in the layout...as
image1 = (ImageView) findViewById(R.id.ImageView01);
ViewTreeObserver viewTreeObserver = image1.getViewTreeObserver();
viewTreeObserver
.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
if (isFirstImage) {
applyRotation(0, 90);
isFirstImage = !isFirstImage;
}
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN)
image1.getViewTreeObserver()
.removeOnGlobalLayoutListener(this);
else
image1.getViewTreeObserver()
.removeGlobalOnLayoutListener(this);
}
});
By the way, views don't get sized until the measurement steps have been taken. See this link:
getWidth() and getHeight() of View returns 0
Maybe you should call View.measure(int,int) first.
Since the width and height is not defined until this view is draw. You can call measure by hand to enforce this view to calculate it's size;
Please using a Handler and get height and width on this with delay time >= 10
This may be useful for use:
#Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
getHeight();
}
private void getHeight() {
// TODO Auto-generated method stub
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(), "Height:" + mAnimationView.getMeasuredHeight(),
Toast.LENGTH_SHORT).show();
}
}, 10L);
}

Categories

Resources