Recently Added

6/recent/ticker-posts

multiple item select from recyclerview Video Player Part 15

 In this video player app series I am going to show you how you can select multiple files from recylerview and also change toolbar options and also show how many items you have selected

so let's start



1.Add Checkbox in file_view_folder.xml


<CheckBox
android:visibility="gone"
android:id="@+id/video_folder_checkbox"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:buttonTint="@color/white"
tools:targetApi="lollipop" />

2.Update Toolbar in activity_video_folder.xml


<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:menu="@menu/main_toolbar">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">

<TextView
android:id="@+id/counter_textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:maxLines="1"
android:ellipsize="end"
android:textSize="18sp"
android:text="0 item selectde"
android:textColor="@color/white"/>

</RelativeLayout>
</androidx.appcompat.widget.Toolbar>

3.Add this code in your VideoFolderAdapter.java

package com.example.player.adapter;

import android.app.AlertDialog;
import android.app.Dialog;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.provider.MediaStore;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import com.bumptech.glide.Glide;
import com.example.player.R;
import com.example.player.VideoModel;
import com.example.player.activity.VideoFolder;
import com.example.player.activity.VideoPlayer;
import com.google.android.material.bottomsheet.BottomSheetDialog;
import com.google.android.material.snackbar.BaseTransientBottomBar;
import com.google.android.material.snackbar.Snackbar;

import java.io.File;
import java.util.ArrayList;

public class VideosAdapter extends RecyclerView.Adapter<VideosAdapter.MyHolder> {


public static ArrayList<VideoModel> videoFolder = new ArrayList<>();
private final Context context;
VideoFolder videoFolderActivity;

public VideosAdapter(ArrayList<VideoModel> videoFolder, Context context) {
this.videoFolder = videoFolder;
this.context = context;
videoFolderActivity = (VideoFolder) context;
}

@NonNull
@Override
public MyHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.files_view, parent, false);
return new MyHolder(view, videoFolderActivity);
}

@Override
public void onBindViewHolder(@NonNull MyHolder holder, int position) {


Glide.with(context).load(videoFolder.get(position).getPath()).into(holder.thumbnail);
holder.title.setText(videoFolder.get(position).getTitle());
holder.duration.setText(videoFolder.get(position).getDuration());
holder.size.setText(videoFolder.get(position).getSize());
holder.resolution.setText(videoFolder.get(position).getResolution());
holder.menu.setOnClickListener(v -> {
BottomSheetDialog bottomSheetDialog = new BottomSheetDialog(context, R.style.BottomSheetDialogTheme);
View bottomSheetView = LayoutInflater.from(context).inflate(R.layout.file_menu, null);
bottomSheetDialog.setContentView(bottomSheetView);
bottomSheetDialog.show();
bottomSheetView.findViewById(R.id.menu_down).setOnClickListener(v1 -> {
bottomSheetDialog.dismiss();
});
bottomSheetView.findViewById(R.id.menu_share).setOnClickListener(v2 -> {
bottomSheetDialog.dismiss();
shareFile(position);
});
bottomSheetView.findViewById(R.id.menu_rename).setOnClickListener(v3 -> {
bottomSheetDialog.dismiss();
renameFiles(position, v);
});
bottomSheetView.findViewById(R.id.menu_delete).setOnClickListener(v4 -> {
bottomSheetDialog.dismiss();
deleteFiles(position, v);
});
bottomSheetView.findViewById(R.id.menu_properties).setOnClickListener(v5 -> {
bottomSheetDialog.dismiss();
showProperties(position);
});
});

holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(context, VideoPlayer.class);
intent.putExtra("p", position);
context.startActivity(intent);
}
});



if (videoFolderActivity.is_selectable){
//when true
holder.checkBox.setVisibility(View.VISIBLE);
holder.menu.setVisibility(View.GONE);
holder.checkBox.setChecked(false);
}else {
//when false
holder.checkBox.setVisibility(View.GONE);
holder.menu.setVisibility(View.VISIBLE);
}

}


