Skip to content

Latest commit

 

History

History
492 lines (384 loc) · 22.2 KB

README_EN.md

File metadata and controls

492 lines (384 loc) · 22.2 KB

Banner

mlhfileselector

Maven CentraljitpackAPI: 19-33 (shields.io)license: Apache-2.0 (shields.io)Starbilibili: 玲莫利 (shields.io)CSDN: molihuan (shields.io)

(Provide file or path selection, automatically apply for storage permission, support Android 4.4 to 13, support Android/data and Android/obb directory access, support custom UI,Support SD card.The Keyword:file selector operator android/data android 11 android 13)

Characteristics

  • Automatically request storage permissions
  • Android 4.4 ~ 13
  • Android/data and Android/obb directory access and manipulation
  • SD Card
  • Highly customizable UI
  • Internationalization
  • Search function

Language(语言)

Preface

Can you give the project a Star before starting? Thank you very much, your support is the only thing that keeps me going. Welcome Star and Issues!

Project Address:

Demo:

Android version:Android 13

Download Links:Experience App

pathSelectorDemo.gif

I. Quick start

Step 1: Add the repository:

  • If your project Gradle configuration is under 7.0, you need to add to the build.gradle file
allprojects {
    repositories {
        ...
        mavenCentral()
        maven { url 'https://jitpack.io' }
    }
}
  • If your Gradle configuration is 7.0 and above, you need to add to your settings.gradle file
dependencyResolutionManagement {
    repositories {
    	...
        mavenCentral()
        maven { url 'https://jitpack.io' }
    }
}

Step 2: Add the remote dependency:

  • After configuring the remote repository, add the remote dependency to the build.gradle file under the project app module
  • Latest Release:Maven Central
dependencies {
    ...
    // Please replace "version" with a specific version number, e.g. 1.1.2
    implementation 'io.github.molihuan:pathselector:version'
}

Step 3: Demonstration of basic usage:

//Permissions will be requested automatically if you don't have them
PathSelector.build(this, MConstants.BUILD_DIALOG)//Dialog build mode
        .setMorePopupItemListeners(
                new CommonItemListener("OK") {
                    @Override
                    public boolean onClick(View v, List<FileBean> selectedFiles, String currentPath, BasePathSelectFragment pathSelectFragment) {

                        StringBuilder builder = new StringBuilder();
                        builder.append("you selected:\n");
                        for (FileBean fileBean : selectedFiles) {
                            builder.append(fileBean.getPath() + "\n");
                        }
                        Mtools.toast(builder.toString());

                        return false;
                    }
                }
        )
        .show();//Start building

II. Basic settings

Turn on debug mode

//Turn on debug mode, please turn off production environment
PathSelectorConfig.setDebug(true);
//or use PathSelector.setDebug(true);

1、Activity build mode:

//Activity build mode
PathSelectFragment selector = PathSelector.build(this, MConstants.BUILD_ACTIVITY)
        .setRequestCode(635)
        .setMorePopupItemListeners(
                new CommonItemListener("OK") {
                    @Override
                    public boolean onClick(View v, List<FileBean> selectedFiles, String currentPath, BasePathSelectFragment pathSelectFragment) {

                        StringBuilder builder = new StringBuilder();
                        builder.append("you selected:\n");
                        for (FileBean fileBean : selectedFiles) {
                            builder.append(fileBean.getPath() + "\n");
                        }
                        Mtools.toast(builder.toString());

                        return false;
                    }
                }
        )
        .show();

2、Fragment build mode:

Step 1: Use FrameLayout placeholders in the xml of the layout file you need to display
<FrameLayout
    android:id="@+id/fragment_select_show_area"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />
Step 2: Write the code
//Get the PathSelectFragment instance and then handle the back button click event in onBackPressed
PathSelectFragment selector = PathSelector.build(this, MConstants.BUILD_FRAGMENT)
        .setFrameLayoutId(R.id.fragment_select_show_area)//Load position, ID of FrameLayout
        .setMorePopupItemListeners(
                new CommonItemListener("OK") {
                    @Override
                    public boolean onClick(View v, List<FileBean> selectedFiles, String currentPath, BasePathSelectFragment pathSelectFragment) {

                        StringBuilder builder = new StringBuilder();
                        builder.append("you selected:\n");
                        for (FileBean fileBean : selectedFiles) {
                            builder.append(fileBean.getPath() + "\n");
                        }
                        
                        Mtools.toast(builder.toString());
                        return false;
                    }
                }
        )
        .show();
Step 3: Override the onBackPressed() method to let the path selector take precedence over the return button click event
Very important!!!
Very important!!!
Very important!!!
Important things are to be repeated for 3 times
@Override
public void onBackPressed() {

    //Let PathSelectFragment handle the return button click event first
    if (selector != null && selector.onBackPressed()) {
        return;
    }
    ......
    super.onBackPressed();
}

3、Dialog build mode & common settings.

