从 SD 卡中选择和显示图像时出现奇怪的行为

发布于 2024-12-13 07:20:16 字数 4770 浏览 2 评论 0原文

我制作了一个简单的 Android 应用程序,它在网格视图中显示图像,您可以选择一些图像并发送它们。这是我的 getView 方法。

 public View getView(intposition,ViewconvertView,ViewGroupparent)
    {
        查看v;
        if (convertView == null)
        {
            LayoutInflater li = getLayoutInflater();
            v = li.inflate(R.layout.imageview, null);
            final CheckBox cb = (CheckBox) v.findViewById(R.id.checkbox);
            cb.setOnCheckedChangeListener(new AddPhotos());

            ImageView iv = (ImageView) v.findViewById(R.id.image);

            //make image clickable so that it is checked when clicked on the image
            iv.setOnClickListener(new OnClickListener()
            {

                @Override
                public void onClick(View v)
                {
                    cb.setChecked((cb.isChecked() ? false : true));

                }
            });

            imagecursor.moveToPosition(position);

            uriList.add(imagecursor.getString(image_column_index));

            File image = new File(imagecursor.getString(image_column_index));

            Bitmap actualBitmap = resizeBitMapImage(image.getPath(), image_width, image_height);
            iv.setImageBitmap(actualBitmap);

            iv.setLayoutParams(new FrameLayout.LayoutParams(95, 95));
            System.gc();

        }
        else
        {
            v = convertView;
            System.gc();

        }
        return v;
    }
}

现在的问题是,对于较少的图像,即当所有图像都显示而无需滚动时,它工作得很好。但是,如果有图像不可见并且您必须向下滚动,那么它会通过重复先前的图像并在向下或向上滚动时更改图像的选中状态来显示奇怪的行为。我改变了 getView 方法,例如

公共视图 getView(int 位置,视图 ConvertView,ViewGroup 父级)

    {

        View v;
        if (convertView == null)
        {
            LayoutInflater li = getLayoutInflater();
            v = li.inflate(R.layout.imageview, null);

        }
        else
        {
            v = convertView;
            System.gc();

        }

        final CheckBox cb = (CheckBox) v.findViewById(R.id.checkbox);
        cb.setOnCheckedChangeListener(new AddPhotos());

        ImageView iv = (ImageView) v.findViewById(R.id.image);

        // make image clickable so that it is checked when clicked on the image
        iv.setOnClickListener(new OnClickListener()
        {

            @Override
            public void onClick(View v)
            {
                cb.setChecked((cb.isChecked() ? false : true));

            }
        });

        imagecursor.moveToPosition(position);

        uriList.add(imagecursor.getString(image_column_index));

        File image = new File(imagecursor.getString(image_column_index));

        Bitmap actualBitmap = resizeBitMapImage(image.getPath(), image_width, image_height);
        iv.setImageBitmap(actualBitmap);

        iv.setLayoutParams(new FrameLayout.LayoutParams(95, 95));
        System.gc();

        return v;
    }
}

现在图像的顺序没有改变,但向上或向下滚动会引发ANR,并且检查状态也会改变(我猜是随机的)。 traces.txt 显示它来自 resizeBitMapImage 方法中的 bitMapImage = BitmapFactory.decodeFile(filePath, options); 行,如下所示

public static Bitmap resizeBitMapImage(String filePath, int targetWidth, int targetHeight)

{
    Bitmap bitMapImage = null;
    // First, get the dimensions of the image
    Options options = new Options();
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeFile(filePath, options);
    double sampleSize = 0;
    // Only scale if we need to
    // (16384 buffer for img processing)
    Boolean scaleByHeight = Math.abs(options.outHeight - targetHeight) >= Math.abs(options.outWidth - targetWidth);

    if (options.outHeight * options.outWidth * 2 >= 1638)
    {
        // Load, scaling to smallest power of 2 that'll get it <= desired
        // dimensions
        sampleSize = scaleByHeight ? options.outHeight / targetHeight : options.outWidth / targetWidth;
        sampleSize = (int) Math.pow(2d, Math.floor(Math.log(sampleSize) / Math.log(2d)));
    }

    // Do the actual decoding
    options.inJustDecodeBounds = false;
    options.inTempStorage = new byte[128];
    while (true)
    {
        try
        {
            options.inSampleSize = (int) sampleSize;
            bitMapImage = BitmapFactory.decodeFile(filePath, options);

            break;
        }
        catch (Exception ex)
        {
            try
            {
                sampleSize = sampleSize * 2;
            }
            catch (Exception ex1)
            {

            }
        }
    }

    return bitMapImage;
}

