一个带时间的相册页面,真小米手机仿小米相册

这个我研究了两天,真要命,昨晚搞出来的。在这里我们用了以下gradle:

compile 'com.android.support:cardview-v7:24.0.0'
compile 'com.android.support:recyclerview-v7:24.2.1'

compile 'com.github.bumptech.glide:glide:3.7.0'
compile 'com.truizlop.sectionedrecyclerview:library:1.0.0'
第一个是卡片,点了有水波效果,
第 2个是你们懂得看名字就知道,
第3个是安卓官方推荐的处理图片的框架,
第4个是一个带头部分组栏的适配器.

首先你们看到的布局,我们来写:
主布局
 
时间的item:

这个!

http://download.csdn.net/download/x_bx_b/10031735


然后现在我们说一说怎么拿到这些照片,我们是从medisstore拿的,注意要添加权限:
三个都加吧
在manifest那里加。
我们可以在new thread里面获取到两个list,然后传送到handle里面。
读取的权限

public class RVAdapter extends SectionedRecyclerViewAdapter<RVAdapter.MyHeadView,RVAdapter.MyViewHolder,RVAdapter.MyFootView>{//remember extendspublic List<Photo> photos;Context context;public List<String> photoDates;public static int sectionCount;String[][] path=new String[1000][1000];//这个是我的数组,将list转变为这个数组//我不懂怎么动态初始化//前面的【】是某天,后面【】是某天里面有几张照片OnItemClickListener onItemClickListener;OnItemLongClickListener onItemLongClickListener;public RVAdapter(List<Photo> photos, List<String> photoDates,Context context) {this.photos = photos;this.context = context;this.photoDates = photoDates;sectionCount=photoDates.size();// System.out.println("zhiqian");// System.out.println(sectionCount);getPath();//其实是将list转变为2D数组System.out.println(photos.size()+"@@@"+photoDates.size());}@Overrideprotected MyFootView onCreateSectionFooterViewHolder(ViewGroup parent, int viewType) {return null;}//必须继承@Overrideprotected MyHeadView onCreateSectionHeaderViewHolder(ViewGroup parent, int viewType) {//必须继承,添加时间item的View view=LayoutInflater.from(parent.getContext()).inflate(R.layout.headitem,parent,false);return new MyHeadView(view);}@Overrideprotected MyViewHolder onCreateItemViewHolder(ViewGroup parent, int viewType) {//必须继承,添加主体photoView view=LayoutInflater.from(parent.getContext()).inflate(R.layout.item,parent,false);//  System.out.println("photoSize: "+photos.size()+"\n"+"photoDates: "+photoDates.size());return new MyViewHolder(view);}@Overridepublic void onBindItemViewHolder(MyViewHolder holder, final int section, int position) {//绑定数据,也就是绑定照片final MyViewHolder viewHolder=(MyViewHolder)holder;
//       String path=getPath(section)[section][position];
//        System.out.println(path);
//            Ttest();Glide.with(context).load(new File(path[section][position])).centerCrop().diskCacheStrategy(DiskCacheStrategy.NONE).into(viewHolder.img);//Glide就是加载图片的工具,android官方推荐的viewHolder.cardView.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {onItemClickListener.onItemClick(v,viewHolder.getAdapterPosition()-section-1);//-1是因为从0开始的,第一个位置就要变成第0个;}});}public void setOnItemClickListener(OnItemClickListener itemClick){this.onItemClickListener=itemClick;}public void setOnItemLongClickListener(OnItemLongClickListener itemLongClick){this.onItemLongClickListener=itemLongClick;}public interface OnItemClickListener{void onItemClick(View view,int position);}public interface OnItemLongClickListener{void onItemLongClick(View view,int position);}//有了这这四个可以有点击的效果@Overrideprotected void onBindSectionFooterViewHolder(MyFootView holder, int section) {}//必须继承, @Overrideprotected void onBindSectionHeaderViewHolder(MyHeadView holder, int section) {MyHeadView viewHolder=(MyHeadView)holder;viewHolder.dateTV.setText(photoDates.get(section));}//必须继承,绑定头部时间@Overrideprotected boolean hasFooterInSection(int section) {return false;}//必须继承,有脚吗?@Overridepublic int getSectionCount() {//return photoDates.size();// System.out.println(MainActivity.photoDates.size()+"");return MainActivity.photoDates.size();}//必须继承这个就是一共有多少个日期的。一天就是一个,100天就是一百个@Overridepublic int getItemCount() {return photos.size()+photoDates.size();}//必须继承 一个有多少个item,有天数的和照片个数的@Overrideprotected int getItemCountForSection(int section) {return getCountInsection(section);}//必须继承public int  getCountInsection(int section){List<Photo> sectionPhotos=new ArrayList<>();for (int i=0;i<MainActivity.photos.size();i++){if (MainActivity.photoDates.get(section).equals(MainActivity.photos.get(i).getDate())){sectionPhotos.add(MainActivity.photos.get(i));}}//这个是获得某一天里面有多少张照片。return sectionPhotos.size();} public void getPath(){int count=0;for (×××){for (××){path[i][j]=photos.get(count).getPath();count++;}}//这个是将list转变为2D数据的方法,我自己写的,这4行最烦心,最烧脑。所以我不让你看,想看就下面我的工程呗,AndroidStudio的;
   System.out.println(photos.get(0).getPath());}class MyViewHolder extends RecyclerView.ViewHolder{CardView cardView;SquareImg img;public MyViewHolder(View itemView) {super(itemView);cardView=(CardView)itemView.findViewById(R.id.cardView);img=(SquareImg)itemView.findViewById(R.id.img);}}//怎么说,这3个就是用到findView的吧class MyHeadView extends RecyclerView.ViewHolder{TextView dateTV;public MyHeadView(View itemView) {super(itemView);dateTV=(TextView) itemView.findViewById(R.id.headTV);}}class MyFootView extends RecyclerView.ViewHolder{public MyFootView(View itemView) {super(itemView);}}
}

