java - 部分回收者按日期查看照片
问题描述
我创建了一个简单的画廊,显示手机上的所有图像。我想按日期(月份)划分图像,并且还想要一个包含最近拍摄的照片的顶部。请参考下图:
我该怎么做呢?
我的代码:
选择文件活动.Java
public class SelectFileActivity extends AppCompatActivity {
RecyclerView recyclerView;
GalleryAdapter galleryAdapter;
List < String > images;
TextView gallery_number;
ImageView back_arrow;
private static final int REQUEST_CODE_STORAGE_PERMISSION = 101;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_select_file);
// Remove status bar
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
// Initialize content
gallery_number = findViewById(R.id.gallery_number);
recyclerView = findViewById(R.id.recyclerview_gallery_images);
back_arrow = findViewById(R.id.select_file_back_arrow);
// Check for permission
if (ContextCompat.checkSelfPermission(SelectFileActivity.this,
Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(SelectFileActivity.this,
new String[] {
Manifest.permission.READ_EXTERNAL_STORAGE
}, REQUEST_CODE_STORAGE_PERMISSION);
} else {
loadImages();
}
}
@Override
public void onBackPressed() {
startActivity(new Intent(this, HomeActivity.class));
finish();
}
private void loadImages() {
recyclerView.setHasFixedSize(true);
// Set the number of pictures per a row
recyclerView.setLayoutManager(new GridLayoutManager(this, 3));
images = SelectImagesGallery.listOfImages(this);
galleryAdapter = new GalleryAdapter(this, images, new GalleryAdapter.PhotoListener() {
@Override
public void onPhotoClick(String path) {
// Do something with the selected photo
}
});
recyclerView.setAdapter(galleryAdapter);
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == REQUEST_CODE_STORAGE_PERMISSION) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
loadImages();
} else {
Toast.makeText(this, "Permission Denied", Toast.LENGTH_SHORT).show();
}
}
}
}
GalleryAdapter.java
public class GalleryAdapter extends RecyclerView.Adapter < GalleryAdapter.ViewHolder > {
private Context context;
private List < String > images;
protected PhotoListener photoListener;
public GalleryAdapter(Context context, List < String > images, PhotoListener photoListener) {
this.context = context;
this.images = images;
this.photoListener = photoListener;
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return new ViewHolder(
LayoutInflater.from(context).inflate(R.layout.gallery_item, parent, false)
);
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
String image = images.get(position);
// Load images to Glide
Glide.with(context)
.load(image)
.transform(new CenterCrop(), new RoundedCorners(15))
.into(holder.image);
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
photoListener.onPhotoClick(image);
}
});
}
@Override
public int getItemCount() {
return images.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
ImageView image;
public ViewHolder(@NonNull View itemView) {
super(itemView);
image = itemView.findViewById(R.id.image);
}
}
public interface PhotoListener {
void onPhotoClick(String path);
}
}
活动选择文件.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/windowBackground"
android:orientation="vertical"
tools:context=".upload.SelectFileActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerview_gallery_images"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
解决方案
TLDR
为它们创建两个 xml 和两个视图。在您的数据列表中还添加月份作为对象,并在您的onCreateViewHolder
方法中,检查 viewType 并为此膨胀适当的 xml。
详细解答
我必须在我的一个项目中实现类似的东西,这就是我的适配器的样子。这只是一个示例应用程序,当然这些功能可以更好地实现。您需要通过更好的设计来实现它们。
首先你需要实现你自己的 RecyclerView 适配器:
public class RvAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private List<GalleryBaseModel> _data;
Context context ;
public RvAdapter(Context context){
this.context = context;
this._data = new ArrayList<>();
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
if (viewType == 1){ //DATE
return new DateViewHolder(
LayoutInflater.from(context).inflate(R.layout.date_layout, parent, false)
);
}
else { //Image
return new ImageViewHolder(
LayoutInflater.from(context).inflate(R.layout.image_layout, parent, false)
);
}
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
if (getItemViewType(position) == 1){
// set date here
FlexboxLayoutManager.LayoutParams layoutParams = (FlexboxLayoutManager.LayoutParams) holder.itemView.getLayoutParams();
layoutParams.setFlexGrow(1.0f);
layoutParams.width = MATCH_PARENT;
holder.itemView.setLayoutParams(layoutParams);
}
else {
// set image here
FlexboxLayoutManager.LayoutParams layoutParams = (FlexboxLayoutManager.LayoutParams) holder.itemView.getLayoutParams();
layoutParams.setFlexGrow(1.0f);
layoutParams.width = getWidth();
holder.itemView.setLayoutParams(layoutParams);
}
}
/**
* A function to calculate width of your image cardViews.
* As it is a sample application I just return constant value, but you should calculate it.
* For example screenWidth/3
* @return Width of image cardView
*/
public int getWidth(){
return 200;
}
@Override
public int getItemCount() {
return _data.size();
}
@Override
public int getItemViewType(int position) {
return _data.get(position).getType();
}
class DateViewHolder extends RecyclerView.ViewHolder{
TextView dateTv;
public DateViewHolder(@NonNull View itemView) {
super(itemView);
dateTv = itemView.findViewById(R.id.dateTv);
}
}
class ImageViewHolder extends RecyclerView.ViewHolder{
ImageView mImage;
public ImageViewHolder(@NonNull View itemView) {
super(itemView);
mImage = itemView.findViewById(R.id.mImage);
}
}
public void addItem(GalleryBaseModel item){
this._data.add(item);
notifyDataSetChanged();
}
}
这是我的image_view.xml
:
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView android:layout_width="match_parent"
android:background="@android:color/black"
android:layout_height="120dp"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
xmlns:android="http://schemas.android.com/apk/res/android">
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<ImageView
android:id="@+id/mImage"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
这是我的date_layout.xml
:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto">
<TextView
android:id="@+id/dateTv"
android:text="June 2020"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</androidx.constraintlayout.widget.ConstraintLayout>
这是我的GalleryBaseModel.java
哪个是需要在我的适配器中膨胀的对象的基本模型类。
public abstract class GalleryBaseModel {
abstract int getType();
}
继承这个抽象类的所有类都需要实现getType()
方法并返回它们实际的模型类型。例如,这里 1 用于我的日期模型,0 用于我的图像模型。由于这些非常简单,我不将它们包含在回答。
最后是我如何设置我的 recyclerView:
//this could be onCreate method of your activity or any other proper method in activity or fragment or ...
adapter = new RvAdapter(getApplicationContext());
flexboxLayoutManager = new FlexboxLayoutManager(getApplicationContext());
flexboxLayoutManager.setJustifyContent(JustifyContent.SPACE_BETWEEN);
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(flexboxLayoutManager);
对于管理我使用的布局,您可以在此处FlexBoxLayoutManager
找到有关它的更多信息,如果您打算使用它,请阅读文档并为其使用适当的配置。但是您可以使用任何其他您希望的布局管理器。
希望这对您有所帮助。
推荐阅读
- python - python pandas数据框单元格更新错误
- wordpress - 如何更改“价格”
- amazon-s3 - 在亚马逊 s3 中生成签名的脚本是什么?
- json-ld - JSON-LD 不能在 @context 中定义多个节点类型
- ios - Swift google firebase VisionTextDetector 显示使用未声明类型
- pywinauto - 无法使用 UIA 后端访问子菜单元素
- gem5 - 如何在 gem5 中为创建的伪指令实现延迟
- python-3.x - 如何使用 glade gtk python 打印我的窗口
- python - 在python的while循环中创建固定大小的数组
- butterknife - 如何解决黄油刀库的这个错误?