【问题标题】:getWidth() returns 0 in onCreateView()getWidth() 在 onCreateView() 中返回 0
【发布时间】:2013-12-01 13:44:20
【问题描述】:

我开始打算从图库中选择图像,然后缩放图像并动态地将 ImageView 添加到布局中。

我希望在方向更改时重新加载此图像。我在 onCreate 中设置了 setRetainInstance(true)。但是,在方向更改后,当我尝试通过调用应该是其容器的 FrameLayout 上的 getWidth() 来为要缩放的位图获得适当的宽度时,我得到 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();
        }
    }
}

我似乎找不到在方向更改后重新填充视图的方法。有人可以告诉我我做错了什么吗?

【问题讨论】:

  • 你的活动结果是否被调用?
  • 是的,这对我来说不是问题。我尝试重新加载图像的方向更改后遇到问题。
  • 请检查我的答案

标签: android orientation-changes


【解决方案1】:

不要从onCreateView 拨打setBackgroundPreview()。如果视图尚未完成创建,则无法测量视图。

改为在onActivityCreated 中调用setBackgroundPreview()

【讨论】:

  • 不幸的是,这仍然返回零。
【解决方案2】:

如果你想要像素宽度,你应该调用 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();
    }
  });
}

在第一次回调之后移除监听器可以确保释放大量进程,因为我们只需要一次测量的参数。

【讨论】:

  • 我不敢相信我必须这样做。我只希望我的 ImageView 在方向更改后显示相同的图像。
  • 好吧,当你改变方向时,@onCreate() 会再次被调用,以及其他活动的常规回调和生命周期。如果您需要在每次方向更改时重新计算视图的大小,只需确保通过设置 ViewTreeObserver 回调在 @onCreate() 回调中重新计算 viewWidth 和 viewHeight。它只会执行一次(当布局最终时,所以所有视图都是已创建),因此它根本不会给设备带来太多负载。我认为这是一个很好的解决方案,每次都会为您提供像素宽度和高度。请如果它帮助我欢迎率/正确答案。
  • 如果您还有任何问题,我会回来查看,祝您好运!
【解决方案3】:

直到视图实际渲染到屏幕上才定义宽度和高度。 收集自getWidth and getHeight are returning a zero。 你也检查这个帖子How do you to retrieve dimensions of a view? Getheight() and Getwidth() always return zero

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-02
    • 1970-01-01
    • 1970-01-01
    • 2019-02-03
    • 1970-01-01
    • 2014-05-23
    相关资源
    最近更新 更多