【问题标题】:Section recyclerview photos by date部分回收者按日期查看照片
【发布时间】:2020-06-14 01:28:13
【问题描述】:

我创建了一个简单的图库,显示手机上的所有图像。我想按日期(月份)划分图像,并且还想要一个包含最近拍摄的照片的顶部。请参考下图:

我该怎么做呢?

我的代码:

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

activity_select_file.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>

【问题讨论】:

    标签: java android xml android-recyclerview


    【解决方案1】:

    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,您可以找到更多关于它的信息here,如果您打算使用它,请阅读文档并为其使用适当的配置。但是您可以使用任何其他您想要的布局管理器。

    希望这对您有所帮助。

    【讨论】:

    • 感谢您的回答!您能否提供有关 XML 文件的详细信息!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-12
    • 1970-01-01
    • 2022-06-22
    • 2013-03-16
    • 2017-08-18
    相关资源
    最近更新 更多