界面无小事(三):用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" />
复制代码

然后使用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要被巨硬收购, 瑟瑟发抖.


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值