java - setimageresource - ImageView.getWidth() devuelve 0
scale image android studio (3)
Obtengo el ancho 0 de imageView. A continuación se muestra el código.
archivo xml:
<ImageView
android:id="@+id/img"
android:layout_width="200dp"
android:layout_height="200dp" />
Actividad :
@Override
protected void onResume() {
super.onResume();
ImageView img = (ImageView) findViewById(R.id.img);
Log.d(TAG, "width : " + img.getWidth());
}
No quiero usar el código de abajo, ya que necesito colocar este código en tantos lugares.
ViewTreeObserver vto = img.getViewTreeObserver();
vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
public boolean onPreDraw() {
ImageView img = (ImageView) findViewById(R.id.img);
Log.d(TAG, "width : " + img.getWidth());
return true;
}
});
Mi solución: en realidad, más tarde no tuve que agregar este código en una actividad. Lo agregué a una clase sin actividad y, en lugar del ancho de ImageView, utilicé el ancho de la imagen de mapa de bits y ahora no tengo este problema.
¿Dónde se llama a getWidth()
y getHeight()
en ImageView? Si llama desde onCreate()
en actividad, no funcionará. getWidth() and getHeight()
esperar a que se adjunte la ventana de actividad y luego llamar a getWidth() and getHeight()
en ImageView. Puedes intentar llamar a getWidth() and getHeight()
desde el método onWindowFocusChanged()
de tu actividad.
llamar en onWindowFocusChanged como esta manera
public void onWindowFocusChanged(boolean hasFocus) {
// TODO Auto-generated method stub
super.onWindowFocusChanged(hasFocus);
if (hasFocus) {
ImageView img = (ImageView) findViewById(R.id.img);
Log.d(TAG, "width : " + img.getWidth());
}
}
Bueno, encontré muchas preguntas relacionadas que están duplicadas a esta pregunta, y la mayoría de las respuestas no eran adecuadas para mi caso.
He encontrado una solución que puede ajustarse a la tuya como lo hace para mí. Simplemente, he creado un ImageView
personalizado y agregué una nueva devolución de llamada OnSizeChangedCallback
que se llama cada vez que el tamaño de la vista cambia a valores distintos de cero.
Aquí hay una muestra de código de mi propio:
public class AvatarImageView extends ImageView{
private OnImageViewSizeChanged sizeCallback = null;
public AvatarImageView(Context context) {
super(context);
}
public AvatarImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public AvatarImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
if (w == 0 || h == 0) {
return;
}
else{
if(sizeCallback != null)
sizeCallback.invoke(this, w, h);
}
}
public void setOnImageViewSizeChanged(OnImageViewSizeChanged _callback){
this.sizeCallback = _callback;
if (getWidth() != 0 && getHeight() != 0) {
_callback.invoke(this, getWidth(), getHeight());
}
}
public interface OnImageViewSizeChanged{
public void invoke(ImageView v, int w, int h);
}
}
y simplemente puedes usarlo de la siguiente manera:
final AvatarImageView avatarIcon = (AvatarImageView) findViewById(R.id.avatarImg);
avatarIcon.setOnImageViewSizeChanged(new AvatarImageView.OnImageViewSizeChanged() {
@Override
public void invoke(ImageView v, final int w, final int h) {
// Do whatever you want with w and h which are non zero values ...
}
});
preguntas relacionadas:
Como ya tiene una imagen de ancho "fija" de 200dp, ¿por qué no la pone en dimens.xml?
<dimen name="image_width">200dp</dimen>
y luego simplemente
int width = (int) getResources().getDimension(R.dimen.image_Width)