美文网首页
rxAndroid 和ActionMode实现简易文件浏览器

rxAndroid 和ActionMode实现简易文件浏览器

作者: 源来是你啊 | 来源:发表于2017-08-05 19:59 被阅读0次

    ActionMode简介

    Android 3.0以前,我们处理列表的长按事件经常使用Context Menu,Android3.0以后,我们有了新的选择:ActionMode。

    Android开发者应该都熟悉Context Menu了,Context Menu是悬浮在操作项之上的视图,ActionMode是临时占据了ActionBar的位置。

    ActionMode使用步骤

    实现ActionMode.Callbak接口,并处理其生命周期方法即可

    1.public boolean onCreateActionMode(ActionMode mode, Menu menu)

    2.public boolean onPrepareActionMode(ActionMode mode, Menu menu)

    3.public boolean onActionItemClicked(ActionMode mode, MenuItem item)

    4.public void onDestroyActionMode(ActionMode mode)

    重写ActionMode
    
    package com.example.simpleexplore;
    
    import android.app.Activity;
    
    import android.support.v7.view.ActionMode;
    
    import android.view.Menu;
    
    import android.view.MenuItem;
    
    import android.view.Window;
    
    /**
    
    * Created by Administrator on 2017/8/5 0005.
    
    */
    
    public class ActionModeCallback implements ActionMode.Callback{
    
        private Activity activity;
    
        private Window window;
    
        private ActionListener mActionListener;
    
        private ActionMode actionMode;
    
        private boolean isShowing = true;
    
        public ActionModeCallback(Activity activity,ActionListener listener){
    
            this.activity = activity;
    
            this.window = activity.getWindow();
    
            mActionListener = listener;
    
        }
    
        @Override
    
        public boolean onCreateActionMode(ActionMode mode, Menu menu) {
    
            actionMode = mode;
    
            mode.getMenuInflater().inflate(R.menu.menu_item_top,menu);
    
            return true;
    
        }
    
        @Override
    
        public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
    
            return false;
    
        }
    
        @Override
    
        public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
    
            if(item.getItemId() == R.id.menu_item_done){
    
                if(mActionListener != null){
    
                    mActionListener.onFinishAction();
    
                }
    
            }else if(item.getItemId() == R.id.menu_item_delete){
    
              if(mActionListener != null){
    
                  mActionListener.onDeleteAction();
    
              }
    
            }
    
            mode.finish();
    
            return false;
    
        }
    
        @Override
    
        public void onDestroyActionMode(ActionMode mode) {
    
            isShowing = false;
    
            if(mActionListener != null){
    
                mActionListener.onDismissAction();
    
            }
    
        }
    
        /**
    
        * 更新title
    
        * @param count
    
        */
    
        public void updateTitleSelectItemCount(int count){
    
            if(actionMode != null){
    
                actionMode.setTitle(count + (count > 1?"items":"item") + "selected");
    
            }
    
        }
    
        /**
    
        * 退出actionMode
    
        */
    
        public void dismiss(){
    
            if(actionMode != null){
    
                actionMode.finish();
    
            }
    
        }
    
        /**
    
        * ActionmMode 是否开启
    
        */
    
        public boolean isShowing(){
    
            return isShowing;
    
        }
    
        /**
    
        * 设置ActionMode的开启
    
        * @param showing
    
        */
    
        public void setShowing(boolean showing){
    
            isShowing = showing;
    
        }
    
        /**
    
        * actionMode的监听者
    
        */
    
        public interface ActionListener {
    
            void onFinishAction();
    
            void onDismissAction();
    
            void onDeleteAction();
    
        }
    
    }
    
    ```
    
    ###定义文件model
    
    ```
    
    public class FileWraper {
    
        /**
    
        * 文件
    
        */
    
        public File file;
    
        /**
    
        * 是否选中
    
        */
    
        public boolean isSelected = false;
    
        public FileWraper(){
    
        }
    
        public FileWraper(File file){
    
            this.file = file;
    
        }
    
        public FileWraper(File file,boolean isSelected){
    
            this.file = file;
    
            this.isSelected = isSelected;
    
        }
    
    }
    
    ```
    
    ###定义堆栈
    
    存储每次浏览时访问节点的记录
    
    ```
    
    public class FileTreeStack {
    
        //栈顶节点
    
        private Node mTopNode;
    
        //栈内元素个数
    
        private int mSize;
    
        //入栈
    
        public void push(FileShotSnap shotSnap){
    
            Node node = new Node();
    
            node.shotSnap = shotSnap;
    
            node.next = mTopNode;
    
            mTopNode = node;//尾插法
    
            mSize++;
    
        }
    
        //出栈
    
        public FileShotSnap pop(){
    
            if(mTopNode == null) return null;
    
            FileShotSnap shotSnap = mTopNode.shotSnap;
    
            mTopNode = mTopNode.next;
    
            mSize--;
    
            return shotSnap;
    
        }
    
        /**
    
        * 返回堆栈大小
    
        * @return
    
        */
    
        public int size(){
    
            return mSize;
    
        }
    
        //访问节点
    
        class Node {
    
            FileShotSnap shotSnap;
    
            Node next;//指向下一个节点
    
        }
    
        public static class FileShotSnap {
    
            //母文件夹
    
            public File parent;
    
            //此文件夹下的文件
    
            public List files;
    
            //y上的滑动距离
    
            public int ScrollY;
    
        }
    
    }
    
    ```
    
    ###MainActvity
    
    ```
    
    public class FileExploreActivity extends BaseActivity {
    
        @BindView(R.id.recycler_view)
    
        RecyclerView recyclerView;
    
        private int position;
    
        //根目录
    
        private File rootFile = Environment.getExternalStorage();
    
        //文件访问栈
    
        private FileTreeStack mFileStack;
    
        private ActionModeCallback mCallback;
    
    
    //当前状态下的母文件夹
    
    File mCurrentFileParent;
    
    //当前所有文件
    
    List mCurrentFiles;
    
    //选中的文件列表
    
    List mSelectedFiles = new ArrayList<>();
    
    private FileAdapter adapter;
    
        @Override
    
        protected void onCreate(@Nullable Bundle savedInstanceState) {
    
            super.onCreate(savedInstanceState);
    
            setContentView(R.layout.activity_file_explore);
    
            ButterKnife.bind(this);
    
            initView();
    
        }
    
        //回退
    
        @Override
    
        public void onBackPressed() {
    
            if(mFileStack.size() == 0){
    
                super.onBackPressed();
    
            }else {
    
                restoreTreeStack(mFileStack.pop());
    
            }
    
        }
    
        private void initView() {
    
            adapter = new FileAdapter(this,null);
    
            adapter.setOnClickListener(new ListAdapter.OnItemClickListener() {
    
                @Override
    
                public void onClick(View itemView, int position) {
    
                    //获取选中文件
    
                    FileWraper item = adapter.getItem(position);
    
                    if(item.file.isDirectory()){
    
                        //如果是在选择状态
    
                        if(isInModeAction()){
    
                            //选中或取消文件
    
                            updateSelectFiles(item,position);
    
                        }else {
    
                            //进入文件夹 首先堆栈
    
                            storeTreeStack();
    
                            //加载文件
    
                            loadFiles(item.file);
    
                            //刷新标题
    
                            updateTitle();
    
                        }
    
                    }
    
                }
    
            });
    
            adapter.setOnItemLongClickListener(new ListAdapter.OnItemLongClickListener() {
    
                @Override
    
                public void onLongClick(View itemView, int position) {
    
                    FileWraper item = adapter.getItem(position);
    
                    //长按进入选则文件状态
    
                    if(item.file.isDirectory()){
    
                        if(mCallback == null || !mCallback.isShowing()){
    
                            startActionMode();
    
                        }
    
                        //选中或取消文件
    
                        updateSelectFiles(item,position);
    
                    }
    
                }
    
            });
    
            recyclerView.setAdapter(adapter);
    
            //加载音乐
    
            loadFiles(rootFile);
    
        }
    
        private void startActionMode() {
    
            if(mCallback == null){
    
                mCallback = new ActionModeCallback(this, new ActionModeCallback.ActionListener() {
    
                    @Override
    
                    public void onFinishAction() {
    
                        //选中
    
                        Toast.makeText(FileExploreActivity.this, "选中所有", Toast.LENGTH_SHORT).show();
    
                        if(mSelectedFiles.size() > 0){
    
                            //操作
    
                        } else {
    
                            mCallback.dismiss();
    
                        }
    
                    }
    
                    @Override
    
                    public void onDismissAction() {
    
                        //取消
    
                        Toast.makeText(FileExploreActivity.this, "取消续重", Toast.LENGTH_SHORT).show();
    
                        clearSelections();
    
                    }
    
                    @Override
    
                    public void onDeleteAction() {
    
                        //删除
    
                        Toast.makeText(FileExploreActivity.this, "删除选中文件", Toast.LENGTH_SHORT).show();
    
                    }
    
                });
    
            }
    
            startSupportActionMode(mCallback);//开启ActionMode ActionBar被替代,进入选择文件状态
    
            mCallback.setShowing(true);
    
        }
    
        //清楚当前所有选中文件
    
        private void clearSelections() {
    
            boolean needClear = mSelectedFiles.size() > 0;
    
            mSelectedFiles.clear();
    
            if(needClear){
    
                adapter.clearSelections();
    
                adapter.notifyDataSetChanged();
    
            }
    
        }
    
        //更新选中或取消
    
        private void updateSelectFiles(FileWraper fileWraper,int position) {
    
            if(fileWraper.file.isFile()) return;
    
            //更新文件选中状态
    
            fileWraper.isSelected = !fileWraper.isSelected;
    
            //添加或取消选中
    
            if(fileWraper.isSelected){
    
                mSelectedFiles.add(fileWraper.file);
    
            }else {
    
                if(mSelectedFiles.indexOf(fileWraper.file) != -1){
    
                    mSelectedFiles.remove(fileWraper.file);
    
                }
    
            }
    
            //更新UI
    
            adapter.notifyItemChanged(position);
    
            //更新选中UI
    
            mCallback.updateTitleSelectItemCount(mSelectedFiles.size());
    
        }
    
        /**
    
        * 更新标题
    
        */
    
        private void updateTitle() {
    
            getSupportActionBar().setTitle(mCurrentFileParent.getName());
    
        }
    
        /**
    
        * 存储节点
    
        */
    
        private void storeTreeStack() {
    
            //把当前节点加入树栈中
    
            FileTreeStack.FileShotSnap shotSnap = new FileTreeStack.FileShotSnap();
    
            shotSnap.parent = mCurrentFileParent;
    
            shotSnap.files = mCurrentFiles;
    
            mFileStack.push(shotSnap);
    
        }
    
        /**
    
        * 取出节点
    
        * @param top
    
        */
    
        private void restoreTreeStack(FileTreeStack.FileShotSnap top) {
    
            mCurrentFileParent = top.parent;
    
            mCurrentFiles = top.files;
    
            int scrollOffsetY = top.ScrollY;
    
            adapter.setDate(mCurrentFiles);
    
            adapter.notifyDataSetChanged();
    
            recyclerView.scrollTo(0,scrollOffsetY);
    
        }
    
        /**
    
        * 判断是否在选择模式下
    
        * @return
    
        */
    
        private boolean isInModeAction() {
    
            //如果第一个条件不符合 就直接返回 不会看第二个
    
            return mCallback != null && mCallback.isShowing();
    
        }
    
        /**
    
        * 加载文件 并更新UI
    
        */
    
        private void loadFiles(File parent) {
    
            //rxAndroid 加载文件
    
            Subscription subscription = Observable.just(parent)
    
                    .flatMap(new Func1>>() {
    
                        @Override
    
                        public Observable> call(File parent) {
    
                            List files = Arrays.asList(parent.listFiles(SystemFileFilter.DEFAULT_INSTANCE));
    
                            Collections.sort(files, new Comparator() {
    
                                @Override
    
                                public int compare(File f1, File f2) {
    
                                    if (f1.isDirectory() && f2.isFile()) {
    
                                        return -1;
    
                                    }
    
                                    if (f2.isDirectory() && f1.isFile()) {
    
                                        return 1;
    
                                    }
    
                                    return f1.getName().compareToIgnoreCase(f2.getName());
    
                                }
    
                            });
    
                            // 创建文件列表
    
                            List fileWrappers = new ArrayList<>(files.size());
    
                            for (File file : files) {
    
                                fileWrappers.add(new FileWrapper(file));
    
                            }
    
                            return Observable.just(fileWrappers);
    
                        }
    
                    })
    
                    .subscribeOn(Schedulers.io())
    
                    .observeOn(AndroidSchedulers.mainThread())
    
                    .subscribe(new Subscriber>() {
    
                        @Override
    
                        public void onCompleted() {
    
    
    }
    
                        @Override
    
                        public void onError(Throwable throwable) {
    
                            Log.e(TAG, "onError: ", throwable);
    
                        }
    
                        @Override
    
                        public void onNext(List files) {
    
                            mCurrentFiles = files;
    
                            onFileLoaded(parent);
    
                        }
    
                    });
    
            addSubscription(subscription);
    
        }
    
        private void onFileLoaded(File parent) {
    
            mCurrentFileParent = parent;
    
            //刷新数据
    
            adapter.setDate(mCurrentFiles);
    
            adapter.notifyDataSetChanged();
    
            //进入文件夹的时候滑动到第一个位置就可以
    
            recyclerView.scrollTo(0,0);
    
        }
    
    }
    ```
    
    适配器及数据的绑定就省略了

    相关文章

      网友评论

          本文标题:rxAndroid 和ActionMode实现简易文件浏览器

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