private void shareFile(int p) {
Uri uri = Uri.parse(videoFolder.get(p).getPath());
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("video/*");
intent.putExtra(Intent.EXTRA_STREAM, uri);
context.startActivity(Intent.createChooser(intent, "share"));
Toast.makeText(context, "loading..", Toast.LENGTH_SHORT).show();
}

private void deleteFiles(int p, View view) {
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle("delete")
.setMessage(videoFolder.get(p).getTitle())
.setNegativeButton("cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
//todo
// leave it as empty
}
}).setPositiveButton("ok", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Uri contentUri = ContentUris.withAppendedId(MediaStore.Video.Media.EXTERNAL_CONTENT_URI,
Long.parseLong(videoFolder.get(p).getId()));
File file = new File(videoFolder.get(p).getPath());
boolean deleted = file.delete();
if (deleted) {
context.getApplicationContext().getContentResolver().delete(contentUri,
null, null);
videoFolder.remove(p);
notifyItemRemoved(p);
notifyItemRangeChanged(p, videoFolder.size());
Snackbar.make(view, "File Deleted Success", Snackbar.LENGTH_SHORT).show();
} else {
Snackbar.make(view, "File Deleted Fail", Snackbar.LENGTH_SHORT).show();
}
}
}).show();
}

private void renameFiles(int position, View view) {
final Dialog dialog = new Dialog(context);
dialog.setContentView(R.layout.rename_layout);
final EditText editText = dialog.findViewById(R.id.rename_edit_text);
Button cancel = dialog.findViewById(R.id.cancel_rename_button);
Button rename_btn = dialog.findViewById(R.id.rename_button);
final File renameFile = new File(videoFolder.get(position).getPath());
String nameText = renameFile.getName();
nameText = nameText.substring(0, nameText.lastIndexOf("."));
editText.setText(nameText);
editText.clearFocus();
dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
cancel.setOnClickListener(v -> {
dialog.dismiss();
});
rename_btn.setOnClickListener(v1 -> {
String onlyPath = renameFile.getParentFile().getAbsolutePath();
String ext = renameFile.getAbsolutePath();
ext = ext.substring(ext.lastIndexOf("."));
String newPath = onlyPath + "/" + editText.getText() + ext;
File newFile = new File(newPath);
boolean rename = renameFile.renameTo(newFile);
if (rename) {
context.getApplicationContext().getContentResolver().
delete(MediaStore.Files.getContentUri("external"),
MediaStore.MediaColumns.DATA + "=?",
new String[]{renameFile.getAbsolutePath()});
Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
intent.setData(Uri.fromFile(newFile));
context.getApplicationContext().sendBroadcast(intent);
Snackbar.make(view, "Rename Success", Snackbar.LENGTH_SHORT).show();
} else {
Snackbar.make(view, "Rename Failed", Snackbar.LENGTH_SHORT).show();
}
dialog.dismiss();
});
dialog.show();
}

private void showProperties(int p) {
Dialog dialog = new Dialog(context);
dialog.setContentView(R.layout.file_properties);

String name = videoFolder.get(p).getTitle();
String path = videoFolder.get(p).getPath();
String size = videoFolder.get(p).getSize();
String duration = videoFolder.get(p).getDuration();
String resolution = videoFolder.get(p).getResolution();

TextView tit = dialog.findViewById(R.id.pro_title);
TextView st = dialog.findViewById(R.id.pro_storage);
TextView siz = dialog.findViewById(R.id.pro_size);
TextView dur = dialog.findViewById(R.id.pro_duration);
TextView res = dialog.findViewById(R.id.pro_resolution);

tit.setText(name);
st.setText(path);
siz.setText(size);
dur.setText(duration);
res.setText(resolution + "p");

dialog.show();

}

@Override
public int getItemCount() {
return videoFolder.size();
}

