getWidth() возвращает 0 в onCreateView()
Я начинаю собирать изображение из галереи, затем масштабирую изображение и динамически добавляю ImageView к макету.
Я хочу, чтобы это изображение было перезагружено при изменении ориентации. Я устанавливаю setRetainInstance (true) в onCreate. Тем не менее, после изменения ориентации, когда я пытаюсь получить соответствующую ширину для растрового изображения, которое нужно масштабировать, вызывая getWidth() для FrameLayout, который должен быть его контейнером, я получаю 0.
public class NewWallpaper extends Fragment {
private static final int PICK_BACKGROUND = 1;
private BitmapFactory.Options bitmapFactoryOptions;
// Data
private Uri backgroundURI = null;
private WeakReference<Bitmap> backgroundBitmap = null;
// Views
FrameLayout backgroundContainer;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.layout_new_wallpaper, container, false);
// BitmapFactory options
bitmapFactoryOptions = new BitmapFactory.Options();
bitmapFactoryOptions.inPurgeable = true;
Button pickBackground = (Button) view.findViewById(R.id.buttonPickBackground);
pickBackground.setOnClickListener(pickBackgroundListener);
backgroundContainer = (FrameLayout) view.findViewById(R.id.frameLayoutbackgroundContainer);
if (backgroundURI != null)
setBackgroundPreview();
return view;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
}
private Button.OnClickListener pickBackgroundListener = new Button.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("image/*");
startActivityForResult(intent, PICK_BACKGROUND);
}
};
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if(requestCode == PICK_BACKGROUND && resultCode == getActivity().RESULT_OK && data != null && data.getData() != null) {
backgroundURI = data.getData();
setBackgroundPreview();
}
super.onActivityResult(requestCode, resultCode, data);
}
private void setBackgroundPreview() {
try {
backgroundContainer.removeAllViews();
Bitmap background = BitmapHelper.loadScaledBitmap(getActivity(), backgroundURI, backgroundContainer.getWidth());
backgroundBitmap = new WeakReference<Bitmap>(background);
// returns 0
int containerWidth = backgroundContainer.getWidth();
ImageView backgroundView = new ImageView(getActivity());
backgroundView.setLayoutParams(new LinearLayout.LayoutParams(
backgroundContainer.getWidth(),
BitmapHelper.calculateHeight(
background.getWidth(),
background.getHeight(),
backgroundContainer.getWidth())
));
backgroundView.setAdjustViewBounds(true);
backgroundView.setScaleType(ImageView.ScaleType.FIT_XY);
backgroundView.setImageBitmap(background);
backgroundContainer.addView(backgroundView);
} catch (IOException e) {
e.printStackTrace();
}
}
}
Кажется, я не могу найти способ заселить представления после изменения ориентации. Может кто-нибудь сказать мне, что я делаю не так?
3 ответа
Не звони setBackgroundPreview()
от onCreateView
, Вы не можете измерить вид, если он еще не закончен.
Вызов setBackgroundPreview()
в onActivityCreated
вместо.
Если вы хотите ширину в пикселях, вы должны вместо этого вызвать view.getMeasuredWidth (). getWidth () и getHeight () дадут вам
LayoutParams.WRAP_CONTENT | LayoutParams.MATCH_PARENT //constants (1 or 0).
Тем не менее, чтобы убедиться, что вы получаете правильное значение, вызовите этот метод после обратного вызова @onDraw () вашего представления (переопределите его) или получите viewTreeObserver и дождитесь обратного вызова onGlobalLayout() для вызова методов.
<<<<< РЕДАКТИРОВАТЬ: >>>>>
Найден один пример с ViewTreeObserver:
ViewTreeObserver viewTreeObserver = view.getViewTreeObserver();
if (viewTreeObserver.isAlive()) {
viewTreeObserver.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
view.getViewTreeObserver().removeGlobalOnLayoutListener(this);
viewWidth = mediaGallery.getMeasuredWidth();
viewHeight = mediaGallery.getMeasuredHeight();
}
});
}
Удаление прослушивателя после первого обратного вызова гарантирует освобождение большого количества процесса, поскольку нам нужны только один раз измеренные параметры.
Ширина и высота не определяются до тех пор, пока вид фактически не отобразится на экране. Собранные из getWidth и getHeight возвращают ноль. Также вы проверяете этот пост Как вам получить размеры представления? Getheight () и Getwidth() всегда возвращают ноль