Родительский просмотрщик утилит
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".fragments.PhotoFragment">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_photo"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical"
android:clipToPadding="false"
android:paddingBottom="170dp">
</androidx.recyclerview.widget.RecyclerView>
</FrameLayout>
Его адаптер
public class PhotoAdapter extends RecyclerView.Adapter<PhotoAdapter.ViewHolder> {
private static final String TAG = "PhotoAdapter";
private Map<String, List<Photo>> photoMap;
private Context context;
private PhotoCategoryAdapter photoCategoryAdapter;
private List<String> keysList;
public PhotoAdapter(Map<String, List<Photo>> photoMap, Context context, List<String> keysList) {
this.photoMap = photoMap;
this.context = context;
this.keysList = keysList;
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return new ViewHolder(LayoutInflater.from(parent.getContext())
.inflate(R.layout.row_photo, parent, false));
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
String date = keysList.get(position);
holder.lblTakenDate.setText(date);
List<Photo> photoList = photoMap.get(date);
String size = ("( "+ photoList.size() + " )");
holder.lblCountPhotos.setText(size);
setRecyclerView(holder, context, photoList);
}
@Override
public int getItemCount() {
return photoMap.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
@BindView(R.id.rv_photo_category) RecyclerView recyclerView;
@BindView(R.id.lbl_taken_date_photo) TextView lblTakenDate;
@BindView(R.id.lbl_count_images_photo) TextView lblCountPhotos;
public ViewHolder(@NonNull View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
}
}
}
Обзор Reycler внутри утилитного просмотра
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="5dp">
<TextView
android:id="@+id/lbl_taken_date_photo"
android:textColor="@android:color/black"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:textSize="14dp"
android:hint="23-Aug-2018" />
<TextView
android:id="@+id/lbl_count_images_photo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:layout_toRightOf="@id/lbl_taken_date_photo"
android:hint="(2)"
android:textSize="12sp" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_photo_category"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/lbl_taken_date_photo"
android:layout_marginTop="10dp"
android:background="@color/light_grey" />
</RelativeLayout>
Его адаптер
public class PhotoCategoryAdapter extends RecyclerView.Adapter<PhotoCategoryAdapter.ViewHolder> {
private static final String TAG = "PhotoCategoryAdapter";
private List<Photo> photoList;
private Context context;
public PhotoCategoryAdapter(List<Photo> photoList, Context context) {
this.photoList = photoList;
this.context = context;
}
@NonNull
@Override
public PhotoCategoryAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return new ViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.row_category_photo, parent, false));
}
@Override
public void onBindViewHolder(@NonNull PhotoCategoryAdapter.ViewHolder holder, int position) {
Photo photo = photoList.get(position);
RequestOptions myOptions = new RequestOptions() .format(DecodeFormat.PREFER_ARGB_8888).
fitCenter().override(100, 100).placeholderOf(R.drawable.ic_image);
Glide.with(context)
.applyDefaultRequestOptions(myOptions)
.asBitmap()
.load(photo.getImage())
.diskCacheStrategy(DiskCacheStrategy.RESOURCE)
.into(holder.imgVImages);
}
@Override
public int getItemCount() {
return photoList.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
@BindView(R.id.imgv_images_category_photo)
ImageView imgVImages;
@BindView(R.id.imgv_selected_icon_photo) ImageView imgVSelectedPhoto;
public ViewHolder(@NonNull View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
}
}
}
Рядвнутренний просмотрщик
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_margin="5dp"
android:layout_width="80dp"
android:layout_height="80dp">
<ImageView
android:id="@+id/imgv_images_category_photo"
android:scaleType="fitXY"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<ImageView
android:id="@+id/imgv_selected_icon_photo"
android:visibility="gone"
android:layout_width="15dp"
android:layout_height="15dp"
android:layout_margin="10dp"
android:src="@drawable/ic_select"
android:layout_alignParentEnd="true"/>
</RelativeLayout>
Активность или фрагмент, из которого вы будете отправлять данные в адаптер
public class PhotoFragment extends Fragment {
@BindView(R.id.rv_photo) RecyclerView recyclerView;
private PhotoAdapter photoAdapter;
private ArrayList<Photo> photoList;
private ArrayList<String> keyList;
private Map<String,List<Photo>> map;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_photo, container, false);
ButterKnife.bind(this, view);
init();
setRecyclerViewAdapter();
new PhotoAsync(getContext()).execute();
return view;
}
private void init(){
map = new HashMap<>();
keyList = new ArrayList<>();
photoList = new ArrayList<>();
}
//set layout manager to recyclerView
private void setRecyclerViewAdapter() {
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
}
//get list of images
@RequiresApi(api = Build.VERSION_CODES.Q)
private List<Photo> getAllImages(){
Uri u = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
String[] projection = {MediaStore.Images.ImageColumns.DATA, MediaStore.Images.ImageColumns.DATE_TAKEN};
Cursor c = null;
ArrayList<Photo> photoList = new ArrayList<>();
if (u != null) {
c = getContext().getContentResolver().query(u, projection, null, null, null); }
if ((c != null) && (c.moveToFirst())) {
do {
Photo photo = new Photo();
String path = c.getString(c.getColumnIndexOrThrow(MediaStore.Images.ImageColumns.DATA));
String takenDate = c.getString(c.getColumnIndexOrThrow(MediaStore.Images.ImageColumns.DATE_TAKEN));
long millisecond = Long.parseLong(takenDate);
String date = DateFormat.format("dd-MMM-yyyy", new Date(millisecond)).toString();
try{
photo.setImage(path);
photo.setDate(date);
photoList.add(photo);
}
catch(Exception e)
{ }
}
while (c.moveToNext());
}
//reverse photoList
Collections.reverse(photoList);
return photoList;
}
public class PhotoAsync extends AsyncTask<Void, Void, Void> {
private Context context;
public PhotoAsync(Context context) {
this.context = context;
}
@RequiresApi(api = Build.VERSION_CODES.Q)
@Override
protected Void doInBackground(Void... params) {
getPhotoList();
return null;
}
@Override
protected void onPostExecute(Void aVoid) {
photoAdapter = new PhotoAdapter(map, context, keyList);
recyclerView.setAdapter(photoAdapter);
photoAdapter.notifyDataSetChanged();
}
@Override
protected void onPreExecute() {
}
}
@RequiresApi(api = Build.VERSION_CODES.Q)
private void getPhotoList(){
photoList.addAll(getAllImages());
for (Photo string : photoList) {
if (!keyList.contains(string.getDate()))
keyList.add(string.getDate());
else;
}
for (String s : keyList){
ArrayList<Photo> photos = new ArrayList<>();
for (Photo s1 : photoList) {
if (s1.getDate().equals(s))
photos.add(s1);
else;
}
map.put(s, photos);
}
}
}
Here is the logic which you have to apply
1. Find all the common dates from the data list
for example you data list is :
List<Model> dataList = new ArrayList<>();
dataList.add(new Model("23/10/19"));
dataList.add(new Model("23/10/19"));
dataList.add(new Model("23/09/19"));
dataList.add(new Model("23/10/19"));
dataList.add(new Model("27/09/19"));
dataList.add(new Model("23/10/19"));
List<String> commonList = new ArrayList<>();
for(Model m : dataList){
if(!commonList.contains(model.getDate()))
commonList.add(m.getDate());
else
Log.d("Dates", commonList);
}
Above function will help in getting all common dates
//Here map store date with data which has common date
Map<String, List<Model>> map = new HashMap<>();
List<Model> objectsofCommonDate = new ArrayList();
for(String date: commonList){
objectsofCommonDate.clear();
for(Model model : dataList){
if(model.getData.contains(date))
objectsofCommonDate.add(model);
else
\\do nothing
}
map.put(data, objectsOfCommonDate);
}
and pass map to main recyclerview adapter along with commonDateList;