mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge
synced 2024-11-08 19:27:04 +01:00
Data Management: Add basic search to file manager
This commit is contained in:
parent
c9e4379346
commit
d033c5e33e
@ -17,10 +17,16 @@
|
||||
package nodomain.freeyourgadget.gadgetbridge.activities.files;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.ActionBar;
|
||||
import androidx.appcompat.widget.SearchView;
|
||||
import androidx.core.view.MenuProvider;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
@ -35,15 +41,18 @@ import nodomain.freeyourgadget.gadgetbridge.activities.AbstractGBActivity;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.FileUtils;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
||||
|
||||
public class FileManagerActivity extends AbstractGBActivity {
|
||||
public class FileManagerActivity extends AbstractGBActivity implements MenuProvider {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(FileManagerActivity.class);
|
||||
|
||||
public static final String EXTRA_PATH = "path";
|
||||
|
||||
private SearchView searchView;
|
||||
|
||||
@Override
|
||||
protected void onCreate(final Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_file_manager);
|
||||
addMenuProvider(this);
|
||||
|
||||
final RecyclerView fileListView = findViewById(R.id.fileListView);
|
||||
fileListView.setLayoutManager(new LinearLayoutManager(this));
|
||||
@ -76,6 +85,40 @@ public class FileManagerActivity extends AbstractGBActivity {
|
||||
final FileManagerAdapter appListAdapter = new FileManagerAdapter(this, directory);
|
||||
|
||||
fileListView.setAdapter(appListAdapter);
|
||||
|
||||
searchView = findViewById(R.id.fileListSearchView);
|
||||
searchView.setIconifiedByDefault(false);
|
||||
searchView.setVisibility(View.GONE);
|
||||
searchView.setIconified(false);
|
||||
searchView.setQuery("", false);
|
||||
searchView.clearFocus();
|
||||
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
|
||||
@Override
|
||||
public boolean onQueryTextSubmit(final String query) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onQueryTextChange(final String newText) {
|
||||
appListAdapter.getFilter().filter(newText);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreateMenu(@NonNull final Menu menu, @NonNull final MenuInflater menuInflater) {
|
||||
menuInflater.inflate(R.menu.menu_file_manager, menu);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onMenuItemSelected(@NonNull final MenuItem menuItem) {
|
||||
final int itemId = menuItem.getItemId();
|
||||
if (itemId == R.id.file_manager_search) {
|
||||
searchView.setVisibility(View.VISIBLE);
|
||||
searchView.requestFocus();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -21,6 +21,7 @@ import android.content.Intent;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Filter;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.PopupMenu;
|
||||
import android.widget.TextView;
|
||||
@ -36,6 +37,7 @@ import org.slf4j.LoggerFactory;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
@ -49,11 +51,13 @@ public class FileManagerAdapter extends RecyclerView.Adapter<FileManagerAdapter.
|
||||
private final List<File> fileList;
|
||||
private final Context mContext;
|
||||
|
||||
private final FileFilter fileFilter;
|
||||
|
||||
public FileManagerAdapter(final Context context, final File directory) {
|
||||
mContext = context;
|
||||
|
||||
// FIXME: This can be slow, make it async
|
||||
fileList = Arrays.asList(directory.listFiles());
|
||||
fileList = new ArrayList<>(Arrays.asList(directory.listFiles()));
|
||||
fileList.sort((f1, f2) -> {
|
||||
if (f1.isDirectory() && f2.isFile())
|
||||
return -1;
|
||||
@ -62,6 +66,8 @@ public class FileManagerAdapter extends RecyclerView.Adapter<FileManagerAdapter.
|
||||
|
||||
return String.CASE_INSENSITIVE_ORDER.compare(f1.getName(), f2.getName());
|
||||
});
|
||||
|
||||
fileFilter = new FileFilter(this, fileList);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@ -125,6 +131,10 @@ public class FileManagerAdapter extends RecyclerView.Adapter<FileManagerAdapter.
|
||||
return fileList.size();
|
||||
}
|
||||
|
||||
public Filter getFilter() {
|
||||
return fileFilter;
|
||||
}
|
||||
|
||||
public static class FileManagerViewHolder extends RecyclerView.ViewHolder {
|
||||
final ImageView icon;
|
||||
final TextView name;
|
||||
@ -149,4 +159,48 @@ public class FileManagerAdapter extends RecyclerView.Adapter<FileManagerAdapter.
|
||||
int digitGroups = (int) (Math.log10(size) / Math.log10(1024));
|
||||
return SIZE_FORMAT.format(size / Math.pow(1024, digitGroups)) + " " + units[digitGroups];
|
||||
}
|
||||
|
||||
private class FileFilter extends Filter {
|
||||
private final FileManagerAdapter adapter;
|
||||
private final List<File> originalList;
|
||||
private final List<File> filteredList;
|
||||
|
||||
private FileFilter(final FileManagerAdapter adapter, final List<File> originalList) {
|
||||
super();
|
||||
this.originalList = new ArrayList<>(originalList);
|
||||
this.filteredList = new ArrayList<>();
|
||||
this.adapter = adapter;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected FilterResults performFiltering(final CharSequence filter) {
|
||||
filteredList.clear();
|
||||
final Filter.FilterResults results = new Filter.FilterResults();
|
||||
|
||||
if (filter == null || filter.length() == 0)
|
||||
filteredList.addAll(originalList);
|
||||
else {
|
||||
final String filterPattern = filter.toString().toLowerCase().trim();
|
||||
|
||||
for (File f : originalList) {
|
||||
final CharSequence name = f.getName();
|
||||
if (name.toString().toLowerCase().contains(filterPattern)) {
|
||||
filteredList.add(f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
results.values = filteredList;
|
||||
results.count = filteredList.size();
|
||||
return results;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void publishResults(final CharSequence constraint, final FilterResults filterResults) {
|
||||
adapter.fileList.clear();
|
||||
adapter.fileList.addAll((List<File>) filterResults.values);
|
||||
adapter.notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
12
app/src/main/res/drawable/ic_search.xml
Normal file
12
app/src/main/res/drawable/ic_search.xml
Normal file
@ -0,0 +1,12 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:tint="#7E7E7E"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M15.5,14h-0.79l-0.28,-0.27C15.41,12.59 16,11.11 16,9.5 16,5.91 13.09,3 9.5,3S3,5.91 3,9.5 5.91,16 9.5,16c1.61,0 3.09,-0.59 4.23,-1.57l0.27,0.28v0.79l5,4.99L20.49,19l-4.99,-5zM9.5,14C7.01,14 5,11.99 5,9.5S7.01,5 9.5,5 14,7.01 14,9.5 11.99,14 9.5,14z" />
|
||||
|
||||
</vector>
|
@ -4,10 +4,19 @@
|
||||
android:layout_height="match_parent"
|
||||
tools:context=".activities.files.FileManagerActivity">
|
||||
|
||||
<androidx.appcompat.widget.SearchView
|
||||
android:id="@+id/fileListSearchView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentTop="true"
|
||||
android:paddingStart="8dp"
|
||||
android:paddingEnd="8dp" />
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/fileListView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_below="@id/fileListSearchView"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:divider="@null"
|
||||
android:scrollbarSize="5dp"
|
||||
|
11
app/src/main/res/menu/menu_file_manager.xml
Normal file
11
app/src/main/res/menu/menu_file_manager.xml
Normal file
@ -0,0 +1,11 @@
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
tools:context="nodomain.freeyourgadget.gadgetbridge.activities.files.FileManagerActivity">
|
||||
<item
|
||||
android:id="@+id/file_manager_search"
|
||||
android:icon="@drawable/ic_search"
|
||||
android:title="@string/search"
|
||||
app:iconTint="?attr/actionmenu_icon_color"
|
||||
app:showAsAction="always" />
|
||||
</menu>
|
@ -37,6 +37,7 @@
|
||||
<string name="action_changelog">Changelog</string>
|
||||
<string name="controlcenter_fetch_activity_data">Synchronize</string>
|
||||
<string name="controlcenter_find_device">Find lost device</string>
|
||||
<string name="search">Search</string>
|
||||
<string name="find_lost_device_message">Search for %1$s?</string>
|
||||
<string name="controlcenter_take_screenshot">Take Screenshot</string>
|
||||
<string name="controlcenter_power_off">Power Off</string>
|
||||
|
Loading…
Reference in New Issue
Block a user