mirror of
https://github.com/stom79/exodus-android-app
synced 2025-02-04 10:07:30 +01:00
Merge branch 'stom79-filter_app'
This commit is contained in:
commit
2a09ff9819
@ -19,11 +19,16 @@
|
||||
package org.eu.exodus_privacy.exodusprivacy;
|
||||
|
||||
import android.support.v4.app.FragmentManager;
|
||||
import android.content.Context;
|
||||
import android.databinding.DataBindingUtil;
|
||||
import android.support.design.widget.Snackbar;
|
||||
import android.support.v4.app.FragmentTransaction;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.os.Bundle;
|
||||
import android.support.v7.widget.SearchView;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
|
||||
import org.eu.exodus_privacy.exodusprivacy.adapters.ApplicationListAdapter;
|
||||
import org.eu.exodus_privacy.exodusprivacy.databinding.MainBinding;
|
||||
@ -35,6 +40,8 @@ public class MainActivity extends AppCompatActivity {
|
||||
|
||||
AppListFragment appList;
|
||||
ReportFragment report;
|
||||
SearchView searchView;
|
||||
private Menu mMenu;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
@ -76,6 +83,14 @@ public class MainActivity extends AppCompatActivity {
|
||||
.replace(R.id.fragment_container,report)
|
||||
.addToBackStack(null)
|
||||
.commit();
|
||||
|
||||
searchView.clearFocus();
|
||||
if (mMenu != null)
|
||||
(mMenu.findItem(R.id.action_filter)).collapseActionView();
|
||||
InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
assert imm != null;
|
||||
imm.hideSoftInputFromWindow(mainBinding.fragmentContainer.getWindowToken(), 0);
|
||||
|
||||
};
|
||||
|
||||
appList = AppListFragment.newInstance(networkListener,onAppClickListener);
|
||||
@ -94,4 +109,28 @@ public class MainActivity extends AppCompatActivity {
|
||||
else
|
||||
getSupportFragmentManager().popBackStack();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
mMenu = menu;
|
||||
MenuInflater inflater = getMenuInflater();
|
||||
inflater.inflate(R.menu.main, menu);
|
||||
searchView = (SearchView) menu.findItem(R.id.action_filter).getActionView();
|
||||
searchView.setIconifiedByDefault(false);
|
||||
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
|
||||
@Override
|
||||
public boolean onQueryTextSubmit(String query) {
|
||||
appList.filter(query);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onQueryTextChange(String newText) {
|
||||
appList.filter(newText);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -22,32 +22,33 @@ import android.content.Context;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.databinding.DataBindingUtil;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.eu.exodus_privacy.exodusprivacy.R;
|
||||
import org.eu.exodus_privacy.exodusprivacy.databinding.AppItemBinding;
|
||||
import org.eu.exodus_privacy.exodusprivacy.manager.DatabaseManager;
|
||||
import org.eu.exodus_privacy.exodusprivacy.objects.Report;
|
||||
import org.eu.exodus_privacy.exodusprivacy.objects.Tracker;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class ApplicationListAdapter extends android.support.v7.widget.RecyclerView.Adapter<ApplicationListAdapter.ApplicationListViewHolder>{
|
||||
public class ApplicationListAdapter extends RecyclerView.Adapter {
|
||||
|
||||
private List<PackageInfo> packages;
|
||||
private PackageManager packageManager;
|
||||
private OnAppClickListener onAppClickListener;
|
||||
private static final String gStore = "com.android.vending";
|
||||
private String filter = "";
|
||||
private final int HIDDEN_APP = 0;
|
||||
private final int DISPLAYED_APP = 1;
|
||||
|
||||
|
||||
private Comparator<PackageInfo> alphaPackageComparator = new Comparator<PackageInfo>() {
|
||||
@Override
|
||||
@ -66,13 +67,13 @@ public class ApplicationListAdapter extends android.support.v7.widget.RecyclerVi
|
||||
private void setInstalledPackages(List<PackageInfo> installedPackages) {
|
||||
packages = installedPackages;
|
||||
applyStoreFilter();
|
||||
Collections.sort(packages,alphaPackageComparator);
|
||||
Collections.sort(packages, alphaPackageComparator);
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
private void applyStoreFilter() {
|
||||
List<PackageInfo> toRemove = new ArrayList<>();
|
||||
for(PackageInfo pkg : packages) {
|
||||
for (PackageInfo pkg : packages) {
|
||||
if (!gStore.equals(packageManager.getInstallerPackageName(pkg.packageName))) {
|
||||
toRemove.add(pkg);
|
||||
}
|
||||
@ -81,22 +82,40 @@ public class ApplicationListAdapter extends android.support.v7.widget.RecyclerVi
|
||||
}
|
||||
|
||||
@Override
|
||||
public ApplicationListViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||
AppItemBinding appItemBinding = DataBindingUtil.inflate(LayoutInflater.from(parent.getContext()),R.layout.app_item,parent,false);
|
||||
return new ApplicationListViewHolder(appItemBinding);
|
||||
public int getItemViewType(int position){
|
||||
return (Pattern.compile(Pattern.quote(filter.trim()), Pattern.CASE_INSENSITIVE).matcher(packageManager.getApplicationLabel(packages.get(position).applicationInfo)).find())?DISPLAYED_APP:HIDDEN_APP;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
if( viewType == HIDDEN_APP)
|
||||
return new ApplicationEmptyViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.app_item_empty, parent, false));
|
||||
else
|
||||
return new ApplicationListViewHolder(DataBindingUtil.inflate(LayoutInflater.from(parent.getContext()), R.layout.app_item, parent, false));
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(ApplicationListViewHolder holder, int position) {
|
||||
holder.setData(packages.get(position));
|
||||
holder.itemView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
onAppClickListener.onAppClick(holder.packageInfo);
|
||||
}
|
||||
});
|
||||
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position) {
|
||||
if( viewHolder.getItemViewType() == DISPLAYED_APP) {
|
||||
final ApplicationListViewHolder holder = (ApplicationListViewHolder) viewHolder;
|
||||
holder.setData(packages.get(position));
|
||||
//noinspection Convert2Lambda
|
||||
holder.itemView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
onAppClickListener.onAppClick(holder.packageInfo);
|
||||
}
|
||||
});
|
||||
}else {
|
||||
//noinspection unused
|
||||
final ApplicationEmptyViewHolder holder = (ApplicationEmptyViewHolder) viewHolder;
|
||||
//If something should be done for app that are hidden, it's here
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return packages.size();
|
||||
@ -110,6 +129,13 @@ public class ApplicationListAdapter extends android.support.v7.widget.RecyclerVi
|
||||
}
|
||||
}
|
||||
|
||||
class ApplicationEmptyViewHolder extends RecyclerView.ViewHolder{
|
||||
ApplicationEmptyViewHolder(View itemView) {
|
||||
super(itemView);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class ApplicationListViewHolder extends RecyclerView.ViewHolder {
|
||||
|
||||
PackageInfo packageInfo;
|
||||
@ -168,4 +194,10 @@ public class ApplicationListAdapter extends android.support.v7.widget.RecyclerVi
|
||||
public interface OnAppClickListener {
|
||||
void onAppClick(PackageInfo packageInfo);
|
||||
}
|
||||
|
||||
|
||||
public void filter(String text) {
|
||||
filter = text;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
|
@ -48,6 +48,7 @@ public class AppListFragment extends Fragment {
|
||||
private ApplicationListAdapter.OnAppClickListener onAppClickListener;
|
||||
private boolean startupRefresh;
|
||||
private ApplistBinding applistBinding;
|
||||
private ApplicationListAdapter adapter;
|
||||
|
||||
public static AppListFragment newInstance(NetworkListener networkListener, ApplicationListAdapter.OnAppClickListener appClickListener) {
|
||||
AppListFragment fragment = new AppListFragment();
|
||||
@ -86,7 +87,7 @@ public class AppListFragment extends Fragment {
|
||||
}
|
||||
applistBinding.noPackageManager.setVisibility(View.GONE);
|
||||
applistBinding.noAppFound.setVisibility(View.GONE);
|
||||
ApplicationListAdapter adapter = new ApplicationListAdapter(packageManager, onAppClickListener);
|
||||
adapter = new ApplicationListAdapter(packageManager, onAppClickListener);
|
||||
if(adapter.getItemCount() == 0) {
|
||||
applistBinding.noAppFound.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
@ -170,4 +171,8 @@ public class AppListFragment extends Fragment {
|
||||
super.onDetach();
|
||||
packageManager = null;
|
||||
}
|
||||
|
||||
public void filter(String filter){
|
||||
adapter.filter(filter);
|
||||
}
|
||||
}
|
||||
|
@ -28,6 +28,8 @@ import android.os.Bundle;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
@ -61,6 +63,7 @@ public class ReportFragment extends Fragment {
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setHasOptionsMenu(true);
|
||||
}
|
||||
|
||||
|
||||
@ -178,4 +181,10 @@ public class ReportFragment extends Fragment {
|
||||
public void setPackageInfo(PackageInfo packageInfo) {
|
||||
this.packageInfo = packageInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPrepareOptionsMenu(Menu menu) {
|
||||
MenuItem item = menu.findItem(R.id.action_filter);
|
||||
item.setVisible(false);
|
||||
}
|
||||
}
|
||||
|
BIN
app/src/main/res/drawable-hdpi/ic_search.png
Normal file
BIN
app/src/main/res/drawable-hdpi/ic_search.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 448 B |
BIN
app/src/main/res/drawable-ldpi/ic_search.png
Normal file
BIN
app/src/main/res/drawable-ldpi/ic_search.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 384 B |
BIN
app/src/main/res/drawable-mdpi/ic_search.png
Normal file
BIN
app/src/main/res/drawable-mdpi/ic_search.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 265 B |
BIN
app/src/main/res/drawable-xhdpi/ic_search.png
Normal file
BIN
app/src/main/res/drawable-xhdpi/ic_search.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 492 B |
BIN
app/src/main/res/drawable-xxhdpi/ic_search.png
Normal file
BIN
app/src/main/res/drawable-xxhdpi/ic_search.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 744 B |
BIN
app/src/main/res/drawable-xxxhdpi/ic_search.png
Normal file
BIN
app/src/main/res/drawable-xxxhdpi/ic_search.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 967 B |
5
app/src/main/res/layout/app_item_empty.xml
Normal file
5
app/src/main/res/layout/app_item_empty.xml
Normal file
@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="gone"/>
|
10
app/src/main/res/menu/main.xml
Normal file
10
app/src/main/res/menu/main.xml
Normal file
@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
<item
|
||||
android:id="@+id/action_filter"
|
||||
android:icon="@drawable/ic_search"
|
||||
android:title="@string/menu_action_filter"
|
||||
app:actionViewClass="android.support.v7.widget.SearchView"
|
||||
app:showAsAction="ifRoom|collapseActionView" />
|
||||
</menu>
|
@ -20,4 +20,7 @@
|
||||
<string name="parse_trackers">Traitement des pisteurs :</string>
|
||||
<string name="get_trackers_connection">Récupération des pisteurs : en attente de connexion au serveur</string>
|
||||
<string name="get_trackers">Récupération des pisteurs</string>
|
||||
|
||||
<!-- Menu -->
|
||||
<string name="menu_action_filter">Filtrer</string>
|
||||
</resources>
|
||||
|
@ -20,4 +20,7 @@
|
||||
<string name="parse_trackers">Processing Trackers:</string>
|
||||
<string name="get_trackers_connection">Getting trackers: Waiting for server connection</string>
|
||||
<string name="get_trackers">Getting trackers</string>
|
||||
|
||||
<!-- Menu -->
|
||||
<string name="menu_action_filter">Filter</string>
|
||||
</resources>
|
||||
|
Loading…
x
Reference in New Issue
Block a user