public void updateSearchList(ArrayList<VideoModel> searchList) {
videoFolder = new ArrayList<>();
videoFolder.addAll(searchList);
notifyDataSetChanged();
}


public class MyHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
ImageView thumbnail, menu;
TextView title, size, duration, resolution;
CheckBox checkBox;
VideoFolder videoFolderActivity;

public MyHolder(@NonNull View itemView, VideoFolder videoFolderActivity) {
super(itemView);

thumbnail = itemView.findViewById(R.id.thumbnail);
title = itemView.findViewById(R.id.video_title);
size = itemView.findViewById(R.id.video_size);
duration = itemView.findViewById(R.id.video_duration);
resolution = itemView.findViewById(R.id.video_quality);
menu = itemView.findViewById(R.id.video_menu);
checkBox = itemView.findViewById(R.id.video_folder_checkbox);
this.videoFolderActivity = videoFolderActivity;

itemView.setOnLongClickListener(videoFolderActivity);
checkBox.setOnClickListener(this);
}

@Override
public void onClick(View v) {
videoFolderActivity.prepareSelection(v, getAdapterPosition());
}
}
}

4.Add this code to your VideoFolder.java 

package com.example.player.activity;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.SearchView;
import androidx.appcompat.widget.Toolbar;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.provider.MediaStore;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import com.example.player.R;
import com.example.player.VideoModel;
import com.example.player.adapter.VideosAdapter;
import com.google.android.gms.ads.AdError;
import com.google.android.gms.ads.AdRequest;
import com.google.android.gms.ads.AdSize;
import com.google.android.gms.ads.AdView;
import com.google.android.gms.ads.FullScreenContentCallback;
import com.google.android.gms.ads.LoadAdError;
import com.google.android.gms.ads.MobileAds;
import com.google.android.gms.ads.initialization.InitializationStatus;
import com.google.android.gms.ads.initialization.OnInitializationCompleteListener;
import com.google.android.gms.ads.interstitial.InterstitialAd;
import com.google.android.gms.ads.interstitial.InterstitialAdLoadCallback;

import java.util.ArrayList;
import java.util.Locale;

public class VideoFolder extends AppCompatActivity
implements SearchView.OnQueryTextListener, View.OnLongClickListener {

private static final String MY_SORT_PREF = "sortOrder";
Toolbar toolbar;
private RecyclerView recyclerView;
private String name;
private ArrayList<VideoModel> videoModelArrayList = new ArrayList<>();
private VideosAdapter videosAdapter;
private InterstitialAd mInterstitialAd;

public boolean is_selectable = false;
TextView countText;
ArrayList<VideoModel> selectionArrayList = new ArrayList<>();
int count = 0;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_video_folder);
recyclerView = findViewById(R.id.video_recyclerview);
countText = findViewById(R.id.counter_textView);

name = getIntent().getStringExtra("folderName");
toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeAsUpIndicator(getResources().getDrawable(R.drawable.go_back));
int index = name.lastIndexOf("/");
String onlyFolderName = name.substring(index + 1);
countText.setText(onlyFolderName);
loadVideos();
loadBannerAds();
}

private void loadBannerAds() {
MobileAds.initialize(this, new OnInitializationCompleteListener() {
@Override
public void onInitializationComplete(InitializationStatus initializationStatus) {}
});
AdRequest adRequest = new AdRequest.Builder().build();

InterstitialAd.load(this,"ca-app-pub-3940256099942544/1033173712", adRequest, new InterstitialAdLoadCallback() {
@Override
public void onAdLoaded(@NonNull InterstitialAd interstitialAd) {
// The mInterstitialAd reference will be null until
// an ad is loaded.
mInterstitialAd = interstitialAd;
Log.i("TAG", "onAdLoaded");
}

@Override
public void onAdFailedToLoad(@NonNull LoadAdError loadAdError) {
// Handle the error
Log.i("TAG", loadAdError.getMessage());
mInterstitialAd = null;
}
});
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
if (mInterstitialAd != null) {
mInterstitialAd.show(VideoFolder.this);
} else {
Log.d("TAG", "The interstitial ad wasn't ready yet.");
}
}
},4000);

}


