Видеогалерея не прокручивается плавно

Я использую представление сетки, которое увеличивает custom_layout из макета. Представление сетки загружает видео с телефона и заполняет его в виде миниатюр. Все работает нормально. Возникла проблема с прокруткой сетки. Он прокручивается медленно, а в телефоне, API которого > 20, выдается сообщение Приложение не отвечает

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

Я использовал асинхронную задачу для загрузки видео из галереи. Я даю код для того же. Вот мой фрагмент:

<сильный>1. AddFragment.java

public class AddFragment extends Fragment {

private ImageButton imageButton;
private GridView gridView;
private ProgressDialog videoProgressDialog;
ArrayList<File> list = new ArrayList<>();
ImageAdapter imageAdapter;

public AddFragment() {
    // Required empty public constructor
}


@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    View view = inflater.inflate(R.layout.fragment_add, container, false);

    imageButton = (ImageButton) view.findViewById(R.id.gotoButton);

    gridView = (GridView) view.findViewById(R.id.grid_view);
    gridView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
    Log.e("ADD_VIDEOS","FRAGMENT CREATED");
    videoProgressDialog = new ProgressDialog(getContext());
    videoProgressDialog.setTitle("Loading Videos");
    videoProgressDialog.setMessage("please wait.....");
    videoProgressDialog.setCancelable(false);
    videoProgressDialog.show();

    LoadVideoTask videoTask = new LoadVideoTask();
    videoTask.execute(new File("/mnt"));

    return view;
}

//reading the file from the storage
void videoReader(File root) {


    File[] file = root.listFiles();

    if (file != null) {

        for (File aFile : file) {
            if (!aFile.isDirectory()) {
                if (aFile.getName().endsWith(".mp4")) {
                    Log.e("VIDEO_FILE=====", aFile.getName());
                    list.add(aFile);
                }
            } else
                videoReader(aFile);
        }
    } else{}
}

//Show hide select button if images are selected or deselected
public void showSelectButton() {
    ArrayList<String> selectedItems = imageAdapter.getCheckedItems();
    Log.e("CHECKED_ITEMS",imageAdapter.getCheckedItems().toString());
    if (selectedItems.size() > 0) {
        imageButton.setVisibility(View.VISIBLE);
    } else
        imageButton.setVisibility(View.GONE);

}

 class ImageAdapter extends BaseAdapter {


    private Bitmap bitmap;

    private LayoutInflater inflater;
     SparseBooleanArray mSparseBooleanArray;

    private final Context context;

    private ImageAdapter(Context c) {
        context = c;
        //changes done from here
        mSparseBooleanArray = new SparseBooleanArray();

    }

    //Method to return selected Images
    public ArrayList<String> getCheckedItems() {
        ArrayList<String> mTempArry = new ArrayList<String>();

        for (int i = 0; i < list.size(); i++) {
            if (mSparseBooleanArray.get(i)) {
                mTempArry.add(list.get(i).toString());
            }
        }

        return mTempArry;
    }


    //for the video numbers
    @Override
    public int getCount() {
        return list.size();
    }

    //for getting the video items position vise
    @Override
    public Object getItem(int position) {
        return list.get(position);
    }

    @Override
    public long getItemId(int i) {
        return i;
    }


    @Override
    public View getView(int position, View convertView, ViewGroup viewGroup) {

        View v;

        if (convertView == null) {

            inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            v = inflater.inflate(R.layout.custom_gridview,viewGroup,false);
            v.setLayoutParams(new AbsListView.LayoutParams(215,215));

        } else {
           // picturesView = (ImageView) convertView;
            v = (View)convertView;
        }

        Viewholder viewHolder = new Viewholder(v);
        //viewHolder.imageView.setId(position);
        viewHolder.id = position;
        //convertView.setTag(viewHolder);

        //loading images from the videos
        if (list.get(position).toString().contains(".jpg")) {
            bitmap = BitmapFactory.decodeFile(list.get(position).toString()); //Creation of Thumbnail of image
          //  viewHolder.imageView.setImageBitmap(bitmap);
        } else {
            if (list.get(position).toString().contains(".mp4")) {
                bitmap = ThumbnailUtils.createVideoThumbnail(list.get(position).toString(), 1); //Creation of Thumbnail of video
                viewHolder.imageView.setImageBitmap(bitmap);
            }
        }

        //picturesView.setScaleType(ImageView.ScaleType.CENTER_CROP);
        //picturesView.setAdjustViewBounds(true);
        //picturesView.setLayoutParams(new GridView.LayoutParams(215, 215));
        //picturesView.setImageBitmap(bitmap);
        //setting layout params for every device

        viewHolder.checkBox.setTag(position);
        viewHolder.checkBox.setChecked(mSparseBooleanArray.get(position));
        CompoundButton.OnCheckedChangeListener mCheckedChangeListener = new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton compoundButton, boolean isChecked) {
                mSparseBooleanArray.put((Integer) compoundButton.getTag(), isChecked);//Insert selected checkbox value inside boolean array
                showSelectButton();
            }
        };
        viewHolder.checkBox.setOnCheckedChangeListener(mCheckedChangeListener);


        //return picturesView;
        return v;

    }

     class Viewholder {
        public ImageView imageView;
        public CheckBox checkBox;
         public int id;
         public Viewholder(View v){
             imageView = (ImageView) v.findViewById(R.id.galleryImageView);
             checkBox = (CheckBox) v.findViewById(R.id.selectCheckBox);
         }
    }
}

