界面无小事(三):用RecyclerView + Toolbar做个文件选择器

简介: 界面无小事(一): RecyclerView+CardView了解一下界面无小事(二): 让RecyclerView展示更多不同视图界面无小事(三):用RecyclerView + Toolbar做个文件选择器界面无小事(四):来写个滚动选择器吧!界面...

界面无小事(一): RecyclerView+CardView了解一下
界面无小事(二): 让RecyclerView展示更多不同视图
界面无小事(三):用RecyclerView + Toolbar做个文件选择器
界面无小事(四):来写个滚动选择器吧!
界面无小事(五):自定义TextView
界面无小事(六):来做个好看得侧拉菜单!

目录

  • 前言
  • 最终效果演示
  • 布局文件
  • RecyclerView适配器
  • Toolbar的使用
  • 填充RecyclerView条目
  • 悬浮按钮
  • 最后

前言

github传送门

在之前两期也是说了很多RecyclerView的使用, 这期打算来个实操性质的. 用RecyclerView制作一个文件管理器, 并且可以进行文件的多选, 应该是蛮实用的.


最终效果展示

最终效果展示

布局文件

还是先从最简单的布局文件开始看. 可以看到, 三个字符串和一个图标. 图标依据是文件夹或者文件进行显示, 当然了, 之后会做得更细, 例如依据文件类型进行图标变换, mp3就显示为音乐, mp4就是显示视频. 上方字符串是文件或者文件夹名称. 下方字符串的话, 见下面的展示图, 依据类型进行显示:

布局文件
文件夹
文件

RecyclerView适配器

具体的使用在之前文章里面也细说过了. 这里来看两个关键函数. 我们的填充内容主要是当前目录下全部的files, 存放在ArrayList当中. 每当用户展开新的一层, 就会调用refreshData函数进行刷新. 如果是单选或者是多选, 就会调用refreshSelect函数进行对应的处理. 整体也比较简单, 不多赘述.

public void refreshData(ArrayList<File> files) {
    mFiles = files;
    this.notifyDataSetChanged();
}

public int refreshSelect(int pos) {
    if (pos < 0) {
        if (pos == -1) {
            // 全不选
            mSelectList.clear();
        } else if (pos == -2) {
            // 全选
            for (int i = 0; i < mFiles.size(); i++) {
                if (mFiles.get(i).isFile() && !mSelectList.contains((Integer) i)) {
                    mSelectList.add((Integer) i);
                }
            }
        }
    } else {
        // 单选
        if (!mSelectList.contains((Integer) pos)) {
            mSelectList.add((Integer) pos);
        } else {
            mSelectList.remove((Integer) pos);
        }
    }
    this.notifyDataSetChanged();

    return mSelectList.size();
}

Toolbar的使用

Toolbar是个好东西. 你可以看看官方文档. 反正我自从会用了之后, 几乎没有不用的时候. Toolbar使用细节的文章就太多了, 我也不多说了. 但是app:layout_scrollFlags="scroll|enterAlways|snap"这行还是很重要的, 作用就是让Toolbar在上拉RecyclerView的时候隐藏, 下拉的时候显示. 来张效果图:

<android.support.v7.widget.Toolbar
    android:id="@+id/toolbar"
    android:layout_width="match_parent"
    android:layout_height="?attr/actionBarSize"
    android:background="?attr/colorPrimary"
    app:layout_scrollFlags="scroll|enterAlways|snap"
    app:popupTheme="@style/AppTheme.PopupOverlay" />
Toolbar隐藏和显示

然后使用setTitle函数可以修改Toolbar中标题内容, 关于变化内容的字符串使用可以看我之前的文章.

getSupportActionBar().setTitle(
        String.format(getResources().getString(
                R.string.selected_str), mSelectCount));

如果你要在Toolbar上添加按钮:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <item
        android:id="@+id/all"
        android:icon="@drawable/all"
        android:orderInCategory="100"
        android:title="@string/all"
        app:showAsAction="ifRoom" />
</menu>
@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}

添加对应按钮的点击监听的话:

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case android.R.id.home:
            break;
        case R.id.all:
            break;
    }
    return true;
}

android.R.id.home是系统自带的一个返回按钮, 和ios的返回类似, 你懂的~. 当然了, 一般是不显示出来的, 你需要如下代码:

ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
    actionBar.setDisplayHomeAsUpEnabled(true);
}

填充RecyclerView条目

既然要使用RecyclerView, 条目填充就很重要了. 思路就是使用Stack进行当前路径存储, 后续每点击一个文件夹就添加一层, 每返回一层, 就弹出一个.

// 获取sdcard目录
mSdcardPath = Environment.getExternalStorageDirectory().toString();

mSelectPath = new ArrayList<>();

mCurPathStack = new Stack<>();

mCurFileList = new ArrayList<>();

File[] files = Environment.getExternalStorageDirectory().listFiles();
if (files != null) {
    for (File f : files) {
        mCurFileList.add(f);
    }
}

mCurPathStack.push(mSdcardPath);

具体细节肯定要查看下源码的, 这里看到mCurPathStack就是处理路径的. mCurFileList用来存储当前展开文件夹的内容. mSelectPath用来存储勾选的文件.

