首页 > 解决方案 > 如何正确旋转属于 RecyclerView 的 ImageView

问题描述

我问这个问题是因为我得到一个有趣的错误,当我的 RecyclerView 的两个 ImageView 被旋转时,原则上,我只对它进行了编程,以便一个人进行旋转。

背景信息:我总共上传了 30 张图片到可绘制文件夹。当我运行代码时,它们使我的应用程序崩溃,因此我创建了一个类来优化它们,就像 android 开发人员指南建议的那样:

public class ImagenOptimizada {


public static int calculateInSampleSize(
        BitmapFactory.Options options, int reqWidth, int reqHeight) {
    // Raw height and width of image
    final int height = options.outHeight;
    final int width = options.outWidth;
    int inSampleSize = 1;

    if (height > reqHeight || width > reqWidth) {

        final int halfHeight = height / 2;
        final int halfWidth = width / 2;

        // Calculate the largest inSampleSize value that is a power of 2 and keeps both
        // height and width larger than the requested height and width.
        while ((halfHeight / inSampleSize) >= reqHeight
                && (halfWidth / inSampleSize) >= reqWidth) {
            inSampleSize *= 2;
        }
    }

    return inSampleSize;
}


public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
                                                     int reqWidth, int reqHeight) {

    // First decode with inJustDecodeBounds=true to check dimensions
    final BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeResource(res, resId, options);

    // Calculate inSampleSize
    options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);

    // Decode bitmap with inSampleSize set
    options.inJustDecodeBounds = false;
    return BitmapFactory.decodeResource(res, resId, options);
}
}

这解决了OutOfMemoryError. 但是我仍然遇到我上传的一些图像出现颠倒的问题(即使它们在桌面上以正确的方向出现),所以我决定onBindViewHolder在类的方法中包含以下代码RecyclerAdapter

@Override
public void onBindViewHolder(@NonNull MyViewHolder viewHolder, int i) {

int image_id = images[i];

viewHolder.album.setImageBitmap(ImagenOptimizada.decodeSampledBitmapFromResource(viewHolder.album.getResources(), image_id, 250, 250));

if(image_id == R.drawable.img_2321 || image_id == R.drawable.img_2322 || image_id == R.drawable.img_2323 || image_id == R.drawable.img_2335 || image_id == R.drawable.img_2359 || image_id == R.drawable.img_2361) {

    viewHolder.album.setRotationX(180);

}


viewHolder.albumTitle.setText("Image: " + i);

}

这引发了一个有趣的行为,因为它确实转动了​​我想要的图像,但也转动了具有不同 ID 的其他图像(我意识到它转动了两个图像,我想要的一个和另一个,对于我在 if 中给出的每个 id健康)状况)。现在我完全被卡住了,因为我不知道为什么会这样。

这是 RecyclerAdapter.java 的完整代码:

public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.MyViewHolder> {


    private int[] images;


    public RecyclerAdapter(int[]images){
        this.images = images;

    }



    public static class MyViewHolder extends RecyclerView.ViewHolder {

        ImageView album;
        TextView albumTitle;

        public MyViewHolder(@NonNull View itemView) {
            super(itemView);

            album = itemView.findViewById(R.id.album);                                                  // R.id.album porque album es el id que dimos a la ImageView en image_and_text_layout.xml
            albumTitle = itemView.findViewById(R.id.album_title);                                       // R.id.album_title porque album_title es el id que dimos al TextView en image_and_text_layout.xml
        }
    }



    @NonNull
    @Override
    public MyViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {

        View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.image_and_text_layout, viewGroup, false);

        MyViewHolder myViewHolder = new MyViewHolder(view);

        return myViewHolder;
    }

    @Override
    public void onBindViewHolder(@NonNull MyViewHolder viewHolder, int i) {

        int image_id = images[i];

        viewHolder.album.setImageBitmap(ImagenOptimizada.decodeSampledBitmapFromResource(viewHolder.album.getResources(), image_id, 250, 250));

        if(image_id == R.drawable.img_2321 || image_id == R.drawable.img_2322 || image_id == R.drawable.img_2323 || image_id == R.drawable.img_2335 || image_id == R.drawable.img_2359 || image_id == R.drawable.img_2361) {

            viewHolder.album.setRotationX(180);

        }


        viewHolder.albumTitle.setText("Image: " + i);

    }

    @Override
    public int getItemCount() {
        return images.length;
    }
}

这是我的 MainActivity.class:

public class MainActivity extends AppCompatActivity {

    private RecyclerView recyclerView;
    private int[] images = {R.drawable.img_2321, R.drawable.img_2322, R.drawable.img_2323, R.drawable.img_2325, R.drawable.img_2326, R.drawable.img_2328,
            R.drawable.img_2329, R.drawable.img_2333, R.drawable.img_2335, R.drawable.img_2356, R.drawable.img_2358, R.drawable.img_2359, R.drawable.img_2360,
            R.drawable.img_2361, R.drawable.img_2363, R.drawable.img_2365, R.drawable.img_2366, R.drawable.img_2383, R.drawable.img_2390, R.drawable.img_2393, R.drawable.img_2394,
            R.drawable.img_2396, R.drawable.img_2397, R.drawable.img_2398, R.drawable.img_2454, R.drawable.img_2455, R.drawable.img_2456, R.drawable.img_2457,
            R.drawable.img_2458, R.drawable.img_2465};

    private RecyclerView.LayoutManager layoutManager;
    private RecyclerView.Adapter adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        recyclerView = findViewById(R.id.recyclerView);
        recyclerView.setHasFixedSize(true);

        layoutManager = new GridLayoutManager(this, 2);
        recyclerView.setLayoutManager(layoutManager);

        adapter = new RecyclerAdapter(images);
        recyclerView.setAdapter(adapter);


    }
}

提前感谢那些花时间回答的人。我非常感谢,因为我是编程的新手,而且我正在自学,这有时会很难。

标签: androidandroid-recyclerviewimageviewandroid-imageview

解决方案


RecyclerView将重用ViewHolder已滚出屏幕的 s,但不会自动重置它们。所以你可能有一个ImageView你已经应用了一个旋转来用于你不想旋转的图像。解决方案是在这种情况下显式调用setRotation(0)。在您的代码中执行此操作的最简单方法可能是在您当前应用轮换的语句中添加一个else块。if

if(...) {
    viewHolder.album.setRotationX(180);
} else {
    viewHOlder.album.setRotationX(0)
}

推荐阅读