//asynch task has been done to do the processing in the background for loading the videos
//three parametres are Params,Progress,Result
private class LoadVideoTask extends AsyncTask<File,Integer, Integer>{


    @Override
    protected Integer doInBackground(File... files) {
        for(int i=0;i<files.length;i++) {
            videoReader(files[i]);
            Log.e("VIDEO_LOAD", files[i].toString());
        }
        return files.length;
    }

    @Override
    protected void onProgressUpdate(Integer... values) {
        super.onProgressUpdate(values);
        videoProgressDialog.setProgress(values[0]);
    }

    @Override
    protected void onPostExecute(Integer integer) {
        super.onPostExecute(integer);
        updateUI();
    }
}

private void updateUI() {

    videoProgressDialog.dismiss();
    //calling imageadapter class in here
    imageAdapter = new ImageAdapter(getContext());
    //for not repeating of the files
    LinkedHashSet<File> fileList = new LinkedHashSet<>();
    fileList.addAll(list);
    list.clear();
    list.addAll(fileList);
    gridView.setAdapter(imageAdapter);

    imageButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Intent intent = new Intent(getContext(), EditVideoActivity.class);
            intent.putExtra("sendData", imageAdapter.getCheckedItems());   //passing the data
            Log.e("SEND_DATA", imageAdapter.getCheckedItems().toString());
            startActivity(intent);
        }
    });
}}

Поскольку данных много, и я знаю, что из-за больших данных прокрутка не медленная. Мне нужно решение для этого. Заранее спасибо.

РЕДАКТИРОВАНИЕ

После перехода по этой ссылке я получил результат и внес некоторые изменения в getView() в соответствии с решением, которое все еще не решает мою проблему.

Ссылка: GridView Smooth Scrolling Solution

Мой getView() сейчас такой:

метод getView() внутри моего класса адаптера

@Override
    public View getView(int position, View convertView, ViewGroup viewGroup) {


        Viewholder viewHolder = null;

        if (convertView == null) {

            viewHolder = new Viewholder();

            inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = inflater.inflate(R.layout.custom_gridview,viewGroup,false);
            convertView.setLayoutParams(new AbsListView.LayoutParams(215,215));

            convertView.setTag(viewHolder);

        } else {
            viewHolder = (Viewholder) convertView.getTag();
        }

        viewHolder.imageView = (ImageView) convertView.findViewById(R.id.galleryImageView);
        viewHolder.checkBox = (CheckBox) convertView.findViewById(R.id.selectCheckBox);
        viewHolder.id = position;

        //loading images from the videos
        if (list.get(position).toString().contains(".jpg")) {
            bitmap = BitmapFactory.decodeFile(list.get(position).toString()); //Creation of Thumbnail of image
          //  viewHolder.imageView.setImageBitmap(bitmap);
        } else {
            if (list.get(position).toString().contains(".mp4")) {
                bitmap = ThumbnailUtils.createVideoThumbnail(list.get(position).toString(), 1); //Creation of Thumbnail of video
                viewHolder.imageView.setImageBitmap(bitmap);
            }
        }

        viewHolder.checkBox.setTag(position);
        viewHolder.checkBox.setChecked(mSparseBooleanArray.get(position));
        CompoundButton.OnCheckedChangeListener mCheckedChangeListener = new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton compoundButton, boolean isChecked) {
                mSparseBooleanArray.put((Integer) compoundButton.getTag(), isChecked);//Insert selected checkbox value inside boolean array
                showSelectButton();
            }
        };
        viewHolder.checkBox.setOnCheckedChangeListener(mCheckedChangeListener);

        return convertView;

    }

