594 lines
95 KiB
XML
594 lines
95 KiB
XML
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
|
|
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
|
|
<channel>
|
|
<title>Examples on NoNonsense FilePicker</title>
|
|
<link>http://localhost:1313/NoNonsense-FilePicker/example/</link>
|
|
<description>Recent content in Examples on NoNonsense FilePicker</description>
|
|
<generator>Hugo -- gohugo.io</generator>
|
|
<language>en-us</language>
|
|
<lastBuildDate>Sat, 16 Jul 2016 17:36:40 +0200</lastBuildDate>
|
|
<atom:link href="http://localhost:1313/NoNonsense-FilePicker/example/index.xml" rel="self" type="application/rss+xml" />
|
|
|
|
<item>
|
|
<title>Standalone fragment</title>
|
|
<link>http://localhost:1313/NoNonsense-FilePicker/example/standalone_fragment/</link>
|
|
<pubDate>Sat, 16 Jul 2016 17:36:40 +0200</pubDate>
|
|
|
|
<guid>http://localhost:1313/NoNonsense-FilePicker/example/standalone_fragment/</guid>
|
|
<description><p>To use the fragment together with an existing toolbar/action bar, a few things should be overridden.</p>
|
|
|
|
<p>Here&rsquo;s a minimal example where the toolbar is intercepted from being set as the main toolbar. The menu creation is also intercepted and populates the toolbar directly.</p>
|
|
<div class="highlight" style="background: #f0f0f0"><pre style="line-height: 125%"><span></span><span style="color: #007020; font-weight: bold">public</span> <span style="color: #007020; font-weight: bold">class</span> <span style="color: #0e84b5; font-weight: bold">StandaloneFilePickerFragment</span> <span style="color: #007020; font-weight: bold">extends</span> FilePickerFragment <span style="color: #666666">{</span>
|
|
|
|
<span style="color: #007020; font-weight: bold">protected</span> Toolbar mToolbar<span style="color: #666666">;</span>
|
|
|
|
<span style="color: #555555; font-weight: bold">@Override</span>
|
|
<span style="color: #007020; font-weight: bold">protected</span> <span style="color: #902000">void</span> <span style="color: #06287e">setupToolbar</span><span style="color: #666666">(</span>Toolbar toolbar<span style="color: #666666">)</span> <span style="color: #666666">{</span>
|
|
<span style="color: #60a0b0; font-style: italic">// Prevent it from being set as main toolbar by NOT calling super.setupToolbar().</span>
|
|
mToolbar <span style="color: #666666">=</span> toolbar<span style="color: #666666">;</span>
|
|
<span style="color: #666666">}</span>
|
|
|
|
<span style="color: #555555; font-weight: bold">@Override</span>
|
|
<span style="color: #007020; font-weight: bold">public</span> <span style="color: #902000">void</span> <span style="color: #06287e">onCreateOptionsMenu</span><span style="color: #666666">(</span>Menu menu<span style="color: #666666">,</span> MenuInflater inflater<span style="color: #666666">)</span> <span style="color: #666666">{</span>
|
|
<span style="color: #60a0b0; font-style: italic">// Populate the toolbar with the menu items instead of the action bar.</span>
|
|
mToolbar<span style="color: #666666">.</span><span style="color: #4070a0">inflateMenu</span><span style="color: #666666">(</span>R<span style="color: #666666">.</span><span style="color: #4070a0">menu</span><span style="color: #666666">.</span><span style="color: #4070a0">picker_actions</span><span style="color: #666666">);</span>
|
|
|
|
<span style="color: #60a0b0; font-style: italic">// Set a menu listener on the toolbar with calls the regular onOptionsItemSelected method.</span>
|
|
mToolbar<span style="color: #666666">.</span><span style="color: #4070a0">setOnMenuItemClickListener</span><span style="color: #666666">(</span><span style="color: #007020; font-weight: bold">new</span> Toolbar<span style="color: #666666">.</span><span style="color: #4070a0">OnMenuItemClickListener</span><span style="color: #666666">()</span> <span style="color: #666666">{</span>
|
|
<span style="color: #555555; font-weight: bold">@Override</span>
|
|
<span style="color: #007020; font-weight: bold">public</span> <span style="color: #902000">boolean</span> <span style="color: #06287e">onMenuItemClick</span><span style="color: #666666">(</span>MenuItem item<span style="color: #666666">)</span> <span style="color: #666666">{</span>
|
|
<span style="color: #007020; font-weight: bold">return</span> onOptionsItemSelected<span style="color: #666666">(</span>item<span style="color: #666666">);</span>
|
|
<span style="color: #666666">}</span>
|
|
<span style="color: #666666">});</span>
|
|
|
|
<span style="color: #60a0b0; font-style: italic">// This is usually handled in onCreateOptions so do it here instead.</span>
|
|
MenuItem item <span style="color: #666666">=</span> mToolbar<span style="color: #666666">.</span><span style="color: #4070a0">getMenu</span><span style="color: #666666">().</span><span style="color: #4070a0">findItem</span><span style="color: #666666">(</span>com<span style="color: #666666">.</span><span style="color: #4070a0">nononsenseapps</span><span style="color: #666666">.</span><span style="color: #4070a0">filepicker</span><span style="color: #666666">.</span><span style="color: #4070a0">R</span><span style="color: #666666">.</span><span style="color: #4070a0">id</span><span style="color: #666666">.</span><span style="color: #4070a0">nnf_action_createdir</span><span style="color: #666666">);</span>
|
|
item<span style="color: #666666">.</span><span style="color: #4070a0">setVisible</span><span style="color: #666666">(</span>allowCreateDir<span style="color: #666666">);</span>
|
|
<span style="color: #666666">}</span>
|
|
<span style="color: #666666">}</span>
|
|
</pre></div>
|
|
</description>
|
|
</item>
|
|
|
|
<item>
|
|
<title>Override selection behavior</title>
|
|
<link>http://localhost:1313/NoNonsense-FilePicker/example/override_selection_behavior/</link>
|
|
<pubDate>Sat, 16 Jul 2016 17:35:01 +0200</pubDate>
|
|
|
|
<guid>http://localhost:1313/NoNonsense-FilePicker/example/override_selection_behavior/</guid>
|
|
<description>
|
|
|
|
<p>New in <a href="https://github.com/spacecowboy/NoNonsense-FilePicker/releases/tag/v2.4.0">2.4.0</a> are overridable methods to handle UI-interactions. The following methods are now available for augmentation:</p>
|
|
|
|
<ul>
|
|
<li>onClickOK, handles ok button.</li>
|
|
<li>onClickCancel, handles cancel button.</li>
|
|
<li>onClickHeader, handles clicks on &ldquo;..&rdquo;.</li>
|
|
<li>onClickDir, handles clicks on non-selectable items (usually directories).</li>
|
|
<li>onLongClickDir, handles long clicks on non-selectable items.</li>
|
|
<li>onClickCheckable, handles clicks on selectable items.</li>
|
|
<li>onLongClickCheckable, handles long clicks on selectable items.</li>
|
|
<li>onClickCheckBox, handles clicks on the checkbox of selectable items.</li>
|
|
</ul>
|
|
|
|
<p>Please see the existing implementations before you override any of them.</p>
|
|
|
|
<h2 id="simple-example-make-clicks-instantly-select-items">Simple example, make clicks instantly select items</h2>
|
|
|
|
<p>As asked in <a href="https://github.com/spacecowboy/NoNonsense-FilePicker/issues/48">#48</a>, what if the picker is configured for selecting a single file and you want a click on that to instantly return the result. The default implementation will mark the item as selected, and then the user is required to press the OK button. This small change will make the operation a single click action, returning instantly once the user selects something.</p>
|
|
<div class="highlight" style="background: #f0f0f0"><pre style="line-height: 125%"><span></span><span style="color: #007020; font-weight: bold">public</span> <span style="color: #007020; font-weight: bold">class</span> <span style="color: #0e84b5; font-weight: bold">SingleFilePickerFragment</span> <span style="color: #007020; font-weight: bold">extends</span> FilePickerFragment <span style="color: #666666">{</span>
|
|
<span style="color: #555555; font-weight: bold">@Override</span>
|
|
<span style="color: #007020; font-weight: bold">public</span> <span style="color: #902000">void</span> <span style="color: #06287e">onClickCheckable</span><span style="color: #666666">(</span>View v<span style="color: #666666">,</span> CheckableViewHolder vh<span style="color: #666666">)</span> <span style="color: #666666">{</span>
|
|
<span style="color: #007020; font-weight: bold">if</span> <span style="color: #666666">(!</span>allowMultiple<span style="color: #666666">)</span> <span style="color: #666666">{</span>
|
|
<span style="color: #60a0b0; font-style: italic">// Clear is necessary, in case user clicked some checkbox directly</span>
|
|
mCheckedItems<span style="color: #666666">.</span><span style="color: #4070a0">clear</span><span style="color: #666666">();</span>
|
|
mCheckedItems<span style="color: #666666">.</span><span style="color: #4070a0">add</span><span style="color: #666666">(</span>vh<span style="color: #666666">.</span><span style="color: #4070a0">file</span><span style="color: #666666">);</span>
|
|
onClickOk<span style="color: #666666">(</span><span style="color: #007020; font-weight: bold">null</span><span style="color: #666666">);</span>
|
|
<span style="color: #666666">}</span> <span style="color: #007020; font-weight: bold">else</span> <span style="color: #666666">{</span>
|
|
<span style="color: #007020; font-weight: bold">super</span><span style="color: #666666">.</span><span style="color: #4070a0">onClickCheckable</span><span style="color: #666666">(</span>v<span style="color: #666666">,</span> vh<span style="color: #666666">);</span>
|
|
<span style="color: #666666">}</span>
|
|
<span style="color: #666666">}</span>
|
|
<span style="color: #666666">}</span>
|
|
</pre></div>
|
|
|
|
<p>Now the astute reader might wonder, if my filepicker is only going to be used for selecting single files, why not just do:</p>
|
|
<div class="highlight" style="background: #f0f0f0"><pre style="line-height: 125%"><span></span><span style="color: #007020; font-weight: bold">public</span> <span style="color: #902000">void</span> <span style="color: #06287e">onClickCheckable</span><span style="color: #666666">(</span>View v<span style="color: #666666">,</span> CheckableViewHolder vh<span style="color: #666666">)</span> <span style="color: #666666">{</span>
|
|
<span style="color: #007020; font-weight: bold">super</span><span style="color: #666666">.</span><span style="color: #4070a0">onClickCheckable</span><span style="color: #666666">(</span>v<span style="color: #666666">,</span> vh<span style="color: #666666">);</span>
|
|
onClickOk<span style="color: #666666">(</span><span style="color: #007020; font-weight: bold">null</span><span style="color: #666666">);</span>
|
|
<span style="color: #666666">}</span>
|
|
</pre></div>
|
|
|
|
<p>The reason is that the default implementation will animate the checkbox being selected on press. If you are closing the picker directly once the user selects something, you are basically animating something which isn&rsquo;t going to be seen and thus you are wasting (not that much) resources. Better to not animate at all in that case.</p>
|
|
</description>
|
|
</item>
|
|
|
|
<item>
|
|
<title>Override the back button</title>
|
|
<link>http://localhost:1313/NoNonsense-FilePicker/example/override_back_button/</link>
|
|
<pubDate>Sat, 16 Jul 2016 17:33:43 +0200</pubDate>
|
|
|
|
<guid>http://localhost:1313/NoNonsense-FilePicker/example/override_back_button/</guid>
|
|
<description>
|
|
|
|
<p>In case you want the back button to navigate the hierarchy instead of
|
|
instantly exiting the activity, this is one approach you might take.</p>
|
|
|
|
<h2 id="create-an-activity-which-overrides-the-back-button-and-loads-a-custom-fragment">Create an activity which overrides the back button and loads a custom fragment</h2>
|
|
<div class="highlight" style="background: #f0f0f0"><pre style="line-height: 125%"><code><span></span><span style="color: #007020; font-weight: bold">package</span> <span style="color: #0e84b5; font-weight: bold">com.nononsenseapps.filepicker.examples.backbutton</span><span style="color: #666666">;</span>
|
|
|
|
<span style="color: #007020; font-weight: bold">import</span> <span style="color: #0e84b5; font-weight: bold">android.os.Environment</span><span style="color: #666666">;</span>
|
|
|
|
<span style="color: #007020; font-weight: bold">import</span> <span style="color: #0e84b5; font-weight: bold">com.nononsenseapps.filepicker.AbstractFilePickerFragment</span><span style="color: #666666">;</span>
|
|
<span style="color: #007020; font-weight: bold">import</span> <span style="color: #0e84b5; font-weight: bold">com.nononsenseapps.filepicker.FilePickerActivity</span><span style="color: #666666">;</span>
|
|
|
|
<span style="color: #007020; font-weight: bold">import</span> <span style="color: #0e84b5; font-weight: bold">java.io.File</span><span style="color: #666666">;</span>
|
|
|
|
<span style="color: #007020; font-weight: bold">public</span> <span style="color: #007020; font-weight: bold">class</span> <span style="color: #0e84b5; font-weight: bold">BackHandlingFilePickerActivity</span> <span style="color: #007020; font-weight: bold">extends</span> FilePickerActivity <span style="color: #666666">{</span>
|
|
|
|
<span style="color: #60a0b0; font-style: italic">/**</span>
|
|
<span style="color: #60a0b0; font-style: italic"> * Need access to the fragment</span>
|
|
<span style="color: #60a0b0; font-style: italic"> */</span>
|
|
BackHandlingFilePickerFragment currentFragment<span style="color: #666666">;</span>
|
|
|
|
<span style="color: #60a0b0; font-style: italic">/**</span>
|
|
<span style="color: #60a0b0; font-style: italic"> * Return a copy of the new fragment and set the variable above.</span>
|
|
<span style="color: #60a0b0; font-style: italic"> */</span>
|
|
<span style="color: #555555; font-weight: bold">@Override</span>
|
|
<span style="color: #007020; font-weight: bold">protected</span> AbstractFilePickerFragment<span style="color: #666666">&lt;</span>File<span style="color: #666666">&gt;</span> <span style="color: #06287e">getFragment</span><span style="color: #666666">(</span>
|
|
<span style="color: #007020; font-weight: bold">final</span> String startPath<span style="color: #666666">,</span> <span style="color: #007020; font-weight: bold">final</span> <span style="color: #902000">int</span> mode<span style="color: #666666">,</span> <span style="color: #007020; font-weight: bold">final</span> <span style="color: #902000">boolean</span> allowMultiple<span style="color: #666666">,</span>
|
|
<span style="color: #007020; font-weight: bold">final</span> <span style="color: #902000">boolean</span> allowDirCreate<span style="color: #666666">,</span> <span style="color: #007020; font-weight: bold">final</span> <span style="color: #902000">boolean</span> allowExistingFile<span style="color: #666666">,</span>
|
|
<span style="color: #007020; font-weight: bold">final</span> <span style="color: #902000">boolean</span> singleClick<span style="color: #666666">)</span> <span style="color: #666666">{</span>
|
|
|
|
<span style="color: #60a0b0; font-style: italic">// startPath is allowed to be null.</span>
|
|
<span style="color: #60a0b0; font-style: italic">// In that case, default folder should be SD-card and not &quot;/&quot;</span>
|
|
String path <span style="color: #666666">=</span> <span style="color: #666666">(</span>startPath <span style="color: #666666">!=</span> <span style="color: #007020; font-weight: bold">null</span> <span style="color: #666666">?</span> startPath
|
|
<span style="color: #666666">:</span> Environment<span style="color: #666666">.</span><span style="color: #4070a0">getExternalStorageDirectory</span><span style="color: #666666">().</span><span style="color: #4070a0">getPath</span><span style="color: #666666">());</span>
|
|
|
|
currentFragment <span style="color: #666666">=</span> <span style="color: #007020; font-weight: bold">new</span> BackHandlingFilePickerFragment<span style="color: #666666">();</span>
|
|
currentFragment<span style="color: #666666">.</span><span style="color: #4070a0">setArgs</span><span style="color: #666666">(</span>path<span style="color: #666666">,</span> mode<span style="color: #666666">,</span> allowMultiple<span style="color: #666666">,</span> allowDirCreate<span style="color: #666666">,</span>
|
|
allowExistingFile<span style="color: #666666">,</span> singleClick<span style="color: #666666">);</span>
|
|
<span style="color: #007020; font-weight: bold">return</span> currentFragment<span style="color: #666666">;</span>
|
|
<span style="color: #666666">}</span>
|
|
|
|
<span style="color: #60a0b0; font-style: italic">/**</span>
|
|
<span style="color: #60a0b0; font-style: italic"> * Override the back-button.</span>
|
|
<span style="color: #60a0b0; font-style: italic"> */</span>
|
|
<span style="color: #555555; font-weight: bold">@Override</span>
|
|
<span style="color: #007020; font-weight: bold">public</span> <span style="color: #902000">void</span> <span style="color: #06287e">onBackPressed</span><span style="color: #666666">()</span> <span style="color: #666666">{</span>
|
|
<span style="color: #60a0b0; font-style: italic">// If at top most level, normal behaviour</span>
|
|
<span style="color: #007020; font-weight: bold">if</span> <span style="color: #666666">(</span>currentFragment<span style="color: #666666">.</span><span style="color: #4070a0">isBackTop</span><span style="color: #666666">())</span> <span style="color: #666666">{</span>
|
|
<span style="color: #007020; font-weight: bold">super</span><span style="color: #666666">.</span><span style="color: #4070a0">onBackPressed</span><span style="color: #666666">();</span>
|
|
<span style="color: #666666">}</span> <span style="color: #007020; font-weight: bold">else</span> <span style="color: #666666">{</span>
|
|
<span style="color: #60a0b0; font-style: italic">// Else go up</span>
|
|
currentFragment<span style="color: #666666">.</span><span style="color: #4070a0">goUp</span><span style="color: #666666">();</span>
|
|
<span style="color: #666666">}</span>
|
|
<span style="color: #666666">}</span>
|
|
<span style="color: #666666">}</span>
|
|
</code></pre></div>
|
|
|
|
<h2 id="in-your-custom-fragment-implement-the-goup-and-isbacktop-methods">In your custom fragment, implement the goUp and isBackTop methods</h2>
|
|
<div class="highlight" style="background: #f0f0f0"><pre style="line-height: 125%"><code><span></span><span style="color: #007020; font-weight: bold">package</span> <span style="color: #0e84b5; font-weight: bold">com.nononsenseapps.filepicker.examples.backbutton</span><span style="color: #666666">;</span>
|
|
|
|
<span style="color: #007020; font-weight: bold">import</span> <span style="color: #0e84b5; font-weight: bold">com.nononsenseapps.filepicker.FilePickerFragment</span><span style="color: #666666">;</span>
|
|
|
|
<span style="color: #007020; font-weight: bold">import</span> <span style="color: #0e84b5; font-weight: bold">java.io.File</span><span style="color: #666666">;</span>
|
|
|
|
<span style="color: #007020; font-weight: bold">public</span> <span style="color: #007020; font-weight: bold">class</span> <span style="color: #0e84b5; font-weight: bold">BackHandlingFilePickerFragment</span> <span style="color: #007020; font-weight: bold">extends</span> FilePickerFragment <span style="color: #666666">{</span>
|
|
|
|
<span style="color: #60a0b0; font-style: italic">/**</span>
|
|
<span style="color: #60a0b0; font-style: italic"> * For consistency, the top level the back button checks against should be the start path.</span>
|
|
<span style="color: #60a0b0; font-style: italic"> * But it will fall back on /.</span>
|
|
<span style="color: #60a0b0; font-style: italic"> */</span>
|
|
<span style="color: #007020; font-weight: bold">public</span> File <span style="color: #06287e">getBackTop</span><span style="color: #666666">()</span> <span style="color: #666666">{</span>
|
|
<span style="color: #007020; font-weight: bold">return</span> getPath<span style="color: #666666">(</span>getArguments<span style="color: #666666">().</span><span style="color: #4070a0">getString</span><span style="color: #666666">(</span>KEY_START_PATH<span style="color: #666666">,</span> <span style="color: #4070a0">&quot;/&quot;</span><span style="color: #666666">));</span>
|
|
<span style="color: #666666">}</span>
|
|
|
|
<span style="color: #60a0b0; font-style: italic">/**</span>
|
|
<span style="color: #60a0b0; font-style: italic"> * @return true if the current path is the startpath or /</span>
|
|
<span style="color: #60a0b0; font-style: italic"> */</span>
|
|
<span style="color: #007020; font-weight: bold">public</span> <span style="color: #902000">boolean</span> <span style="color: #06287e">isBackTop</span><span style="color: #666666">()</span> <span style="color: #666666">{</span>
|
|
<span style="color: #007020; font-weight: bold">return</span> <span style="color: #40a070">0</span> <span style="color: #666666">==</span> compareFiles<span style="color: #666666">(</span>mCurrentPath<span style="color: #666666">,</span> getBackTop<span style="color: #666666">())</span> <span style="color: #666666">||</span>
|
|
<span style="color: #40a070">0</span> <span style="color: #666666">==</span> compareFiles<span style="color: #666666">(</span>mCurrentPath<span style="color: #666666">,</span> <span style="color: #007020; font-weight: bold">new</span> File<span style="color: #666666">(</span><span style="color: #4070a0">&quot;/&quot;</span><span style="color: #666666">));</span>
|
|
<span style="color: #666666">}</span>
|
|
|
|
<span style="color: #60a0b0; font-style: italic">/**</span>
|
|
<span style="color: #60a0b0; font-style: italic"> * Go up on level, same as pressing on &quot;..&quot;.</span>
|
|
<span style="color: #60a0b0; font-style: italic"> */</span>
|
|
<span style="color: #007020; font-weight: bold">public</span> <span style="color: #902000">void</span> <span style="color: #06287e">goUp</span><span style="color: #666666">()</span> <span style="color: #666666">{</span>
|
|
mCurrentPath <span style="color: #666666">=</span> getParent<span style="color: #666666">(</span>mCurrentPath<span style="color: #666666">);</span>
|
|
mCheckedItems<span style="color: #666666">.</span><span style="color: #4070a0">clear</span><span style="color: #666666">();</span>
|
|
mCheckedVisibleViewHolders<span style="color: #666666">.</span><span style="color: #4070a0">clear</span><span style="color: #666666">();</span>
|
|
refresh<span style="color: #666666">(</span>mCurrentPath<span style="color: #666666">);</span>
|
|
<span style="color: #666666">}</span>
|
|
<span style="color: #666666">}</span>
|
|
</code></pre></div>
|
|
|
|
<h2 id="example-manifest">Example manifest</h2>
|
|
|
|
<p>Make sure <code>android-theme</code> points to the correct theme.</p>
|
|
<div class="highlight" style="background: #f0f0f0"><pre style="line-height: 125%"><code><span></span><span style="color: #062873; font-weight: bold">&lt;manifest</span> <span style="color: #4070a0">xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;</span>
|
|
<span style="color: #4070a0">package=&quot;com.nononsenseapps.filepicker.examples&quot;</span><span style="color: #062873; font-weight: bold">&gt;</span>
|
|
|
|
<span style="color: #062873; font-weight: bold">&lt;uses-permission</span> <span style="color: #4070a0">android:name=&quot;android.permission.READ_EXTERNAL_STORAGE&quot;</span> <span style="color: #062873; font-weight: bold">/&gt;</span>
|
|
<span style="color: #60a0b0; font-style: italic">&lt;!-- Only needed to create sub directories. --&gt;</span>
|
|
<span style="color: #062873; font-weight: bold">&lt;uses-permission</span> <span style="color: #4070a0">android:name=&quot;android.permission.WRITE_EXTERNAL_STORAGE&quot;</span> <span style="color: #062873; font-weight: bold">/&gt;</span>
|
|
|
|
<span style="color: #062873; font-weight: bold">&lt;application</span>
|
|
<span style="color: #4070a0">android:allowBackup=&quot;true&quot;</span>
|
|
<span style="color: #4070a0">android:icon=&quot;@mipmap/ic_launcher&quot;</span>
|
|
<span style="color: #4070a0">android:label=&quot;@string/app_name&quot;</span>
|
|
<span style="color: #4070a0">android:supportsRtl=&quot;true&quot;</span>
|
|
<span style="color: #4070a0">android:theme=&quot;@style/FilePickerTheme&quot;</span><span style="color: #062873; font-weight: bold">&gt;</span>
|
|
|
|
<span style="color: #062873; font-weight: bold">&lt;activity</span>
|
|
<span style="color: #4070a0">android:name=&quot;.backbutton.BackHandlingFilePickerActivity&quot;</span>
|
|
<span style="color: #4070a0">android:label=&quot;Override back button&quot;</span>
|
|
<span style="color: #4070a0">android:theme=&quot;@style/FilePickerTheme&quot;</span><span style="color: #062873; font-weight: bold">&gt;</span>
|
|
<span style="color: #062873; font-weight: bold">&lt;/activity&gt;</span>
|
|
<span style="color: #062873; font-weight: bold">&lt;/application&gt;</span>
|
|
|
|
<span style="color: #062873; font-weight: bold">&lt;/manifest&gt;</span>
|
|
</code></pre></div>
|
|
</description>
|
|
</item>
|
|
|
|
<item>
|
|
<title>Filter based on file extension</title>
|
|
<link>http://localhost:1313/NoNonsense-FilePicker/example/filter_file_extension/</link>
|
|
<pubDate>Sat, 16 Jul 2016 17:32:07 +0200</pubDate>
|
|
|
|
<guid>http://localhost:1313/NoNonsense-FilePicker/example/filter_file_extension/</guid>
|
|
<description>
|
|
|
|
<p>By default, the SD-card picker will display all files in alphabetical order. But let&rsquo;s say that your app can only handle a specific type of file, like <code>.txt</code>-files. Here&rsquo;s a minimal example which will only display such files.</p>
|
|
|
|
<p>First, a convenience method to get the extension of files:</p>
|
|
<div class="highlight" style="background: #f0f0f0"><pre style="line-height: 125%"><span></span> <span style="color: #60a0b0; font-style: italic">// File extension to filter on, including the initial dot.</span>
|
|
<span style="color: #007020; font-weight: bold">private</span> <span style="color: #007020; font-weight: bold">static</span> <span style="color: #007020; font-weight: bold">final</span> String EXTENSION <span style="color: #666666">=</span> <span style="color: #4070a0">&quot;.txt&quot;</span><span style="color: #666666">;</span>
|
|
|
|
<span style="color: #60a0b0; font-style: italic">/**</span>
|
|
<span style="color: #60a0b0; font-style: italic"> *</span>
|
|
<span style="color: #60a0b0; font-style: italic"> * @param file</span>
|
|
<span style="color: #60a0b0; font-style: italic"> * @return The file extension. If file has no extension, it returns null.</span>
|
|
<span style="color: #60a0b0; font-style: italic"> */</span>
|
|
<span style="color: #007020; font-weight: bold">private</span> String <span style="color: #06287e">getExtension</span><span style="color: #666666">(</span><span style="color: #555555; font-weight: bold">@NonNull</span> File file<span style="color: #666666">)</span> <span style="color: #666666">{</span>
|
|
String path <span style="color: #666666">=</span> file<span style="color: #666666">.</span><span style="color: #4070a0">getPath</span><span style="color: #666666">();</span>
|
|
<span style="color: #902000">int</span> i <span style="color: #666666">=</span> path<span style="color: #666666">.</span><span style="color: #4070a0">lastIndexOf</span><span style="color: #666666">(</span><span style="color: #4070a0">&quot;.&quot;</span><span style="color: #666666">);</span>
|
|
<span style="color: #007020; font-weight: bold">if</span> <span style="color: #666666">(</span>i <span style="color: #666666">&lt;</span> <span style="color: #40a070">0</span><span style="color: #666666">)</span> <span style="color: #666666">{</span>
|
|
<span style="color: #007020; font-weight: bold">return</span> <span style="color: #007020; font-weight: bold">null</span><span style="color: #666666">;</span>
|
|
<span style="color: #666666">}</span> <span style="color: #007020; font-weight: bold">else</span> <span style="color: #666666">{</span>
|
|
<span style="color: #007020; font-weight: bold">return</span> path<span style="color: #666666">.</span><span style="color: #4070a0">substring</span><span style="color: #666666">(</span>i<span style="color: #666666">);</span>
|
|
<span style="color: #666666">}</span>
|
|
<span style="color: #666666">}</span>
|
|
</pre></div>
|
|
|
|
<p>The decision to display files or not is done with the <code>isItemVisible</code> method. Just add a check for the file-extension:</p>
|
|
<div class="highlight" style="background: #f0f0f0"><pre style="line-height: 125%"><span></span> <span style="color: #555555; font-weight: bold">@Override</span>
|
|
<span style="color: #007020; font-weight: bold">protected</span> <span style="color: #902000">boolean</span> <span style="color: #06287e">isItemVisible</span><span style="color: #666666">(</span><span style="color: #007020; font-weight: bold">final</span> File file<span style="color: #666666">)</span> <span style="color: #666666">{</span>
|
|
<span style="color: #60a0b0; font-style: italic">// simplified behavior (see below full code)</span>
|
|
<span style="color: #60a0b0; font-style: italic">// return isDir(file) || (mode == MODE_FILE || mode == MODE_FILE_AND_DIR);</span>
|
|
<span style="color: #007020; font-weight: bold">if</span> <span style="color: #666666">(!</span>isDir<span style="color: #666666">(</span>file<span style="color: #666666">)</span> <span style="color: #666666">&amp;&amp;</span> <span style="color: #666666">(</span>mode <span style="color: #666666">==</span> MODE_FILE <span style="color: #666666">||</span> mode <span style="color: #666666">==</span> MODE_FILE_AND_DIR<span style="color: #666666">))</span> <span style="color: #666666">{</span>
|
|
String ext <span style="color: #666666">=</span> getExtension<span style="color: #666666">(</span>file<span style="color: #666666">);</span>
|
|
<span style="color: #007020; font-weight: bold">return</span> ext <span style="color: #666666">!=</span> <span style="color: #007020; font-weight: bold">null</span> <span style="color: #666666">&amp;&amp;</span> EXTENSION<span style="color: #666666">.</span><span style="color: #4070a0">equalsIgnoreCase</span><span style="color: #666666">(</span>ext<span style="color: #666666">);</span>
|
|
<span style="color: #666666">}</span>
|
|
<span style="color: #007020; font-weight: bold">return</span> isDir<span style="color: #666666">(</span>file<span style="color: #666666">);</span>
|
|
<span style="color: #666666">}</span>
|
|
</pre></div>
|
|
|
|
<h3 id="before-and-after">Before and After</h3>
|
|
|
|
<p><img src="http://localhost:1313/NoNonsense-FilePicker/screenshots/filter_before.png" width="30%" alt="Before"/>
|
|
<img src="http://localhost:1313/NoNonsense-FilePicker/screenshots/filter_after.png" width="30%" alt="After"/></p>
|
|
|
|
<h3 id="full-fragment-code">Full Fragment code</h3>
|
|
<div class="highlight" style="background: #f0f0f0"><pre style="line-height: 125%"><span></span><span style="color: #007020; font-weight: bold">import</span> <span style="color: #0e84b5; font-weight: bold">com.nononsenseapps.filepicker.FilePickerFragment</span><span style="color: #666666">;</span>
|
|
|
|
<span style="color: #007020; font-weight: bold">import</span> <span style="color: #0e84b5; font-weight: bold">java.io.File</span><span style="color: #666666">;</span>
|
|
|
|
<span style="color: #007020; font-weight: bold">public</span> <span style="color: #007020; font-weight: bold">class</span> <span style="color: #0e84b5; font-weight: bold">FilteredFilePickerFragment</span> <span style="color: #007020; font-weight: bold">extends</span> FilePickerFragment <span style="color: #666666">{</span>
|
|
|
|
<span style="color: #60a0b0; font-style: italic">// File extension to filter on</span>
|
|
<span style="color: #007020; font-weight: bold">private</span> <span style="color: #007020; font-weight: bold">static</span> <span style="color: #007020; font-weight: bold">final</span> String EXTENSION <span style="color: #666666">=</span> <span style="color: #4070a0">&quot;.txt&quot;</span><span style="color: #666666">;</span>
|
|
|
|
<span style="color: #60a0b0; font-style: italic">/**</span>
|
|
<span style="color: #60a0b0; font-style: italic"> *</span>
|
|
<span style="color: #60a0b0; font-style: italic"> * @param file</span>
|
|
<span style="color: #60a0b0; font-style: italic"> * @return The file extension. If file has no extension, it returns null.</span>
|
|
<span style="color: #60a0b0; font-style: italic"> */</span>
|
|
<span style="color: #007020; font-weight: bold">private</span> String <span style="color: #06287e">getExtension</span><span style="color: #666666">(</span><span style="color: #555555; font-weight: bold">@NonNull</span> File file<span style="color: #666666">)</span> <span style="color: #666666">{</span>
|
|
String path <span style="color: #666666">=</span> file<span style="color: #666666">.</span><span style="color: #4070a0">getPath</span><span style="color: #666666">();</span>
|
|
<span style="color: #902000">int</span> i <span style="color: #666666">=</span> path<span style="color: #666666">.</span><span style="color: #4070a0">lastIndexOf</span><span style="color: #666666">(</span><span style="color: #4070a0">&quot;.&quot;</span><span style="color: #666666">);</span>
|
|
<span style="color: #007020; font-weight: bold">if</span> <span style="color: #666666">(</span>i <span style="color: #666666">&lt;</span> <span style="color: #40a070">0</span><span style="color: #666666">)</span> <span style="color: #666666">{</span>
|
|
<span style="color: #007020; font-weight: bold">return</span> <span style="color: #007020; font-weight: bold">null</span><span style="color: #666666">;</span>
|
|
<span style="color: #666666">}</span> <span style="color: #007020; font-weight: bold">else</span> <span style="color: #666666">{</span>
|
|
<span style="color: #007020; font-weight: bold">return</span> path<span style="color: #666666">.</span><span style="color: #4070a0">substring</span><span style="color: #666666">(</span>i<span style="color: #666666">);</span>
|
|
<span style="color: #666666">}</span>
|
|
<span style="color: #666666">}</span>
|
|
|
|
<span style="color: #555555; font-weight: bold">@Override</span>
|
|
<span style="color: #007020; font-weight: bold">protected</span> <span style="color: #902000">boolean</span> <span style="color: #06287e">isItemVisible</span><span style="color: #666666">(</span><span style="color: #007020; font-weight: bold">final</span> File file<span style="color: #666666">)</span> <span style="color: #666666">{</span>
|
|
<span style="color: #902000">boolean</span> ret <span style="color: #666666">=</span> <span style="color: #007020; font-weight: bold">super</span><span style="color: #666666">.</span><span style="color: #4070a0">isItemVisible</span><span style="color: #666666">(</span>file<span style="color: #666666">);</span>
|
|
<span style="color: #007020; font-weight: bold">if</span> <span style="color: #666666">(</span>ret <span style="color: #666666">&amp;&amp;</span> <span style="color: #666666">!</span>isDir<span style="color: #666666">(</span>file<span style="color: #666666">)</span> <span style="color: #666666">&amp;&amp;</span> <span style="color: #666666">(</span>mode <span style="color: #666666">==</span> MODE_FILE <span style="color: #666666">||</span> mode <span style="color: #666666">==</span> MODE_FILE_AND_DIR<span style="color: #666666">))</span> <span style="color: #666666">{</span>
|
|
String ext <span style="color: #666666">=</span> getExtension<span style="color: #666666">(</span>file<span style="color: #666666">);</span>
|
|
<span style="color: #007020; font-weight: bold">return</span> ext <span style="color: #666666">!=</span> <span style="color: #007020; font-weight: bold">null</span> <span style="color: #666666">&amp;&amp;</span> EXTENSION<span style="color: #666666">.</span><span style="color: #4070a0">equalsIgnoreCase</span><span style="color: #666666">(</span>ext<span style="color: #666666">);</span>
|
|
<span style="color: #666666">}</span>
|
|
<span style="color: #007020; font-weight: bold">return</span> ret<span style="color: #666666">;</span>
|
|
<span style="color: #666666">}</span>
|
|
<span style="color: #666666">}</span>
|
|
</pre></div>
|
|
</description>
|
|
</item>
|
|
|
|
<item>
|
|
<title>Custom item layout</title>
|
|
<link>http://localhost:1313/NoNonsense-FilePicker/example/custom_item_layout/</link>
|
|
<pubDate>Sat, 16 Jul 2016 17:21:28 +0200</pubDate>
|
|
|
|
<guid>http://localhost:1313/NoNonsense-FilePicker/example/custom_item_layout/</guid>
|
|
<description>
|
|
|
|
<p>Say you want to browse some files which have really long names. By default, filenames will be cut if they exceed one line in width like <code>ThisIsAReallyLongFi...</code>. What if we really wanted it show like in this image?</p>
|
|
|
|
<p><img src="http://localhost:1313/NoNonsense-FilePicker/screenshots/itemlayout_longfilename.png" alt="Example of a long filename" /></p>
|
|
|
|
<p>The behavior of the text is defined in the listitem layouts:
|
|
<a href="https://github.com/spacecowboy/NoNonsense-FilePicker/blob/master/library/src/main/res/layout/nnf_filepicker_listitem_checkable.xml">nnf_filepicker_listitem_checkable</a>
|
|
and
|
|
<a href="https://github.com/spacecowboy/NoNonsense-FilePicker/blob/master/library/src/main/res/layout/nnf_filepicker_listitem_dir.xml">nnf_filepicker_listitem_dir</a>.</p>
|
|
|
|
<p>There are two kinds of layouts, one with a checkbox to allow selection, and one without a checkbox. The second one is also used for the special header item <code>..</code> though you could of course have a special layout for that if you wanted.</p>
|
|
|
|
<h3 id="layouts">Layouts</h3>
|
|
|
|
<p>Let&rsquo;s create some new layouts which will support longer filenames as follows:</p>
|
|
|
|
<p><strong>longer_listitem_checkable.xml</strong></p>
|
|
<div class="highlight" style="background: #f0f0f0"><pre style="line-height: 125%"><span></span><span style="color: #007020">&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;</span>
|
|
<span style="color: #062873; font-weight: bold">&lt;LinearLayout</span> <span style="color: #4070a0">xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;</span>
|
|
<span style="color: #4070a0">xmlns:tools=&quot;http://schemas.android.com/tools&quot;</span>
|
|
<span style="color: #4070a0">android:layout_width=&quot;match_parent&quot;</span>
|
|
<span style="color: #4070a0">android:layout_height=&quot;wrap_content&quot;</span>
|
|
<span style="color: #4070a0">android:background=&quot;?android:selectableItemBackground&quot;</span>
|
|
<span style="color: #4070a0">android:minHeight=&quot;?android:listPreferredItemHeight&quot;</span>
|
|
<span style="color: #4070a0">android:orientation=&quot;horizontal&quot;</span><span style="color: #062873; font-weight: bold">&gt;</span>
|
|
|
|
|
|
<span style="color: #60a0b0; font-style: italic">&lt;!--suppress AndroidDomInspection --&gt;</span>
|
|
<span style="color: #062873; font-weight: bold">&lt;ImageView</span>
|
|
<span style="color: #4070a0">android:id=&quot;@+id/item_icon&quot;</span>
|
|
<span style="color: #4070a0">android:layout_width=&quot;?android:listPreferredItemHeight&quot;</span>
|
|
<span style="color: #4070a0">android:layout_height=&quot;?android:listPreferredItemHeight&quot;</span>
|
|
<span style="color: #4070a0">android:adjustViewBounds=&quot;true&quot;</span>
|
|
<span style="color: #4070a0">android:scaleType=&quot;fitCenter&quot;</span>
|
|
<span style="color: #4070a0">android:src=&quot;@drawable/nnf_ic_file_folder&quot;</span>
|
|
<span style="color: #4070a0">android:tint=&quot;?attr/colorAccent&quot;</span>
|
|
<span style="color: #4070a0">android:visibility=&quot;visible&quot;</span>
|
|
<span style="color: #4070a0">tools:ignore=&quot;ContentDescription&quot;</span> <span style="color: #062873; font-weight: bold">/&gt;</span>
|
|
|
|
<span style="color: #062873; font-weight: bold">&lt;TextView</span>
|
|
<span style="color: #4070a0">android:id=&quot;@android:id/text1&quot;</span>
|
|
<span style="color: #4070a0">style=&quot;?android:textAppearanceLarge&quot;</span>
|
|
<span style="color: #4070a0">android:layout_width=&quot;0dp&quot;</span>
|
|
<span style="color: #4070a0">android:layout_height=&quot;wrap_content&quot;</span>
|
|
<span style="color: #4070a0">android:minHeight=&quot;?android:listPreferredItemHeight&quot;</span>
|
|
<span style="color: #4070a0">android:layout_weight=&quot;1&quot;</span>
|
|
<span style="color: #4070a0">android:ellipsize=&quot;end&quot;</span>
|
|
<span style="color: #4070a0">android:gravity=&quot;center_vertical&quot;</span>
|
|
<span style="color: #4070a0">android:maxLines=&quot;4&quot;</span>
|
|
<span style="color: #4070a0">android:padding=&quot;8dp&quot;</span><span style="color: #062873; font-weight: bold">/&gt;</span>
|
|
|
|
<span style="color: #062873; font-weight: bold">&lt;CheckBox</span>
|
|
<span style="color: #4070a0">android:id=&quot;@+id/checkbox&quot;</span>
|
|
<span style="color: #4070a0">android:layout_width=&quot;wrap_content&quot;</span>
|
|
<span style="color: #4070a0">android:layout_height=&quot;match_parent&quot;</span>
|
|
<span style="color: #4070a0">android:paddingEnd=&quot;8dp&quot;</span>
|
|
<span style="color: #4070a0">android:paddingRight=&quot;8dp&quot;</span>
|
|
<span style="color: #4070a0">tools:ignore=&quot;RtlSymmetry&quot;</span> <span style="color: #062873; font-weight: bold">/&gt;</span>
|
|
|
|
<span style="color: #062873; font-weight: bold">&lt;/LinearLayout&gt;</span>
|
|
</pre></div>
|
|
|
|
<p><strong>longer_listitem_dir.xml</strong></p>
|
|
<div class="highlight" style="background: #f0f0f0"><pre style="line-height: 125%"><span></span><span style="color: #007020">&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;</span>
|
|
<span style="color: #062873; font-weight: bold">&lt;LinearLayout</span> <span style="color: #4070a0">xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;</span>
|
|
<span style="color: #4070a0">xmlns:tools=&quot;http://schemas.android.com/tools&quot;</span>
|
|
<span style="color: #4070a0">android:layout_width=&quot;match_parent&quot;</span>
|
|
<span style="color: #4070a0">android:layout_height=&quot;wrap_content&quot;</span>
|
|
<span style="color: #4070a0">android:background=&quot;?android:selectableItemBackground&quot;</span>
|
|
<span style="color: #4070a0">android:minHeight=&quot;?android:listPreferredItemHeight&quot;</span>
|
|
<span style="color: #4070a0">android:orientation=&quot;horizontal&quot;</span>
|
|
<span style="color: #062873; font-weight: bold">&gt;</span>
|
|
|
|
<span style="color: #60a0b0; font-style: italic">&lt;!--suppress AndroidDomInspection --&gt;</span>
|
|
<span style="color: #062873; font-weight: bold">&lt;ImageView</span>
|
|
<span style="color: #4070a0">android:id=&quot;@+id/item_icon&quot;</span>
|
|
<span style="color: #4070a0">android:layout_width=&quot;?android:listPreferredItemHeight&quot;</span>
|
|
<span style="color: #4070a0">android:layout_height=&quot;?android:listPreferredItemHeight&quot;</span>
|
|
<span style="color: #4070a0">android:adjustViewBounds=&quot;true&quot;</span>
|
|
<span style="color: #4070a0">android:scaleType=&quot;center&quot;</span>
|
|
<span style="color: #4070a0">android:src=&quot;@drawable/nnf_ic_file_folder&quot;</span>
|
|
<span style="color: #4070a0">android:tint=&quot;?attr/colorAccent&quot;</span>
|
|
<span style="color: #4070a0">android:visibility=&quot;visible&quot;</span>
|
|
<span style="color: #4070a0">tools:ignore=&quot;ContentDescription&quot;</span> <span style="color: #062873; font-weight: bold">/&gt;</span>
|
|
|
|
<span style="color: #062873; font-weight: bold">&lt;TextView</span>
|
|
<span style="color: #4070a0">android:id=&quot;@android:id/text1&quot;</span>
|
|
<span style="color: #4070a0">style=&quot;?android:textAppearanceLarge&quot;</span>
|
|
<span style="color: #4070a0">android:layout_width=&quot;0dp&quot;</span>
|
|
<span style="color: #4070a0">android:layout_height=&quot;wrap_content&quot;</span>
|
|
<span style="color: #4070a0">android:minHeight=&quot;?android:listPreferredItemHeight&quot;</span>
|
|
<span style="color: #4070a0">android:layout_weight=&quot;1&quot;</span>
|
|
<span style="color: #4070a0">android:ellipsize=&quot;end&quot;</span>
|
|
<span style="color: #4070a0">android:gravity=&quot;center_vertical&quot;</span>
|
|
<span style="color: #4070a0">android:maxLines=&quot;4&quot;</span>
|
|
<span style="color: #4070a0">android:padding=&quot;8dp&quot;</span><span style="color: #062873; font-weight: bold">/&gt;</span>
|
|
<span style="color: #062873; font-weight: bold">&lt;/LinearLayout&gt;</span>
|
|
</pre></div>
|
|
|
|
<p>Note that I defined the TextViews to have a maximum of 4 lines (actual number is up to you), and a minimum height of <code>android:listPreferredItemHeight</code> (this I recommend, otherwise it looks wonky and off-center). And just be clear, the <em>ids</em> of these fields must be <code>@+id/item_icon</code>, <code>@android:id/text1</code>, and <code>@+id/checkbox</code>, or the code WILL crash on you.</p>
|
|
|
|
<h3 id="code">Code</h3>
|
|
|
|
<p>To use the new layouts, you need to override the <code>onCreateViewHolder</code> method in
|
|
<a href="https://github.com/spacecowboy/NoNonsense-FilePicker/blob/master/library/src/main/java/com/nononsenseapps/filepicker/AbstractFilePickerFragment.java">AbstractFilePickerFragment</a>.</p>
|
|
|
|
<p>Since this example will be browsing the SD-card, I will extend from the built-in FilePickerFragment.</p>
|
|
<div class="highlight" style="background: #f0f0f0"><pre style="line-height: 125%"><span></span><span style="color: #007020; font-weight: bold">public</span> <span style="color: #007020; font-weight: bold">class</span> <span style="color: #0e84b5; font-weight: bold">CustomLayoutFilePickerFragment</span> <span style="color: #007020; font-weight: bold">extends</span> FilePickerFragment <span style="color: #666666">{</span>
|
|
<span style="color: #60a0b0; font-style: italic">/**</span>
|
|
<span style="color: #60a0b0; font-style: italic"> * @param parent Containing view</span>
|
|
<span style="color: #60a0b0; font-style: italic"> * @param viewType which the ViewHolder will contain. Will be one of:</span>
|
|
<span style="color: #60a0b0; font-style: italic"> * [VIEWTYPE_HEADER, VIEWTYPE_CHECKABLE, VIEWTYPE_DIR]. It is OK, and even expected, to use the same</span>
|
|
<span style="color: #60a0b0; font-style: italic"> * layout for VIEWTYPE_HEADER and VIEWTYPE_DIR.</span>
|
|
<span style="color: #60a0b0; font-style: italic"> * @return a view holder for a file or directory (the difference is presence of checkbox).</span>
|
|
<span style="color: #60a0b0; font-style: italic"> */</span>
|
|
<span style="color: #555555; font-weight: bold">@Override</span>
|
|
<span style="color: #007020; font-weight: bold">public</span> RecyclerView<span style="color: #666666">.</span><span style="color: #4070a0">ViewHolder</span> <span style="color: #06287e">onCreateViewHolder</span><span style="color: #666666">(</span>ViewGroup parent<span style="color: #666666">,</span> <span style="color: #902000">int</span> viewType<span style="color: #666666">)</span> <span style="color: #666666">{</span>
|
|
View v<span style="color: #666666">;</span>
|
|
<span style="color: #007020; font-weight: bold">switch</span> <span style="color: #666666">(</span>viewType<span style="color: #666666">)</span> <span style="color: #666666">{</span>
|
|
<span style="color: #007020; font-weight: bold">case</span> LogicHandler<span style="color: #666666">.</span><span style="color: #4070a0">VIEWTYPE_HEADER</span><span style="color: #666666">:</span>
|
|
v <span style="color: #666666">=</span> LayoutInflater<span style="color: #666666">.</span><span style="color: #4070a0">from</span><span style="color: #666666">(</span>getActivity<span style="color: #666666">()).</span><span style="color: #4070a0">inflate</span><span style="color: #666666">(</span>R<span style="color: #666666">.</span><span style="color: #4070a0">layout</span><span style="color: #666666">.</span><span style="color: #4070a0">longer_listitem_dir</span><span style="color: #666666">,</span>
|
|
parent<span style="color: #666666">,</span> <span style="color: #007020; font-weight: bold">false</span><span style="color: #666666">);</span>
|
|
<span style="color: #007020; font-weight: bold">return</span> <span style="color: #007020; font-weight: bold">new</span> HeaderViewHolder<span style="color: #666666">(</span>v<span style="color: #666666">);</span>
|
|
<span style="color: #007020; font-weight: bold">case</span> LogicHandler<span style="color: #666666">.</span><span style="color: #4070a0">VIEWTYPE_CHECKABLE</span><span style="color: #666666">:</span>
|
|
v <span style="color: #666666">=</span> LayoutInflater<span style="color: #666666">.</span><span style="color: #4070a0">from</span><span style="color: #666666">(</span>getActivity<span style="color: #666666">()).</span><span style="color: #4070a0">inflate</span><span style="color: #666666">(</span>R<span style="color: #666666">.</span><span style="color: #4070a0">layout</span><span style="color: #666666">.</span><span style="color: #4070a0">longer_listitem_checkable</span><span style="color: #666666">,</span>
|
|
parent<span style="color: #666666">,</span> <span style="color: #007020; font-weight: bold">false</span><span style="color: #666666">);</span>
|
|
<span style="color: #007020; font-weight: bold">return</span> <span style="color: #007020; font-weight: bold">new</span> CheckableViewHolder<span style="color: #666666">(</span>v<span style="color: #666666">);</span>
|
|
<span style="color: #007020; font-weight: bold">case</span> LogicHandler<span style="color: #666666">.</span><span style="color: #4070a0">VIEWTYPE_DIR</span><span style="color: #666666">:</span>
|
|
<span style="color: #007020; font-weight: bold">default</span><span style="color: #666666">:</span>
|
|
v <span style="color: #666666">=</span> LayoutInflater<span style="color: #666666">.</span><span style="color: #4070a0">from</span><span style="color: #666666">(</span>getActivity<span style="color: #666666">()).</span><span style="color: #4070a0">inflate</span><span style="color: #666666">(</span>R<span style="color: #666666">.</span><span style="color: #4070a0">layout</span><span style="color: #666666">.</span><span style="color: #4070a0">longer_listitem_dir</span><span style="color: #666666">,</span>
|
|
parent<span style="color: #666666">,</span> <span style="color: #007020; font-weight: bold">false</span><span style="color: #666666">);</span>
|
|
<span style="color: #007020; font-weight: bold">return</span> <span style="color: #007020; font-weight: bold">new</span> DirViewHolder<span style="color: #666666">(</span>v<span style="color: #666666">);</span>
|
|
<span style="color: #666666">}</span>
|
|
<span style="color: #666666">}</span>
|
|
<span style="color: #666666">}</span>
|
|
</pre></div>
|
|
|
|
<p>And as always, to use your custom fragment you need a custom activity which loads it for you:</p>
|
|
<div class="highlight" style="background: #f0f0f0"><pre style="line-height: 125%"><span></span><span style="color: #007020; font-weight: bold">public</span> <span style="color: #007020; font-weight: bold">class</span> <span style="color: #0e84b5; font-weight: bold">CustomLayoutPickerActivity</span> <span style="color: #007020; font-weight: bold">extends</span> AbstractFilePickerActivity <span style="color: #666666">{</span>
|
|
|
|
<span style="color: #007020; font-weight: bold">public</span> <span style="color: #06287e">CustomLayoutPickerActivity</span><span style="color: #666666">()</span> <span style="color: #666666">{</span>
|
|
<span style="color: #007020; font-weight: bold">super</span><span style="color: #666666">();</span>
|
|
<span style="color: #666666">}</span>
|
|
|
|
<span style="color: #555555; font-weight: bold">@Override</span>
|
|
<span style="color: #007020; font-weight: bold">protected</span> AbstractFilePickerFragment<span style="color: #666666">&lt;</span>File<span style="color: #666666">&gt;</span> <span style="color: #06287e">getFragment</span><span style="color: #666666">(</span>
|
|
<span style="color: #007020; font-weight: bold">final</span> String startPath<span style="color: #666666">,</span> <span style="color: #007020; font-weight: bold">final</span> <span style="color: #902000">int</span> mode<span style="color: #666666">,</span> <span style="color: #007020; font-weight: bold">final</span> <span style="color: #902000">boolean</span> allowMultiple<span style="color: #666666">,</span>
|
|
<span style="color: #007020; font-weight: bold">final</span> <span style="color: #902000">boolean</span> allowCreateDir<span style="color: #666666">)</span> <span style="color: #666666">{</span>
|
|
<span style="color: #60a0b0; font-style: italic">// Load our custom fragment here</span>
|
|
AbstractFilePickerFragment<span style="color: #666666">&lt;</span>File<span style="color: #666666">&gt;</span> fragment <span style="color: #666666">=</span> <span style="color: #007020; font-weight: bold">new</span> CustomLayoutFilePickerFragment<span style="color: #666666">();</span>
|
|
<span style="color: #60a0b0; font-style: italic">// startPath is allowed to be null. In that case, default folder should be SD-card and not &quot;/&quot;</span>
|
|
fragment<span style="color: #666666">.</span><span style="color: #4070a0">setArgs</span><span style="color: #666666">(</span>startPath <span style="color: #666666">!=</span> <span style="color: #007020; font-weight: bold">null</span> <span style="color: #666666">?</span> startPath <span style="color: #666666">:</span> Environment<span style="color: #666666">.</span><span style="color: #4070a0">getExternalStorageDirectory</span><span style="color: #666666">().</span><span style="color: #4070a0">getPath</span><span style="color: #666666">(),</span>
|
|
mode<span style="color: #666666">,</span> allowMultiple<span style="color: #666666">,</span> allowCreateDir<span style="color: #666666">);</span>
|
|
<span style="color: #007020; font-weight: bold">return</span> fragment<span style="color: #666666">;</span>
|
|
<span style="color: #666666">}</span>
|
|
<span style="color: #666666">}</span>
|
|
</pre></div>
|
|
</description>
|
|
</item>
|
|
|
|
<item>
|
|
<title>Change the sort order</title>
|
|
<link>http://localhost:1313/NoNonsense-FilePicker/example/sortorder/</link>
|
|
<pubDate>Sat, 16 Jul 2016 17:10:46 +0200</pubDate>
|
|
|
|
<guid>http://localhost:1313/NoNonsense-FilePicker/example/sortorder/</guid>
|
|
<description>
|
|
|
|
<p>By default, the SD-card picker will display all files in alphabetical order. But what if you want a different sort-order?</p>
|
|
|
|
<p>You can override the sorting by overriding the <code>compareFiles</code>-method:</p>
|
|
<div class="highlight" style="background: #f0f0f0"><pre style="line-height: 125%"><span></span> <span style="color: #555555; font-weight: bold">@Override</span>
|
|
<span style="color: #007020; font-weight: bold">protected</span> <span style="color: #902000">int</span> <span style="color: #06287e">compareFiles</span><span style="color: #666666">(</span>File lhs<span style="color: #666666">,</span> File rhs<span style="color: #666666">)</span> <span style="color: #666666">{</span>
|
|
<span style="color: #007020; font-weight: bold">if</span> <span style="color: #666666">(</span>lhs<span style="color: #666666">.</span><span style="color: #4070a0">isDirectory</span><span style="color: #666666">()</span> <span style="color: #666666">&amp;&amp;</span> <span style="color: #666666">!</span>rhs<span style="color: #666666">.</span><span style="color: #4070a0">isDirectory</span><span style="color: #666666">())</span> <span style="color: #666666">{</span>
|
|
<span style="color: #007020; font-weight: bold">return</span> <span style="color: #666666">-</span><span style="color: #40a070">1</span><span style="color: #666666">;</span>
|
|
<span style="color: #666666">}</span> <span style="color: #007020; font-weight: bold">else</span> <span style="color: #007020; font-weight: bold">if</span> <span style="color: #666666">(</span>rhs<span style="color: #666666">.</span><span style="color: #4070a0">isDirectory</span><span style="color: #666666">()</span> <span style="color: #666666">&amp;&amp;</span> <span style="color: #666666">!</span>lhs<span style="color: #666666">.</span><span style="color: #4070a0">isDirectory</span><span style="color: #666666">())</span> <span style="color: #666666">{</span>
|
|
<span style="color: #007020; font-weight: bold">return</span> <span style="color: #40a070">1</span><span style="color: #666666">;</span>
|
|
<span style="color: #666666">}</span>
|
|
<span style="color: #60a0b0; font-style: italic">// This was the previous behaviour for all file-file comparisons. Now it&#39;s</span>
|
|
<span style="color: #60a0b0; font-style: italic">// only done if the files have the same extension, or no extension.</span>
|
|
<span style="color: #007020; font-weight: bold">else</span> <span style="color: #007020; font-weight: bold">if</span> <span style="color: #666666">(</span>getExtension<span style="color: #666666">(</span>lhs<span style="color: #666666">)</span> <span style="color: #666666">!=</span> <span style="color: #007020; font-weight: bold">null</span> <span style="color: #666666">&amp;&amp;</span> getExtension<span style="color: #666666">(</span>lhs<span style="color: #666666">).</span><span style="color: #4070a0">equalsIgnoreCase</span><span style="color: #666666">(</span>getExtension<span style="color: #666666">(</span>rhs<span style="color: #666666">))</span> <span style="color: #666666">||</span>
|
|
getExtension<span style="color: #666666">(</span>lhs<span style="color: #666666">)</span> <span style="color: #666666">==</span> <span style="color: #007020; font-weight: bold">null</span> <span style="color: #666666">&amp;&amp;</span> getExtension<span style="color: #666666">(</span>rhs<span style="color: #666666">)</span> <span style="color: #666666">==</span> <span style="color: #007020; font-weight: bold">null</span><span style="color: #666666">)</span> <span style="color: #666666">{</span>
|
|
<span style="color: #007020; font-weight: bold">return</span> lhs<span style="color: #666666">.</span><span style="color: #4070a0">getName</span><span style="color: #666666">().</span><span style="color: #4070a0">compareToIgnoreCase</span><span style="color: #666666">(</span>rhs<span style="color: #666666">.</span><span style="color: #4070a0">getName</span><span style="color: #666666">());</span>
|
|
<span style="color: #666666">}</span>
|
|
<span style="color: #60a0b0; font-style: italic">// Otherwise, we sort on extension placing files with no extension last.</span>
|
|
<span style="color: #007020; font-weight: bold">else</span> <span style="color: #007020; font-weight: bold">if</span> <span style="color: #666666">(</span>getExtension<span style="color: #666666">(</span>lhs<span style="color: #666666">)</span> <span style="color: #666666">!=</span> <span style="color: #007020; font-weight: bold">null</span> <span style="color: #666666">&amp;&amp;</span> getExtension<span style="color: #666666">(</span>rhs<span style="color: #666666">)</span> <span style="color: #666666">!=</span> <span style="color: #007020; font-weight: bold">null</span><span style="color: #666666">)</span> <span style="color: #666666">{</span>
|
|
<span style="color: #60a0b0; font-style: italic">// Both have extension, just compare extensions</span>
|
|
<span style="color: #007020; font-weight: bold">return</span> getExtension<span style="color: #666666">(</span>lhs<span style="color: #666666">).</span><span style="color: #4070a0">compareToIgnoreCase</span><span style="color: #666666">(</span>getExtension<span style="color: #666666">(</span>rhs<span style="color: #666666">));</span>
|
|
<span style="color: #666666">}</span> <span style="color: #007020; font-weight: bold">else</span> <span style="color: #007020; font-weight: bold">if</span> <span style="color: #666666">(</span>getExtension<span style="color: #666666">(</span>lhs<span style="color: #666666">)</span> <span style="color: #666666">!=</span> <span style="color: #007020; font-weight: bold">null</span><span style="color: #666666">)</span> <span style="color: #666666">{</span>
|
|
<span style="color: #60a0b0; font-style: italic">// Left has extension, place it first</span>
|
|
<span style="color: #007020; font-weight: bold">return</span> <span style="color: #666666">-</span><span style="color: #40a070">1</span><span style="color: #666666">;</span>
|
|
<span style="color: #666666">}</span> <span style="color: #007020; font-weight: bold">else</span> <span style="color: #666666">{</span>
|
|
<span style="color: #60a0b0; font-style: italic">// Right has extension, place it first</span>
|
|
<span style="color: #007020; font-weight: bold">return</span> <span style="color: #40a070">1</span><span style="color: #666666">;</span>
|
|
<span style="color: #666666">}</span>
|
|
<span style="color: #666666">}</span>
|
|
</pre></div>
|
|
|
|
<h3 id="before-and-after">Before and After</h3>
|
|
|
|
<p><img src="http://localhost:1313/NoNonsense-FilePicker/screenshots/sorting_before.png" width="30%" alt="Before"/>
|
|
<img src="http://localhost:1313/NoNonsense-FilePicker/screenshots/sorting_after.png" width="30%" alt="After"/></p>
|
|
|
|
<h3 id="full-fragment-code">Full Fragment code</h3>
|
|
<div class="highlight" style="background: #f0f0f0"><pre style="line-height: 125%"><span></span><span style="color: #007020; font-weight: bold">import</span> <span style="color: #0e84b5; font-weight: bold">com.nononsenseapps.filepicker.FilePickerFragment</span><span style="color: #666666">;</span>
|
|
|
|
<span style="color: #007020; font-weight: bold">import</span> <span style="color: #0e84b5; font-weight: bold">java.io.File</span><span style="color: #666666">;</span>
|
|
|
|
<span style="color: #007020; font-weight: bold">public</span> <span style="color: #007020; font-weight: bold">class</span> <span style="color: #0e84b5; font-weight: bold">SortedFilePickerFragment</span> <span style="color: #007020; font-weight: bold">extends</span> FilePickerFragment <span style="color: #666666">{</span>
|
|
|
|
<span style="color: #60a0b0; font-style: italic">/**</span>
|
|
<span style="color: #60a0b0; font-style: italic"> *</span>
|
|
<span style="color: #60a0b0; font-style: italic"> * @param file</span>
|
|
<span style="color: #60a0b0; font-style: italic"> * @return The file extension. If file has no extension, it returns null.</span>
|
|
<span style="color: #60a0b0; font-style: italic"> */</span>
|
|
<span style="color: #007020; font-weight: bold">private</span> String <span style="color: #06287e">getExtension</span><span style="color: #666666">(</span><span style="color: #555555; font-weight: bold">@NonNull</span> File file<span style="color: #666666">)</span> <span style="color: #666666">{</span>
|
|
String path <span style="color: #666666">=</span> file<span style="color: #666666">.</span><span style="color: #4070a0">getPath</span><span style="color: #666666">();</span>
|
|
<span style="color: #902000">int</span> i <span style="color: #666666">=</span> path<span style="color: #666666">.</span><span style="color: #4070a0">lastIndexOf</span><span style="color: #666666">(</span><span style="color: #4070a0">&quot;.&quot;</span><span style="color: #666666">);</span>
|
|
<span style="color: #007020; font-weight: bold">if</span> <span style="color: #666666">(</span>i <span style="color: #666666">&lt;</span> <span style="color: #40a070">0</span><span style="color: #666666">)</span> <span style="color: #666666">{</span>
|
|
<span style="color: #007020; font-weight: bold">return</span> <span style="color: #007020; font-weight: bold">null</span><span style="color: #666666">;</span>
|
|
<span style="color: #666666">}</span> <span style="color: #007020; font-weight: bold">else</span> <span style="color: #666666">{</span>
|
|
<span style="color: #007020; font-weight: bold">return</span> path<span style="color: #666666">.</span><span style="color: #4070a0">substring</span><span style="color: #666666">(</span>i<span style="color: #666666">);</span>
|
|
<span style="color: #666666">}</span>
|
|
<span style="color: #666666">}</span>
|
|
|
|
<span style="color: #60a0b0; font-style: italic">/**</span>
|
|
<span style="color: #60a0b0; font-style: italic"> * Compare two files to determine their relative sort order. This follows the usual</span>
|
|
<span style="color: #60a0b0; font-style: italic"> * comparison interface. Override to determine your own custom sort order.</span>
|
|
<span style="color: #60a0b0; font-style: italic"> *</span>
|
|
<span style="color: #60a0b0; font-style: italic"> * @param lhs File on the &quot;left-hand side&quot;</span>
|
|
<span style="color: #60a0b0; font-style: italic"> * @param rhs File on the &quot;right-hand side&quot;</span>
|
|
<span style="color: #60a0b0; font-style: italic"> * @return -1 if if lhs should be placed before rhs, 0 if they are equal,</span>
|
|
<span style="color: #60a0b0; font-style: italic"> * and 1 if rhs should be placed before lhs</span>
|
|
<span style="color: #60a0b0; font-style: italic"> */</span>
|
|
<span style="color: #555555; font-weight: bold">@Override</span>
|
|
<span style="color: #007020; font-weight: bold">protected</span> <span style="color: #902000">int</span> <span style="color: #06287e">compareFiles</span><span style="color: #666666">(</span>File lhs<span style="color: #666666">,</span> File rhs<span style="color: #666666">)</span> <span style="color: #666666">{</span>
|
|
<span style="color: #007020; font-weight: bold">if</span> <span style="color: #666666">(</span>lhs<span style="color: #666666">.</span><span style="color: #4070a0">isDirectory</span><span style="color: #666666">()</span> <span style="color: #666666">&amp;&amp;</span> <span style="color: #666666">!</span>rhs<span style="color: #666666">.</span><span style="color: #4070a0">isDirectory</span><span style="color: #666666">())</span> <span style="color: #666666">{</span>
|
|
<span style="color: #007020; font-weight: bold">return</span> <span style="color: #666666">-</span><span style="color: #40a070">1</span><span style="color: #666666">;</span>
|
|
<span style="color: #666666">}</span> <span style="color: #007020; font-weight: bold">else</span> <span style="color: #007020; font-weight: bold">if</span> <span style="color: #666666">(</span>rhs<span style="color: #666666">.</span><span style="color: #4070a0">isDirectory</span><span style="color: #666666">()</span> <span style="color: #666666">&amp;&amp;</span> <span style="color: #666666">!</span>lhs<span style="color: #666666">.</span><span style="color: #4070a0">isDirectory</span><span style="color: #666666">())</span> <span style="color: #666666">{</span>
|
|
<span style="color: #007020; font-weight: bold">return</span> <span style="color: #40a070">1</span><span style="color: #666666">;</span>
|
|
<span style="color: #666666">}</span>
|
|
<span style="color: #60a0b0; font-style: italic">// This was the previous behaviour for all file-file comparisons. Now it&#39;s</span>
|
|
<span style="color: #60a0b0; font-style: italic">// only done if the files have the same extension, or no extension.</span>
|
|
<span style="color: #007020; font-weight: bold">else</span> <span style="color: #007020; font-weight: bold">if</span> <span style="color: #666666">(</span>getExtension<span style="color: #666666">(</span>lhs<span style="color: #666666">)</span> <span style="color: #666666">!=</span> <span style="color: #007020; font-weight: bold">null</span> <span style="color: #666666">&amp;&amp;</span> getExtension<span style="color: #666666">(</span>lhs<span style="color: #666666">).</span><span style="color: #4070a0">equalsIgnoreCase</span><span style="color: #666666">(</span>getExtension<span style="color: #666666">(</span>rhs<span style="color: #666666">))</span> <span style="color: #666666">||</span>
|
|
getExtension<span style="color: #666666">(</span>lhs<span style="color: #666666">)</span> <span style="color: #666666">==</span> <span style="color: #007020; font-weight: bold">null</span> <span style="color: #666666">&amp;&amp;</span> getExtension<span style="color: #666666">(</span>rhs<span style="color: #666666">)</span> <span style="color: #666666">==</span> <span style="color: #007020; font-weight: bold">null</span><span style="color: #666666">)</span> <span style="color: #666666">{</span>
|
|
<span style="color: #007020; font-weight: bold">return</span> lhs<span style="color: #666666">.</span><span style="color: #4070a0">getName</span><span style="color: #666666">().</span><span style="color: #4070a0">compareToIgnoreCase</span><span style="color: #666666">(</span>rhs<span style="color: #666666">.</span><span style="color: #4070a0">getName</span><span style="color: #666666">());</span>
|
|
<span style="color: #666666">}</span>
|
|
<span style="color: #60a0b0; font-style: italic">// Otherwise, we sort on extension placing files with no extension last.</span>
|
|
<span style="color: #007020; font-weight: bold">else</span> <span style="color: #007020; font-weight: bold">if</span> <span style="color: #666666">(</span>getExtension<span style="color: #666666">(</span>lhs<span style="color: #666666">)</span> <span style="color: #666666">!=</span> <span style="color: #007020; font-weight: bold">null</span> <span style="color: #666666">&amp;&amp;</span> getExtension<span style="color: #666666">(</span>rhs<span style="color: #666666">)</span> <span style="color: #666666">!=</span> <span style="color: #007020; font-weight: bold">null</span><span style="color: #666666">)</span> <span style="color: #666666">{</span>
|
|
<span style="color: #60a0b0; font-style: italic">// Both have extension, just compare extensions</span>
|
|
<span style="color: #007020; font-weight: bold">return</span> getExtension<span style="color: #666666">(</span>lhs<span style="color: #666666">).</span><span style="color: #4070a0">compareToIgnoreCase</span><span style="color: #666666">(</span>getExtension<span style="color: #666666">(</span>rhs<span style="color: #666666">));</span>
|
|
<span style="color: #666666">}</span> <span style="color: #007020; font-weight: bold">else</span> <span style="color: #007020; font-weight: bold">if</span> <span style="color: #666666">(</span>getExtension<span style="color: #666666">(</span>lhs<span style="color: #666666">)</span> <span style="color: #666666">!=</span> <span style="color: #007020; font-weight: bold">null</span><span style="color: #666666">)</span> <span style="color: #666666">{</span>
|
|
<span style="color: #60a0b0; font-style: italic">// Left has extension, place it first</span>
|
|
<span style="color: #007020; font-weight: bold">return</span> <span style="color: #666666">-</span><span style="color: #40a070">1</span><span style="color: #666666">;</span>
|
|
<span style="color: #666666">}</span> <span style="color: #007020; font-weight: bold">else</span> <span style="color: #666666">{</span>
|
|
<span style="color: #60a0b0; font-style: italic">// Right has extension, place it first</span>
|
|
<span style="color: #007020; font-weight: bold">return</span> <span style="color: #40a070">1</span><span style="color: #666666">;</span>
|
|
<span style="color: #666666">}</span>
|
|
<span style="color: #666666">}</span>
|
|
<span style="color: #666666">}</span>
|
|
</pre></div>
|
|
</description>
|
|
</item>
|
|
|
|
</channel>
|
|
</rss> |