Как правильно повернуть ImageView, который принадлежит RecyclerView - PullRequest
0 голосов
/ 06 января 2019

Я задаю этот вопрос, потому что я получаю забавную ошибку, из-за которой я поворачиваю два изображения ImageView моего RecyclerView, когда, в принципе, я только запрограммировал его так, что один выполняет вращение.

Справочная информация: у меня есть 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);

}

Это вызвало странное поведение, поскольку оно поворачивало вокруг нужных мне изображений, но также и других изображений с разными идентификаторами (я понял, что это поворачивает вокруг двух изображений, одно, которое я хочу, и другое, для каждого идентификатора, который я даю. внутри условия 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);


    }
}

Заранее спасибо тем, кто нашел время, чтобы ответить. Я очень благодарен, потому что я новичок в программировании, и я учусь самостоятельно, что иногда делает это трудным.

1 Ответ

0 голосов
/ 06 января 2019

RecyclerView будет повторно использовать ViewHolder s, которые прокручиваются за пределы экрана, но не сбрасывает их автоматически. Таким образом, у вас может быть ImageView, что вы уже применили вращение для использования изображения, которое вы не хотите поворачивать. Решение состоит в том, чтобы явно вызвать setRotation(0) в этом случае. Самый простой способ сделать это в вашем коде - это, вероятно, добавить блок else в оператор if, где вы применяете ротацию в данный момент.

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