person Alok    schedule 10.08.2017    source источник
comment
Изображения загружаются ... это делает асинхронная задача. Но после загрузки изображения прокручиваются так медленно   -  person Alok    schedule 10.08.2017
comment
Это манипуляция с изображением вызывает медлительность? Вы декодируете растровое изображение или создаете эскиз из .mp4 каждый раз, когда вызывается getView(). Это должно занять некоторое время. Можно ли это сделать заранее в фоновом потоке, возможно, в рамках AsyncTask?   -  person Cheticamp    schedule 10.08.2017
comment
Нет, настоящая проблема заключается в тяжелых данных. Изображение успешно заполняется, все работает отлично. Но когда все данные появляются, теперь, если вы хотите прокрутить, они прокручиваются медленно. И да, если видео меньше, то проблемы нет. Я уверен, что вы поняли, о чем я пытаюсь сказать   -  person Alok    schedule 10.08.2017


Ответы (1)


Растровые изображения могут очень легко исчерпать бюджет памяти приложения.

Если ваше приложение загружает в память несколько растровых изображений, вам необходимо умело управлять кэшированием памяти и диска. Поэтому всякий раз, когда вы загружаете изображения из видео, он должен исчерпать бюджет памяти приложения.

Я рекомендую использовать библиотеку Picasso. (http://square.github.io/picasso/)

Picasso.with(context).load(new File(YOUR_FILE_PATH)).into(imageView);

Вы должны изменить его в исходном коде.

if (list.get(position).toString().contains(".mp4")) {
            bitmap = ThumbnailUtils.createVideoThumbnail(list.get(position).toString(), 1); //Creation of Thumbnail of video
            Picasso.with(context).load(getImageUri(context, bitmap)).into(viewHolder.imageView);}

public Uri getImageUri(Context inContext, Bitmap inImage) {
    ByteArrayOutputStream bytes = new ByteArrayOutputStream();
    inImage.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
    String path = MediaStore.Images.Media.insertImage(inContext.getContentResolver(), inImage, "Title", null);
    return Uri.parse(path);
}

Также, пожалуйста, прочитайте его

решение-изображения-android -loading-problem-volley-vs-picasso/

Обработка растровых изображений

person redAllocator    schedule 10.08.2017
comment
попробую и скажу результат - person Alok; 10.08.2017
comment
Я сделал это, но были некоторые изменения, например, новый файл (list.get(position).toString()) и да, into не разрешается, поскольку он показывает, что Cannot resolve into(android.widget. imageView) и еще один вопрос, где будет использоваться растровое изображение? - person Alok; 10.08.2017
comment
Я сделал то, что вы мне предложили, но это усложняет задачу, до этого все изображения заполнялись одновременно, но прокрутка была медленной. Теперь проблема усугубляется, когда я прокручиваю изображения, которые отображаются только в это время, и из-за этого прокрутка также слишком медленная. Это не то решение, которое я сейчас ищу. - person Alok; 10.08.2017
comment
пожалуйста, загрузите свой полный источник, например, github - person redAllocator; 10.08.2017
comment
Извините, но я не могу, мне не разрешено это делать. Это код, в котором я столкнулся с проблемой. Вам просто нужно просмотреть код - person Alok; 11.08.2017