//Get the PathSelectFragment instance and then handle the back button click event in onBackPressed
PathSelectFragment selector = PathSelector.build(this, MConstants.BUILD_DIALOG)
        //.setBuildType(MConstants.BUILD_DIALOG)//Already set in the build
        //.setContext(this)//Already set in the build
        .setRootPath("/storage/emulated/0/")//Initial path
        .setShowSelectStorageBtn(true)//Whether to display internal storage selection button
        .setShowTitlebarFragment(true)//Whether to display the title bar
        .setShowTabbarFragment(true)//Whether to show breadcrumbs
        .setAlwaysShowHandleFragment(true)//Whether to always show the long press pop-up option
        .setShowFileTypes("", "mp3", "mp4")//Show only files with (no suffix) or (mp3 suffix) or (mp4 suffix)
        .setSelectFileTypes("", "mp3")//Only files with (no suffix) or (mp3 suffix) can be selected
        .setMaxCount(3)//You can select up to 3 files. The default is - 1 unlimited
        .setRadio()//Single choice
        .setSortType(MConstants.SORT_NAME_ASC)//Sort by name
        .setTitlebarMainTitle(new FontBean("My Selector"))//Set the title bar main title, you can also set the font size, color, etc.
        .setTitlebarBG(Color.GREEN)//Set the title bar background color
        .setFileItemListener(//Set the callback for the file item click (it will be called back only if it is a file, but not if it is a folder)
                new FileItemListener() {
                    @Override
                    public boolean onClick(View v, FileBean file, String currentPath, BasePathSelectFragment pathSelectFragment) {
                        Mtools.toast("you clicked path:\n" + file.getPath());
                        return false;
                    }
                }
        )
        .setMorePopupItemListeners(//Set the top right option callback
                new CommonItemListener("SelectAll") {
                    @Override
                    public boolean onClick(View v, List<FileBean> selectedFiles, String currentPath, BasePathSelectFragment pathSelectFragment) {
                        pathSelectFragment.selectAllFile(true);
                        return false;
                    }
                },
                new CommonItemListener("DeselectAll") {
                    @Override
                    public boolean onClick(View v, List<FileBean> selectedFiles, String currentPath, BasePathSelectFragment pathSelectFragment) {
                        pathSelectFragment.selectAllFile(false);
                        return false;
                    }
                }
        )
        .setHandleItemListeners(//Set long press pop-up option callback
                new CommonItemListener("OK") {
                    @Override
                    public boolean onClick(View v, List<FileBean> selectedFiles, String currentPath, BasePathSelectFragment pathSelectFragment) {
                        StringBuilder builder = new StringBuilder();
                        builder.append("you selected:\n");
                        for (FileBean fileBean : selectedFiles) {
                            builder.append(fileBean.getPath() + "\n");
                        }
                        Mtools.toast(builder.toString());
                        return false;
                    }
                },
                new CommonItemListener("cancel") {
                    @Override
                    public boolean onClick(View v, List<FileBean> selectedFiles, String currentPath, BasePathSelectFragment pathSelectFragment) {
                        pathSelectFragment.openCloseMultipleMode(false);
                        return false;
                    }
                }
        )
        .show();

III. Advanced settings (custom UI)

UI:

UiLayout.png

1、custom option style (HandleItem as an example)

Way 1:Set the style by FontBean
PathSelectFragment selector = PathSelector.build(this, MConstants.BUILD_DIALOG)
        .setHandleItemListeners(//Set long press pop-up option callback
                //FontBean can set the text, the size of the word, the color of the word, and the icon to the left of the word
    			//R.drawable.ic_test_mlh is your own image resource id
                new CommonItemListener(new FontBean("OK", 18, Color.RED, R.drawable.ic_test_mlh)) {
                    @Override
                    public boolean onClick(View v, List<FileBean> selectedFiles, String currentPath, BasePathSelectFragment pathSelectFragment) {
                        Mtools.toast("You Click");
                        return false;
                    }
                }
        )
        .show();
What? This way is not enough for you, then try way 2
Way 2: Override CommonItemListener's setViewStyle method to customize the style
PathSelectFragment selector = PathSelector.build(this, MConstants.BUILD_DIALOG)
        .setHandleItemListeners(
                //Override CommonItemListener's setViewStyle method to customize the style
                new CommonItemListener("OK") {
                    @Override
                    public boolean setViewStyle(RelativeLayout container, ImageView leftImg, TextView textView) {
                        textView.setTextSize(18);
                        textView.setTextColor(Color.RED);
                        //Icons are not displayed by default
                        leftImg.setVisibility(View.VISIBLE);
                        leftImg.setImageResource(R.drawable.ic_test_mlh);
                        leftImg.getLayoutParams().width = 90;
                        leftImg.getLayoutParams().height = 90;
                        return true;
                    }

                    @Override
                    public boolean onClick(View v, List<FileBean> selectedFiles, String currentPath, BasePathSelectFragment pathSelectFragment) {
                        Mtools.toast("You Click");
                        return false;
                    }
                }
        )
        .show();