@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main_toolbar, menu);
MenuItem menuItem = menu.findItem(R.id.search);
SearchView searchView = (SearchView) menuItem.getActionView();
ImageView ivClose = searchView.findViewById(androidx.appcompat.R.id.search_close_btn);
ivClose.setColorFilter(ContextCompat.getColor(getApplicationContext(), R.color.white),
android.graphics.PorterDuff.Mode.SRC_IN);
searchView.setQueryHint("Search file name");
searchView.setOnQueryTextListener(this);
return super.onCreateOptionsMenu(menu);
}

@Override
public boolean onQueryTextSubmit(String query) {
return false;
}

@Override
public boolean onQueryTextChange(String newText) {
String input = newText.toLowerCase();
ArrayList<VideoModel> searchList = new ArrayList<>();
for (VideoModel model : videoModelArrayList) {
if (model.getTitle().toLowerCase().contains(input)) {
searchList.add(model);
}
}
videosAdapter.updateSearchList(searchList);

return false;
}

private void loadVideos() {
videoModelArrayList = getallVideoFromFolder(this, name);
if (name != null && videoModelArrayList.size() > 0) {
videosAdapter = new VideosAdapter(videoModelArrayList, this);
//if your recyclerview lagging then just add this line
recyclerView.setHasFixedSize(true);
recyclerView.setItemViewCacheSize(20);
recyclerView.setDrawingCacheEnabled(true);
recyclerView.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH);
recyclerView.setNestedScrollingEnabled(false);

recyclerView.setAdapter(videosAdapter);
recyclerView.setLayoutManager(new LinearLayoutManager(this,
RecyclerView.VERTICAL, false));
} else {
Toast.makeText(this, "can't find any videos", Toast.LENGTH_SHORT).show();
}

}

private ArrayList<VideoModel> getallVideoFromFolder(Context context, String name) {
SharedPreferences preferences = getSharedPreferences(MY_SORT_PREF, MODE_PRIVATE);
//which one you want to set default in sorting
// i am setting by date
String sort = preferences.getString("sorting", "sortByDate");
String order = null;
switch (sort) {

case "sortByDate":
order = MediaStore.MediaColumns.DATE_ADDED + " ASC";
break;

case "sortByName":
order = MediaStore.MediaColumns.DISPLAY_NAME + " ASC";
break;

case "sortBySize":
order = MediaStore.MediaColumns.DATE_ADDED + " DESC";
break;

}
ArrayList<VideoModel> list = new ArrayList<>();
Uri uri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
String[] projection = {
MediaStore.Video.Media._ID,
MediaStore.Video.Media.DATA,
MediaStore.Video.Media.TITLE,
MediaStore.Video.Media.SIZE,
MediaStore.Video.Media.HEIGHT,
MediaStore.Video.Media.DURATION,
MediaStore.Video.Media.DISPLAY_NAME,
MediaStore.Video.Media.BUCKET_DISPLAY_NAME,
MediaStore.Video.Media.RESOLUTION
};
String selection = MediaStore.Video.Media.DATA + " like?";
String[] selectionArgs = new String[]{"%" + name + "%"};

Cursor cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, order);

