视频库不能滚动平滑

时间:2017-08-10 13:48:15

标签: android gridview vertical-scrolling video-gallery

我正在使用网格视图,它会从布局中展开custom_layout。网格视图正在从手机加载视频并以缩略图的形式填充它。一切都很好。滚动网格视图时出现问题。它的滚动速度很慢,而且手机的API> 20正在提供消息应用未响应

我已经关注此链接,但没有找到完美的解决方案: Gridview is scrolling slow

我使用异步任务从图库中加载视频。我正在给出相同的代码。这是我的片段:

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);
        }
    });
}}

由于存在大量数据,而且我知道由于数据量很大,因此滚动速度不慢。我需要一个解决方案。谢谢你提前。

EDITS

在关注此链接后,我得到了一个结果,并根据解决方案对getView()进行了一些更改,但仍无法解决我的问题。

链接:GridView Smooth Scrolling Solution

我的getView()现在是这样的:

我的Adapter类中的

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;

    }

1 个答案:

答案 0 :(得分:0)

位图很容易耗尽应用程序的内存预算。

如果您的应用正在将多个位图加载到内存中,则需要熟练地管理内存和磁盘缓存。 因此,无论何时从视频加载图像,都必须耗尽应用程序的内存预算。

我建议使用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);
}

另请阅读

solving-the-android-image-loading-problem-volley-vs-picasso/

Handling Bitmaps