记得一定要加权限哦
package com.bbg.textalbum;import android.content.ContentResolver;
import android.database.Cursor;
import android.os.Handler;
import android.os.Message;
import android.provider.MediaStore;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.Toast;import com.timehop.stickyheadersrecyclerview.StickyRecyclerHeadersDecoration;
import com.truizlop.sectionedrecyclerview.SectionedSpanSizeLookup;import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;public class MainActivity extends AppCompatActivity {RecyclerView RV;public static List<Photo> photos;//这两个是可以在其他java都能访问到的。public static List<String> photoDates;ContentResolver resolver;//可以通过数据库拿文件的一个工具。DateFormat format = new SimpleDateFormat("yyyy-MM-dd");//把long转成StringRVAdapter adapter;//适配器@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);findView();getPhotos();}public void findView() {RV = (RecyclerView) findViewById(R.id.RV);resolver = getContentResolver();//要get}Handler handler = new Handler() {@Overridepublic void handleMessage(Message msg) {//先看下面getphotosuper.handleMessage(msg);switch (msg.what) {case 1:Bundle bundle = msg.getData();//获取photos = (ArrayList<Photo>) bundle.getParcelableArrayList("photos").get(0);//从msg拿到两个listphotoDates = (ArrayList<String>) bundle.getParcelableArrayList("photos").get(1);adapter = new RVAdapter(photos, photoDates, MainActivity.this);GridLayoutManager manager = new GridLayoutManager(MainActivity.this, 3);//后面数字就是一行几个图片的意思SectionedSpanSizeLookup lookup = new SectionedSpanSizeLookup(adapter, manager);//这是啥我不知道,关于头部分组的manager.setSpanSizeLookup(lookup);//设置之后,一个位置占满一行RV.setLayoutManager(manager);//设RV的布局RV.setAdapter(adapter);adapter.setOnItemClickListener(new RVAdapter.OnItemClickListener() {@Overridepublic void onItemClick(View view, int position) {Toast.makeText(MainActivity.this,position+": "+photos.get(position).getPath(),Toast.LENGTH_LONG).show();}});}}};public void getPhotos() {new Thread() {@Overridepublic void run() {List<Photo> list = new ArrayList<Photo>();List<String> list1 = new ArrayList<String>();//记得初始化super.run();Cursor cursor = resolver.query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, null, null, null, MediaStore.Images.Media.DATE_TAKEN + " desc");if (cursor != null && cursor.moveToFirst()) {do {String path = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA));long date = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATE_TAKEN));long id=cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Images.Media._ID));String name=cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DISPLAY_NAME));String dec=cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.BUCKET_DISPLAY_NAME));Date date1 = new Date(date);String Sdate = format.format(date1);//将long变stringPhoto photo = new Photo(path, Sdate,id,dec,name);//new一个新photoif (!list1.contains(Sdate)) {//判断日期的list是否已经有了这个照片的日期list1.add(Sdate);//这个是将日期添加到日期的list}list.add(photo);//这个是照片的list} while (cursor.moveToNext());cursor.close();Message msg = new Message();msg.what = 1;//这个是一个key,就是一个标记吧Bundle bundle = new Bundle();ArrayList Alist = new ArrayList();//待会以大的list传送数据Alist.add(list);//大的list 加入之前的照片listAlist.add(list1);//大的list加入日期的listbundle.putParcelableArrayList("photos", Alist);//bundle加入大的listmsg.setData(bundle);//msg设置数据,数据是含有大list的bundlehandler.sendMessage(msg);//发送}}}.start();}
}
好的,那现在就已经有数据了,但是适配器呢?看下面,超级麻烦的,我是新手我觉得麻烦咯;
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/><uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
然后我们在java 用contentResolver获取图片,再获取的时候,我们要分别拿到photo的信息和日期的信息,是两个list.
package com.bbg.textalbum;/*** Created by administrator on 2017/10/19.*/public class Photo {private String path;private String date;private long id;private String discr;private String name;public Photo(String path, String date, long id, String discr, String name) {this.path = path;this.date = date;this.id = id;this.discr = discr;this.name = name;}public Photo(String path, String date) {this.path = path;this.date = date;}public long getId() {return id;}public void setId(long id) {this.id = id;}public String getDiscr() {return discr;}public void setDiscr(String discr) {this.discr = discr;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getPath() {return path;}public void setPath(String path) {this.path = path;}public String getDate() {return date;}public void setDate(String date) {this.date = date;}
}
在这里,其实只要路径和日期就够了,你们注意看了,这个日期是string,不是long。在赋值的时候,将 long的日期变成string.下面会说到
<?xml version="1.0" encoding="utf-8"?><android.support.v7.widget.CardViewxmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="wrap_content"android:id="@+id/cardView"android:foregroundTint="@color/cardview_light_background"android:layout_height="wrap_content">
<com.bbg.textalbum.SquareImgandroid:id="@+id/img"android:layout_width="wrap_content"android:layout_height="wrap_content" />
</android.support.v7.widget.CardView>
cardView可以直接包裹里面的东西,如果里面的东西超过一个的话,包裹一个relativelayout,然后再布局。
好,这个imgview是我自己改过的,改成正方形,怎么改掉=的呢?看下面的java继承
package com.bbg.textalbum;import android.content.Context;
import android.util.AttributeSet;
import android.widget.ImageView;/*** Created by administrator on 2017/10/19.*/public class SquareImg extends ImageView {public SquareImg(Context context) {super(context);}public SquareImg(Context context, AttributeSet attrs) {super(context, attrs);}public SquareImg(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);}public SquareImg(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {super(context, attrs, defStyleAttr, defStyleRes);}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {setMeasuredDimension(getDefaultSize(0,widthMeasureSpec),getDefaultSize(0,heightMeasureSpec));int childwid=getMeasuredWidth();heightMeasureSpec=widthMeasureSpec=MeasureSpec.makeMeasureSpec(childwid,MeasureSpec.EXACTLY);super.onMeasure(widthMeasureSpec, heightMeasureSpec);}
}
那么现在我们要做一个photo的model 就是可以设置属性,路径,然后获取的那种.看看:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:orientation="vertical" android:layout_width="wrap_content"android:layout_height="wrap_content">
<TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginStart="10dp"android:id="@+id/headTV"android:text="159.8.5"android:gravity="center"/>
</LinearLayout>
然后是中间imgview:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:id="@+id/activity_main"android:layout_width="match_parent"android:layout_height="match_parent"tools:context="com.bbg.textalbum.MainActivity"><android.support.v7.widget.RecyclerViewandroid:layout_width="match_parent"android:id="@+id/RV"android:layout_height="match_parent"></android.support.v7.widget.RecyclerView>
</RelativeLayout>

一个带时间的相册页面(仿小米相册)相关推荐

  1. 仿小米相册列表实现自定义带快速索引功能的RecyclerView

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 篇章目标要点 一.实现效果 二.设计布局原理 三.关键代码实现 1.浮标随手势移动 2.浮标随列表移动 3.列表随浮标移动而 ...

  2. android 筛选控件_Flutter学习六之实现一个带筛选的列表页面

    上期实现了一个网络轮播图的效果,自定义了一个轮播图组件,继承自StatefulWidget,我们知道Flutter中并没有像Android中activity的概念.页面间的跳转是通过路由从一个全屏组件 ...

  3. HTML精仿ios相册,高仿ios相册地图功能

    本篇文章已授权微信公众号 guolin_blog (郭霖) 独家发布 老规矩先上图, 高仿 ios 相册, 地图算法分析. 下载.gif 百度地图 SDK 新增点聚合功能.通过该功能,可通过缩小地图层 ...

  4. android 仿微信选取相册_Android 仿微信 相册多图选择器

    下载方式 com.sh.zsh.code shphotoselectorlibrary 2.0.9 pom or Gradle: compile 'com.sh.zsh.code:shphotosel ...

  5. android仿小米日历,实现一个仿小米日历控件

    先看效果图: 效果图 根据效果,我们可以看到,要实现该控件,需要具备: 容器以及触摸事件处理 周日历布局以及选择,切换上下周处理 月日历布局以及选择,切换上下月处理 首先说说容器 对于其他使用者来说, ...

  6. 按照日期排序相册库(支持自定义选中图片,视频数量,支持预览,支持拍摄仿小米原生相册)

    写在前面: 此库源于公司项目需求,暂时无法提供maven地址供大家使用,此处会给源码GitHub链接代码部分修改可直接运行. 库链接:https://github.com/XMDstar/TimeAl ...

  7. Java仿小米计算器源码_xiaomi-Calculator 仿照小米的计算器功能,作为一个Android的初学者可以参考,界面简单大方。 259万源代码下载- www.pudn.com...

    文件名称: xiaomi-Calculator下载  收藏√  [ 5  4  3  2  1 ] 开发工具: Java 文件大小: 795 KB 上传时间: 2016-06-13 下载次数: 0 提 ...

  8. 动态改变标题_小米相册更新,新增动态换天/赛博朋克/MIUI12界面等等!

    嗨咯,各位小伙伴们大家晚上好呀,今天为大家介绍一款灰度测试应用"MIUI相册"也就是大家小米手机里面的相册app,为方便解说,以下统称为"相册"更新后打开相册第 ...

  9. 《微信小程序案例5》仿小米Lite小程序分类板块-两个纵向滚动区域独立互不影响

    一.小米Lite分类板块图 二.技术分解 1.布局是分为左右两个纵向滚动区域,使用   <scroll-view> 2.每个小菜单的如图片 标题等内容使用js里面的data来保存 3.如此 ...

最新文章

  1. mysql设置slave复制_mysql5.5建立主从复制(setupmaster-slavereplication)_MySQL
  2. python就业方向有哪些-Python如何零基础入门?就业方向有哪些?
  3. 字符串排序java_利用Java程序将字符串进行排序与拼接
  4. P3203-[HNOI2010]弹飞绵羊【分块】
  5. excel文件被写保护怎么解除_u盘被写保护怎么解除,看完你就知道了
  6. javascript中类的定义和使用{转载}
  7. Mr.J-- HTTP学习笔记(五)-- Web服务器
  8. Django:静态文件staticfiles
  9. mysql数据库中的分组查询语句_详解MySQL中的分组查询与连接查询语句
  10. Mac字体安装的方法?Mac怎么安装新字体?Mac字体安装教程
  11. arcgis软件界面字体太小
  12. 所有电商API接口,淘宝API接口分类,1688API、拼多多API、京东API
  13. UI设计师平时都用什么设计软件工具?
  14. Android反编译工具与反编译步骤及常见问题
  15. C语言简易程序设计————11、打印楼梯与笑脸
  16. 智安网络丨浅谈信息系统终止时如何确保信息资产的安全
  17. jibx进行xml数据绑定的binging.xml配置
  18. 获取android 用到的所有开发包文件
  19. 2021-6-10-今日收获
  20. 地球动力学类毕业论文文献都有哪些?

热门文章

  1. python找工作技能_【行业发展|作为当今找工作的必备技能python,你需要知道哪些】- 环球网校...
  2. java之next()和nextLine()详细分析
  3. @Value 获取配置文件的属性值(SpringBoot)
  4. 工作中时间货币的处理
  5. fMRI研究 | 社交情境下的混合情绪
  6. 计算机系ppt比赛,计算机科学学院成功举办第四届“创意杯”PPT设计大赛
  7. 关于建立老猿Python研学群的公告
  8. N63044-第一周
  9. css显示隐藏的方法
  10. 查看自己电脑是传统BIOS还是UEFI启动