App list: Show a list of apps matching a particular category.

This populates a search box with the category name and shows a
clear button to the right and a back button to the left of the
text input.
This commit is contained in:
Peter Serwylo 2016-11-24 11:50:28 +11:00
parent f5e6d73999
commit 9bc72ff102
8 changed files with 250 additions and 0 deletions

View File

@ -509,6 +509,8 @@
</intent-filter>
</activity>
<activity android:name=".views.apps.AppListActivity" />
</application>
</manifest>

View File

@ -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<Cursor> {
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<Cursor> 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<Cursor> loader, Cursor cursor) {
appAdapter.setAppCursor(cursor);
}
@Override
public void onLoaderReset(Loader<Cursor> loader) {
appAdapter.setAppCursor(null);
}
}

View File

@ -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<AppListItemController> {
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();
}
}

View File

@ -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);
}
};

View File

@ -0,0 +1,5 @@
<vector android:autoMirrored="true" android:height="24dp"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M20,11H7.83l5.59,-5.59L12,4l-8,8 8,8 1.41,-1.41L7.83,13H20v-2z"/>
</vector>

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M19,6.41L17.59,5 12,10.59 6.41,5 5,6.41 10.59,12 5,17.59 6.41,19 12,13.41 17.59,19 19,17.59 13.41,12z"/>
</vector>

View File

@ -0,0 +1,69 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="12dp">
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginLeft="16dp"
android:layout_marginEnd="16dp"
android:layout_marginRight="16dp">
<ImageView
android:id="@+id/back"
android:contentDescription="@string/back"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:srcCompat="@drawable/ic_back_black_24dp" />
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@+id/back"
app:layout_constraintEnd_toStartOf="@+id/clear"
android:padding="12dp"
android:id="@+id/search"
android:hint="@string/search_hint"
android:background="@android:color/transparent"
android:textSize="18sp" />
<ImageView
android:id="@+id/clear"
android:contentDescription="@string/clear_search"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:srcCompat="@drawable/ic_close_black_24dp" />
</android.support.constraint.ConstraintLayout>
</android.support.v7.widget.CardView>
<android.support.v7.widget.RecyclerView
android:id="@+id/app_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:listitem="@layout/app_list_item"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:scrollbars="vertical" />
</LinearLayout>

View File

@ -90,6 +90,7 @@
<string name="enable">Enable</string>
<string name="add_key">Add Key</string>
<string name="overwrite">Overwrite</string>
<string name="clear_search">Clear search</string>
<string name="tab_available_apps">Available</string>
<string name="tab_installed_apps">Installed</string>