mFMAdapter.setOnItemClickListener(new FMAdapter.OnItemClickListener() {
    @Override
    public void onItemClick(View view, int position) {
        final File file = mCurFileList.get(position);
        if (file.isDirectory()) {
            // 是文件夹
            mCurPathStack.push("/" + file.getName());

            // 根据路径刷新数据
            refreshData(getCurPath());
        } else {
            // 是文件
            mSelectCount = mFMAdapter.refreshSelect(position);
            getSupportActionBar()
                    .setTitle(String.format(getResources()
                            .getString(R.string.selected_str), mSelectCount));

            // 将选中的文件加入文件路径数组
            if (!mSelectPath.contains(file.getAbsolutePath())) {
                mSelectPath.add(file.getAbsolutePath());
            } else {
                mSelectPath.remove(file.getAbsolutePath());
            }
        }
    }

    @Override
    public void onItemLongClick(View view, int position) {

    }
});

然后对每一个条目添加点击事件, 长按事件的话, 大家可以按照自己的喜欢处理, 这里不多写了. 主要是单击事件. 如果是点击文件夹, 就将点击文件夹加入栈, 然后刷新视图. 如果是文件, 就是单选文件, 需要将位置传给适配器函数refreshSelect, 这个之前也说过了. 一个比较重要的就是, 在当前的mSelectPath中需要进行确认, 如果已经存在就删除这个选择, 如果不存在, 就选择这个文件, 这个逻辑也是很好理解的.


悬浮按钮

这个也是非常常用的一个视图类. 如果你点击了悬浮按钮, 就会弹出确认窗口, 关于弹窗, 可以查看我之前的文章. 这里就上一张效果图了.

悬浮按钮
点击演示

最后

好了, 就写到这里了, 喜欢记得点赞或者关注我哦, 有意见或者建议评论区见哦. 然后点击这里查看源码, 听说github要被巨硬收购, 瑟瑟发抖.


目录
相关文章
|
弹性计算 图形学
Unity之浅析 Entity Component System (ECS)
首先放出ECS官方文档 随着目前游戏对CPU性能要求的不断提升,单核高频的CPU对我们的帮助越来越有限。所以ECS(一种面向数据编程)多核心工作的方式也是大势所趋。
4045 0
|
17天前
|
数据可视化 JavaScript 前端开发
Three.js:开启Web 3D世界的魔法钥匙
Three.js是基于WebGL的JavaScript 3D库,简化了网页中3D图形的创建与渲染。它提供场景、相机、光照、动画等完整架构,支持丰富几何体、材质及高级特效,助力开发者轻松实现交互式3D可视化。
136 6
|
2月前
|
存储 缓存 数据挖掘
阿里云轻量应用服务器“CPU优化型”配置介绍、费用价格说明
阿里云轻量应用服务器推出CPU优化型,提供更强计算性能,2核4GB起,最高16核64GB,全系支持200Mbps带宽。适用于企业级应用、数据库、游戏服务器等高算力场景,保障稳定高效运行。
386 1
|
Go
Golang语言之管道channel快速入门篇
这篇文章是关于Go语言中管道(channel)的快速入门教程,涵盖了管道的基本使用、有缓冲和无缓冲管道的区别、管道的关闭、遍历、协程和管道的协同工作、单向通道的使用以及select多路复用的详细案例和解释。
629 4
Golang语言之管道channel快速入门篇
|
机器学习/深度学习 PyTorch 算法框架/工具
【从零开始学习深度学习】31. 卷积神经网络之残差网络(ResNet)介绍及其Pytorch实现
【从零开始学习深度学习】31. 卷积神经网络之残差网络(ResNet)介绍及其Pytorch实现
|
9月前
|
图形学
unity噪声消融效果Shader实现
在 Unity 中实现噪声消融效果,利用噪声纹理和透明度裁剪技术。噪声纹理(如 Perlin 噪声)为物体表面提供随机参考值,透明度裁剪通过设置阈值控制显示与消失。具体步骤包括引入噪声纹理、设置阈值和边缘颜色,使用自定义着色器代码实现物体部分消失的视觉效果。通过调整材质球和噪声贴图,可优化最终呈现。
|
移动开发 数据可视化 HTML5
Twaver-HTML5基础学习(40)表格可视化视图组件(Table)
本文介绍了如何在Twaver-HTML5中使用表格可视化视图组件(Table),包括创建表格、定义列对象、实现数据绑定和排序,以及处理表格事件和获取表格数据的方法。
264 2
|
缓存 监控 Android开发
Android中的RecyclerView优化策略与实践
【4月更文挑战第5天】本文深入探讨了在安卓开发中,如何针对RecyclerView进行性能优化。通过分析常见的滚动卡顿、内存泄漏等问题,提出了相应的解决方案,并结合实际案例展示了优化过程。文章不仅涵盖了使用RecyclerView时应当遵循的最佳实践,还提供了高级技巧以供进阶开发者参考,旨在帮助读者构建更加流畅和高效的列表显示。
|
存储 JavaScript 算法
|
缓存 监控 中间件
构建高效的Go语言Web服务器:基于Fiber框架的性能优化实践
在追求极致性能的Web开发领域,Go语言(Golang)凭借其高效的并发处理能力、垃圾回收机制及简洁的语法赢得了广泛的青睐。本文不同于传统的性能优化教程,将深入剖析如何在Go语言环境下,利用Fiber这一高性能Web框架,通过精细化配置、并发策略调整及代码层面的微优化,构建出既快速又稳定的Web服务器。通过实际案例与性能测试数据对比,揭示一系列非直觉但极为有效的优化技巧,助力开发者在快节奏的互联网环境中抢占先机。