What? What? This way is not enough for you, then you write the UI it to help you add, try the highly customizable UI

2、Highly customizable UI (using Titlebar as an example):

Step 1: Create a new layout file, such as:fragment_custom_titlebar.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="horizontal">

    <Button
        android:id="@+id/my_btn1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="btn1" />

    <Button
        android:id="@+id/my_btn2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="selectAll" />
    
</LinearLayout>
Step 2: Create a new class such as:CustomTitlebarFragment.class so that it extends AbstractTitlebarFragment and associates the layout file in step 1
public class CustomTitlebarFragment extends AbstractTitlebarFragment {
    private Button btn1;
    private Button btn2;
    
    @Override
    public int setFragmentViewId() {
        return R.layout.fragment_custom_titlebar;
    }

    @Override
    public void getComponents(View view) {
        btn1 = view.findViewById(R.id.my_btn1);
        btn2 = view.findViewById(R.id.my_btn2);
        btn1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Mtools.toast("The current path is:\n" + psf.getCurrentPath());
            }
        });
        btn2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                psf.selectAllFile(true);
            }
        });
    }
}
Step 3: Write the code
//Get the PathSelectFragment instance and then handle the back button click event in onBackPressed
PathSelectFragment selector = PathSelector.build(this, MConstants.BUILD_DIALOG)
        .setTitlebarFragment(new CustomTitlebarFragment())
        .show();

IV.Interface and methods (try to see the source code, are written comments, lazy to write the document)

IConfigDataBuilder
Method Role Comment
setFrameLayoutId(int id) Set load location FrameLayout ID Must be set when the build mode is MConstants.BUILD_FRAGMENT
setRequestCode(int code) Set request code Must be set when build mode is MConstants.BUILD_ACTIVITY
setRootPath(String path) Set default path to start Default is the internal storage root path
setMaxCount(int maxCount) Set the maximum number of selections No setting default is -1 i.e. no limit
setShowFileTypes(String... fileTypes) Set the display file type No suffix please use ""
setSelectFileTypes(String... fileTypes) Set the selection file type No suffix please use ""
setSortType(int sortType) Set sorting rules See MConstants for types
setRadio() Set radio selection Default Multiple Choice
setShowSelectStorageBtn(boolean var) Set whether to display the internal storage selection button Default true
setShowTitlebarFragment(boolean var) Whether to display the title bar Default true
setShowTabbarFragment(boolean var) Whether to show breadcrumbs Default true
setAlwaysShowHandleFragment(boolean var) Whether to always show the long press pop-up option Default false
setTitlebarMainTitle(FontBean titlebarMainTitle) Set the main title of the title bar You can also set the font size, color, etc.
setTitlebarBG(Integer titlebarBG) Set the title bar background color
setFileItemListener(FileItemListener fileItemListener) Set file item clickback The callback will be made only if you click on a file, but not if you click on a folder.
setMorePopupItemListeners(CommonItemListener... morePopupItemListener) Set the top right option callback
setHandleItemListeners(CommonItemListener... handleItemListener) Set long press popup option callback
setTitlebarFragment(AbstractTitlebarFragment titlebarFragment) Set custom title bar UI Your own Fragment must extend AbstractTitlebarFragment
setHandleFragment(AbstractHandleFragment handleFragment) Set long press to pop up custom UI Your own Fragment must extend AbstractHandleFragment
start() Start building Must be called
...... ...... ......

V. !!! Special attention !!!

Partition Storage

The library is also adapted to partitioned storage, no additional adaptation is needed, you just need to write your business code and leave the rest to it.
  • Note that the library has been added to the library's AndroidManifest.xml

    <!-- Write access to external storage -->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <!-- Android 11 extra permissions -->
    <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"
        tools:ignore="ScopedStorage" />
    <!-- Partitioned storage features have been adapted -->
    <application
            android:preserveLegacyExternalStorage="true"
            android:requestLegacyExternalStorage="true"
            >
  • Error may be reported:

    Execution failed for task ':app:processDebugMainManifest'.
    > Manifest merger failed with multiple errors, see logs

    Please set the AndroidManifest.xml in your project to be consistent

Version Upgrade

  • The new version often solves some of the problems of the old version, increases performance, scalability ...... It is recommended to upgrade to a new version
  • Please note that the old version is not compatible with the new version due to the refactoring of the project. 1.0.x upgrade 1.1.x is a non-compatible upgrade, please pay attention to learn the new API

Excessive volume

  • Already integrated with Blankj/AndroidUtilCode

    If the project has strict requirements on size, please download the source code and streamline the AndroidUtilCode module.

Code obfuscation

  • Generally no configuration is required, obfuscation rules are imported automatically

Special Thanks

Open source projects and their dependencies.