if (cursor != null) {
while (cursor.moveToNext()) {

String id = cursor.getString(0);
String path = cursor.getString(1);
String title = cursor.getString(2);
int size = cursor.getInt(3);
String resolution = cursor.getString(4);
int duration = cursor.getInt(5);
String disName = cursor.getString(6);
String bucket_display_name = cursor.getString(7);
String width_height = cursor.getString(8);

//this method convert 1204 in 1MB
String human_can_read = null;
if (size < 1024) {
human_can_read = String.format(context.getString(R.string.size_in_b), (double) size);
} else if (size < Math.pow(1024, 2)) {
human_can_read = String.format(context.getString(R.string.size_in_kb), (double) (size / 1024));
} else if (size < Math.pow(1024, 3)) {
human_can_read = String.format(context.getString(R.string.size_in_mb), size / Math.pow(1024, 2));
} else {
human_can_read = String.format(context.getString(R.string.size_in_gb), size / Math.pow(1024, 3));
}

//this method convert any random video duration like 1331533132 into 1:21:12
String duration_formatted;
int sec = (duration / 1000) % 60;
int min = (duration / (1000 * 60)) % 60;
int hrs = duration / (1000 * 60 * 60);

if (hrs == 0) {
duration_formatted = String.valueOf(min)
.concat(":".concat(String.format(Locale.UK, "%02d", sec)));
} else {
duration_formatted = String.valueOf(hrs)
.concat(":".concat(String.format(Locale.UK, "%02d", min)
.concat(":".concat(String.format(Locale.UK, "%02d", sec)))));
}


VideoModel files = new VideoModel(id, path, title,
human_can_read, resolution, duration_formatted,
disName, width_height);
if (name.endsWith(bucket_display_name))
list.add(files);

}
cursor.close();
}

return list;
}

@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {

SharedPreferences.Editor editor = getSharedPreferences(MY_SORT_PREF, MODE_PRIVATE).edit();
switch (item.getItemId()) {

case R.id.sort_by_date:
editor.putString("sorting", "sortByDate");
editor.apply();
this.recreate();
break;

case R.id.sort_by_name:
editor.putString("sorting", "sortByName");
editor.apply();
this.recreate();
break;

case R.id.sort_by_size:
editor.putString("sorting", "sortBySize");
editor.apply();
this.recreate();
break;

case R.id.refresh:
refresh();
break;

case android.R.id.home:
if (is_selectable){
clearSelectingToolbar();
videosAdapter.notifyDataSetChanged();
}else {
onBackPressed();
}
break;
}

return super.onOptionsItemSelected(item);
}


private void refresh(){
if (name !=null && videoModelArrayList.size()>0){
videoModelArrayList.clear();
//handler will wait for 1.5sec and then run the code..
//1000=1sec
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
loadVideos();
videosAdapter.notifyDataSetChanged();
Toast.makeText(VideoFolder.this, "Refreshed",
Toast.LENGTH_SHORT).show();
}
},1500);
}else {
Toast.makeText(VideoFolder.this, "folder is empty",
Toast.LENGTH_SHORT).show();

}
}

@Override
public boolean onLongClick(View v) {
toolbar.getMenu().clear();
toolbar.inflateMenu(R.menu.item_selected_menu);
is_selectable = true;
videosAdapter.notifyDataSetChanged();
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeAsUpIndicator(getResources().getDrawable(R.drawable.go_back));
return true;
}

public void prepareSelection(View v, int position) {
if( ((CheckBox) v).isChecked() ){
selectionArrayList.add(videoModelArrayList.get(position));
count = count + 1;
updateCount(count);
}else {
selectionArrayList.remove(videoModelArrayList.get(position));
count = count - 1;
updateCount(count);
}
}

private void updateCount(int counts) {
if (counts == 0){
countText.setText("0 item selected");
}else {
countText.setText(counts + " item selected");
}
}

private void clearSelectingToolbar(){
is_selectable = false;
toolbar.getMenu().clear();
toolbar.inflateMenu(R.menu.main_toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeAsUpIndicator(getResources().getDrawable(R.drawable.go_back));
int index = name.lastIndexOf("/");
String onlyFolderName = name.substring(index + 1);
countText.setText(onlyFolderName);
count = 0;
selectionArrayList.clear();
}


@Override
public void onBackPressed() {
if (is_selectable){
clearSelectingToolbar();
videosAdapter.notifyDataSetChanged();
}else {
super.onBackPressed();
}
}
}

Watch Full Video Tutorials

Post a Comment

0 Comments