diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 972079285..54b36931c 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -509,6 +509,8 @@
+
+
diff --git a/app/src/main/java/org/fdroid/fdroid/views/apps/AppListActivity.java b/app/src/main/java/org/fdroid/fdroid/views/apps/AppListActivity.java
new file mode 100644
index 000000000..e9294eaa6
--- /dev/null
+++ b/app/src/main/java/org/fdroid/fdroid/views/apps/AppListActivity.java
@@ -0,0 +1,115 @@
+package org.fdroid.fdroid.views.apps;
+
+import android.content.Intent;
+import android.database.Cursor;
+import android.os.Bundle;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.support.v4.app.LoaderManager;
+import android.support.v4.content.CursorLoader;
+import android.support.v4.content.Loader;
+import android.support.v7.app.AppCompatActivity;
+import android.support.v7.widget.LinearLayoutManager;
+import android.support.v7.widget.RecyclerView;
+import android.view.View;
+import android.widget.EditText;
+
+import org.fdroid.fdroid.R;
+import org.fdroid.fdroid.data.AppProvider;
+import org.fdroid.fdroid.data.Schema;
+
+public class AppListActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks {
+
+ public static final String EXTRA_CATEGORY = "org.fdroid.fdroid.views.apps.AppListActivity.EXTRA_CATEGORY";
+ private RecyclerView appView;
+ private AppListAdapter appAdapter;
+ private String category;
+ private String searchTerms;
+ private EditText searchInput;
+
+ @Override
+ protected void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ setContentView(R.layout.activity_app_list);
+
+ searchInput = (EditText) findViewById(R.id.search);
+
+ View backButton = findViewById(R.id.back);
+ backButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ finish();
+ }
+ });
+
+ View clearButton = findViewById(R.id.clear);
+ clearButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ searchInput.setText("");
+ }
+ });
+
+ appAdapter = new AppListAdapter(this);
+
+ appView = (RecyclerView) findViewById(R.id.app_list);
+ appView.setHasFixedSize(true);
+ appView.setLayoutManager(new LinearLayoutManager(this));
+ appView.setAdapter(appAdapter);
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+
+ Intent intent = getIntent();
+ category = intent.hasExtra(EXTRA_CATEGORY) ? intent.getStringExtra(EXTRA_CATEGORY) : null;
+
+ searchInput.setText(getSearchText(category, null));
+ searchInput.setSelection(searchInput.getText().length());
+
+ if (category != null) {
+ // Do this so that the search input does not get focus by default. This allows for a user
+ // experience where the user scrolls through the apps in the category.
+ appView.requestFocus();
+ }
+
+ getSupportLoaderManager().initLoader(0, null, this);
+ }
+
+ private CharSequence getSearchText(@Nullable String category, @Nullable String searchTerms) {
+ StringBuilder string = new StringBuilder();
+ if (category != null) {
+ string.append(category).append(' ');
+ }
+
+ if (searchTerms != null) {
+ string.append(searchTerms);
+ }
+
+ return string.toString();
+ }
+
+ @Override
+ public Loader onCreateLoader(int id, Bundle args) {
+ return new CursorLoader(
+ this,
+ AppProvider.getSearchUri(searchTerms, category),
+ Schema.AppMetadataTable.Cols.ALL,
+ null,
+ null,
+ null
+ );
+ }
+
+ @Override
+ public void onLoadFinished(Loader loader, Cursor cursor) {
+ appAdapter.setAppCursor(cursor);
+ }
+
+ @Override
+ public void onLoaderReset(Loader loader) {
+ appAdapter.setAppCursor(null);
+ }
+}
diff --git a/app/src/main/java/org/fdroid/fdroid/views/apps/AppListAdapter.java b/app/src/main/java/org/fdroid/fdroid/views/apps/AppListAdapter.java
new file mode 100644
index 000000000..0a81e5323
--- /dev/null
+++ b/app/src/main/java/org/fdroid/fdroid/views/apps/AppListAdapter.java
@@ -0,0 +1,40 @@
+package org.fdroid.fdroid.views.apps;
+
+import android.app.Activity;
+import android.database.Cursor;
+import android.support.v7.widget.RecyclerView;
+import android.view.ViewGroup;
+
+import org.fdroid.fdroid.R;
+import org.fdroid.fdroid.data.App;
+
+class AppListAdapter extends RecyclerView.Adapter {
+
+ private Cursor cursor;
+ private final Activity activity;
+
+ AppListAdapter(Activity activity) {
+ this.activity = activity;
+ }
+
+ public void setAppCursor(Cursor cursor) {
+ this.cursor = cursor;
+ notifyDataSetChanged();
+ }
+
+ @Override
+ public AppListItemController onCreateViewHolder(ViewGroup parent, int viewType) {
+ return new AppListItemController(activity, activity.getLayoutInflater().inflate(R.layout.app_list_item, parent, false));
+ }
+
+ @Override
+ public void onBindViewHolder(AppListItemController holder, int position) {
+ cursor.moveToPosition(position);
+ holder.bindModel(new App(cursor));
+ }
+
+ @Override
+ public int getItemCount() {
+ return cursor == null ? 0 : cursor.getCount();
+ }
+}
diff --git a/app/src/main/java/org/fdroid/fdroid/views/categories/CategoryController.java b/app/src/main/java/org/fdroid/fdroid/views/categories/CategoryController.java
index 85dcc9aa0..402239f0c 100644
--- a/app/src/main/java/org/fdroid/fdroid/views/categories/CategoryController.java
+++ b/app/src/main/java/org/fdroid/fdroid/views/categories/CategoryController.java
@@ -1,6 +1,7 @@
package org.fdroid.fdroid.views.categories;
import android.app.Activity;
+import android.content.Intent;
import android.content.Context;
import android.database.Cursor;
import android.graphics.Color;
@@ -20,6 +21,7 @@ import android.widget.TextView;
import org.fdroid.fdroid.R;
import org.fdroid.fdroid.data.AppProvider;
import org.fdroid.fdroid.data.Schema;
+import org.fdroid.fdroid.views.apps.AppListActivity;
import java.util.Random;
@@ -130,6 +132,13 @@ public class CategoryController extends RecyclerView.ViewHolder implements Loade
private final View.OnClickListener onViewAll = new View.OnClickListener() {
@Override
public void onClick(View v) {
+ if (currentCategory == null) {
+ return;
+ }
+
+ Intent intent = new Intent(activity, AppListActivity.class);
+ intent.putExtra(AppListActivity.EXTRA_CATEGORY, currentCategory);
+ activity.startActivity(intent);
}
};
diff --git a/app/src/main/res/drawable/ic_back_black_24dp.xml b/app/src/main/res/drawable/ic_back_black_24dp.xml
new file mode 100644
index 000000000..a5b378a9c
--- /dev/null
+++ b/app/src/main/res/drawable/ic_back_black_24dp.xml
@@ -0,0 +1,5 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_close_black_24dp.xml b/app/src/main/res/drawable/ic_close_black_24dp.xml
new file mode 100644
index 000000000..ede4b7108
--- /dev/null
+++ b/app/src/main/res/drawable/ic_close_black_24dp.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/layout/activity_app_list.xml b/app/src/main/res/layout/activity_app_list.xml
new file mode 100644
index 000000000..f81d7ba9e
--- /dev/null
+++ b/app/src/main/res/layout/activity_app_list.xml
@@ -0,0 +1,69 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 7052fc58c..4acac57c2 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -90,6 +90,7 @@
Enable
Add Key
Overwrite
+ Clear search
Available
Installed