如何正确旋转属于 RecyclerView 的 ImageView

How to properly rotate ImageView that belongs to a RecyclerView

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

背景资料:我一共上传了30张图片到drawable文件夹。当我 运行 代码时,他们使我的应用程序崩溃,所以我创建了一个 class 来优化它们,就像 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。但我仍然遇到一些问题,我上传的一些图片出现颠倒(即使它们在桌面上显示的方向正确),所以我决定在 onBindViewHolderonBindViewHolder 方法中包含以下代码16=] class:

@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 的图像(我意识到它转动了两张图像,一张是我想要的,另一张是我想要的,对于每个 ID我在 if 条件内给出)。现在我完全卡住了,因为我不知道为什么会这样。

这里是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);


    }
}

预先感谢那些花时间回答的人。我很感激,因为我是编程的新手,而且我正在自学,有时很难。

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

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