2018-11-26

好看的皮囊千篇一律,有趣的灵魂100来斤。

RecyclerView按时间加载一天中的相似图片

android小白一枚,最近公司让做相似图片处理的demo,经过一个多月的查资料、请教,终于实现了功能,本人就开发中遇到的问题,并且把认为对大家有帮助的地方写下来,希望对大家有所帮助。

  1. 相册中的图片按照日期排列
    这是开发中遇到的第一个问题,效果如图所示


    image.png

    当前android比较流行的Rxjava可以轻松解决这个问题,代码如下:

    // 重要:获取数据
    private void initData() {
        List<File> fileList = TaHelper.getInstance().getSrcFiles();
        Observable.fromIterable(fileList)
                .flatMapIterable(new Function<File, Iterable<File>>() {
                    @Override
                    public Iterable<File> apply(File file) throws Exception {
                        return Arrays.asList(file.listFiles());
                    }
                })
                .filter(new Predicate<File>() {
                    @Override
                    public boolean test(File it) throws Exception {
                        return it.getName().endsWith(".jpg") || it.getName().endsWith(".mp4");
                    }
                })
                .map(new Function<File, AlbumBean>() {
                    @Override
                    public AlbumBean apply(File file) throws Exception {
                        Date fileDate = FileUtils.parseDate(file);
                        cal1.setTime(fileDate);
                        // 将时分秒,毫秒域清零
                        cal1.set(Calendar.HOUR_OF_DAY, 0);
                        cal1.set(Calendar.MINUTE, 0);
                        cal1.set(Calendar.SECOND, 0);
                        cal1.set(Calendar.MILLISECOND, 0);
                        AlbumBean albumBean = new AlbumBean();
                        albumBean.date = cal1.getTime().getTime();
                        albumBean.path = file.getAbsolutePath();
                        return albumBean;
                    }
                })
                .collect(new Callable<List<TimeBean>>() {
                    @Override
                    public List<TimeBean> call() throws Exception {
                        return new ArrayList<>();
                    }
                }, new BiConsumer<List<TimeBean>, AlbumBean>() {
                    @Override
                    public void accept(List<TimeBean> timeBeans, AlbumBean albumBean) throws Exception {
                        TimeBean timeBean = new TimeBean();
                        timeBean.setDate(albumBean.date);
                        int index = timeBeans.indexOf(timeBean);
                        if (index >= 0) {
                            timeBeans.get(index).itemList.add(albumBean);
                        } else {
                            timeBean.itemList.add(albumBean);
                            timeBeans.add(timeBean);
                        }
                    }
                })
                .subscribeOn(Schedulers.io())
                .observeOn(Schedulers.io())
                .subscribe(new BiConsumer<List<TimeBean>, Throwable>() {
                    @Override
                    public void accept(List<TimeBean> timeBeans, Throwable throwable) throws Exception {
                        mData.addAll(timeBeans);
                        sortList();
    
                        //按时间处理后找到所有相似的图片
                        addsimilarPicture();
                        searchMQPic();
                        findMaxQua();
                    }
                });
    } 
    
    
  2. RecyclerView中每个item怎么加载多张图片
    这个是困扰时间最长的问题,我们知道Recyclerview可以加载不同的ViewType,但是我们知道手机每天拍照的图片数量是不能确定的,每一天可能会有1~N张图片,设置多个item也是麻烦且不实用的一件事。经过查询和请教,最后在TimeAlbum项目中找到了解决方法,现在分享给大家。
    TimeAlbum利用的是代理adapter方法,就是在RecyclerView 的adapter中运用一个代理Adapter,在代理的Adapte中在设置一个RecyclerView来横向加载某一天的所有图片。不得不说,作为一个android小白,这个思路以前真的没有听过,只是会简单的使用RecyclerView来相同格式的item
    RecyclerView的adapter如下:

class TimeAdapter extends IbbListDelegateAdapter<List<TimeBean>> {

    private TimeDelegate timeDelegate;
    public TimeAdapter(List<TimeBean> data) {
        addDelegate();
        setItems(data);
    }

    private void addDelegate() {
        timeDelegate = new TimeDelegate();
        delegatesManager.setFallbackDelegate(timeDelegate);
    }

}
 class TimeDelegate extends AbsFallbackAdapterDelegate<List<TimeBean>> {


    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent) {
        return new TimeDelegateHolder(new TaTimeView(parent.getContext()));
    }

    @Override
    public void onBindViewHolder(@NonNull List<TimeBean> items, int position, @NonNull RecyclerView.ViewHolder holder, @NonNull List<Object> payloads) {
        super.onBindViewHolder(items, position, holder, payloads);
        TimeDelegateHolder albumHolder = (TimeDelegateHolder) holder;
        albumHolder.timeView.notify(items.get(position));
    }

    static class TimeDelegateHolder extends RecyclerView.ViewHolder {
        TaTimeView timeView;

        public TimeDelegateHolder(TaTimeView itemView) {
            super(itemView);
            timeView = itemView;
        }
    }
}

其中TaTimeView是一个自定义布局

class TaTimeView extends LinearLayout {
    public TaTimeView(Context context) {
        this(context, null);
    }

    public TaTimeView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        initView();
    }
    private ITaDecoration decoration;
    private AlbumAdapter adapter;
    private List<AlbumBean> data = new ArrayList<>();

    private void initView() {
        setOrientation(VERTICAL);

        decoration = TaHelper.getInstance().getDecoration();
        if (decoration == null) {
            decoration = new TaDecoration(getContext());
        }
        LayoutParams params = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        if (decoration != null) {
            addView(decoration.buildView(), params);
        }
        RecyclerView rcView = new RecyclerView(getContext());
        params = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 0);
        params.weight = 1;

        addView(rcView, params);

        adapter = new AlbumAdapter(data);
        GridLayoutManager gridLayoutManager = new GridLayoutManager(getContext(), 4);
        rcView.setLayoutManager(gridLayoutManager);
        rcView.setAdapter(adapter);
        rcView.addItemDecoration(new GridDecoration(4, 5, true));
    }

    public void notify(TimeBean timeBean) {
        decoration.showDate(timeBean.date);
        int size = timeBean.itemList.size();
        decoration.showNum(size);
        data.clear();
        data.addAll(timeBean.itemList);
        adapter.notifyDataSetChanged();
    }
} 

后面的相似图片的判定以及相似图片中怎么寻找质量最好的图片是leader给的接口,本人只是使用了一下,这里就不作介绍了。上面是核心代码,结果如图所示:


image.png

总结:第一次对RecyclerView有了这么深刻的认识,对于一个小白来说,项目才是提升的最短捷径。还有,没有什么是一段代码不能解决的,如果有,那就两段。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 135,079评论 19 139
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 173,860评论 25 709
  • 回到姥姥家之后,我心里也真是放松了,动不动就10点多睡着,夜里起都起不来,白天腾腾不让我看手机,这日记也被迫中断了...
    文娟_f阅读 317评论 0 0
  • 落叶从远方落下 掉落在了湖面上 泛起了波澜 落叶从落寞人面前掉下 掉落在土地上 但为何那人的心 也在波澜 和那落叶一样呢
    追萝卜的男孩阅读 160评论 2 2
  • 引言:关于财富这个话题,很容易引起阶级纷争,首先声明,大家都是底层的屁民,何苦为难自己人?前段时间跟公司几个人聊天...
    7a0a64e35bf0阅读 799评论 0 0