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:
parent
f5e6d73999
commit
9bc72ff102
@ -509,6 +509,8 @@
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<activity android:name=".views.apps.AppListActivity" />
|
||||
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
|
5
app/src/main/res/drawable/ic_back_black_24dp.xml
Normal file
5
app/src/main/res/drawable/ic_back_black_24dp.xml
Normal 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>
|
9
app/src/main/res/drawable/ic_close_black_24dp.xml
Normal file
9
app/src/main/res/drawable/ic_close_black_24dp.xml
Normal 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>
|
69
app/src/main/res/layout/activity_app_list.xml
Normal file
69
app/src/main/res/layout/activity_app_list.xml
Normal 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>
|
@ -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>
|
||||
|
Loading…
x
Reference in New Issue
Block a user