美文网首页Android开发Android技术知识Android开发经验谈
界面无小事(三):用RecyclerView + Toolbar

界面无小事(三):用RecyclerView + Toolbar

作者: sean_depp | 来源:发表于2018-06-04 13:52 被阅读61次

    界面无小事(一): RecyclerView+CardView了解一下
    界面无小事(二): 让RecyclerView展示更多不同视图

    目录

    • 前言
    • 最终效果演示
    • 布局文件
    • 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要被巨硬收购, 瑟瑟发抖.


    相关文章

      网友评论

        本文标题:界面无小事(三):用RecyclerView + Toolbar

        本文链接:https://www.haomeiwen.com/subject/udwesftx.html