现在我对android开发非常陌生,并且非常困惑。请提供任何帮助,我们将不胜感激

编辑:图像正在添加到 gridview 中,getView 方法适用于该 gridview 的 imageAdapter。

I have made a simple android application that displays images in a gridview and you can select some images and send them. This is my getView method.

  public View getView(int position, View convertView, ViewGroup parent)
    {
        View v;
        if (convertView == null)
        {
            LayoutInflater li = getLayoutInflater();
            v = li.inflate(R.layout.imageview, null);
            final CheckBox cb = (CheckBox) v.findViewById(R.id.checkbox);
            cb.setOnCheckedChangeListener(new AddPhotos());

            ImageView iv = (ImageView) v.findViewById(R.id.image);

            //make image clickable so that it is checked when clicked on the image
            iv.setOnClickListener(new OnClickListener()
            {

                @Override
                public void onClick(View v)
                {
                    cb.setChecked((cb.isChecked() ? false : true));

                }
            });

            imagecursor.moveToPosition(position);

            uriList.add(imagecursor.getString(image_column_index));

            File image = new File(imagecursor.getString(image_column_index));

            Bitmap actualBitmap = resizeBitMapImage(image.getPath(), image_width, image_height);
            iv.setImageBitmap(actualBitmap);

            iv.setLayoutParams(new FrameLayout.LayoutParams(95, 95));
            System.gc();

        }
        else
        {
            v = convertView;
            System.gc();

        }
        return v;
    }
}

Now the problem wit this was that for less images i.e when all images are displayed without any need to scroll, it was working fine. But if there were images not visible and you have to scroll down, then it showed a strange behavior by repeating the earlier images and changing the checked state of the images when you scroll down or up. I changed the getView method like

public View getView(int position, View convertView, ViewGroup parent)

    {

        View v;
        if (convertView == null)
        {
            LayoutInflater li = getLayoutInflater();
            v = li.inflate(R.layout.imageview, null);

        }
        else
        {
            v = convertView;
            System.gc();

        }

        final CheckBox cb = (CheckBox) v.findViewById(R.id.checkbox);
        cb.setOnCheckedChangeListener(new AddPhotos());

        ImageView iv = (ImageView) v.findViewById(R.id.image);

        // make image clickable so that it is checked when clicked on the image
        iv.setOnClickListener(new OnClickListener()
        {

            @Override
            public void onClick(View v)
            {
                cb.setChecked((cb.isChecked() ? false : true));

            }
        });

        imagecursor.moveToPosition(position);

        uriList.add(imagecursor.getString(image_column_index));

        File image = new File(imagecursor.getString(image_column_index));

        Bitmap actualBitmap = resizeBitMapImage(image.getPath(), image_width, image_height);
        iv.setImageBitmap(actualBitmap);

        iv.setLayoutParams(new FrameLayout.LayoutParams(95, 95));
        System.gc();

        return v;
    }
}

Now the order of the images is not changing but scrolling up or down throws an ANR and the checked state is also changed (i guess randomly). the traces.txt shows that it is coming from bitMapImage = BitmapFactory.decodeFile(filePath, options); line in the resizeBitMapImage method which is as below

public static Bitmap resizeBitMapImage(String filePath, int targetWidth, int targetHeight)

{
    Bitmap bitMapImage = null;
    // First, get the dimensions of the image
    Options options = new Options();
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeFile(filePath, options);
    double sampleSize = 0;
    // Only scale if we need to
    // (16384 buffer for img processing)
    Boolean scaleByHeight = Math.abs(options.outHeight - targetHeight) >= Math.abs(options.outWidth - targetWidth);

    if (options.outHeight * options.outWidth * 2 >= 1638)
    {
        // Load, scaling to smallest power of 2 that'll get it <= desired
        // dimensions
        sampleSize = scaleByHeight ? options.outHeight / targetHeight : options.outWidth / targetWidth;
        sampleSize = (int) Math.pow(2d, Math.floor(Math.log(sampleSize) / Math.log(2d)));
    }

    // Do the actual decoding
    options.inJustDecodeBounds = false;
    options.inTempStorage = new byte[128];
    while (true)
    {
        try
        {
            options.inSampleSize = (int) sampleSize;
            bitMapImage = BitmapFactory.decodeFile(filePath, options);

            break;
        }
        catch (Exception ex)
        {
            try
            {
                sampleSize = sampleSize * 2;
            }
            catch (Exception ex1)
            {

            }
        }
    }

    return bitMapImage;
}

Now i am very new to android development and am very confused. Please any help will be greatly appreciated

EDIT: The images are being added to gridview and the getView method is for the imageAdapter for this gridview.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文