Android - Search - Cleanup tabs code and code in general. Show 'no places' message when no results from search.

This commit is contained in:
Cristian Luis Duarte 2018-04-19 17:22:53 -03:00
parent 8249d445c5
commit af785d6072
5 changed files with 102 additions and 130 deletions

View file

@ -19,8 +19,6 @@ import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.widget.EditText; import android.widget.EditText;
import android.widget.TabHost;
import android.widget.TabWidget;
import android.widget.TextView; import android.widget.TextView;
import io.highfidelity.hifiinterface.view.DomainAdapter; import io.highfidelity.hifiinterface.view.DomainAdapter;
@ -38,9 +36,11 @@ public class HomeActivity extends AppCompatActivity implements NavigationView.On
public static final int ENTER_DOMAIN_URL = 1; public static final int ENTER_DOMAIN_URL = 1;
private DomainAdapter domainAdapter; private DomainAdapter mDomainAdapter;
private DrawerLayout mDrawerLayout; private DrawerLayout mDrawerLayout;
private NavigationView mNavigationView; private NavigationView mNavigationView;
private RecyclerView mDomainsView;
private TextView searchNoResultsView;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
@ -59,46 +59,40 @@ public class HomeActivity extends AppCompatActivity implements NavigationView.On
mNavigationView = (NavigationView) findViewById(R.id.nav_view); mNavigationView = (NavigationView) findViewById(R.id.nav_view);
mNavigationView.setNavigationItemSelectedListener(this); mNavigationView.setNavigationItemSelectedListener(this);
TabHost tabs = (TabHost)findViewById(R.id.tabhost); searchNoResultsView = findViewById(R.id.searchNoResultsView);
tabs.setup();
TabHost.TabSpec spec=tabs.newTabSpec("featured"); mDomainsView = findViewById(R.id.rvDomains);
spec.setContent(R.id.featured);
spec.setIndicator(getString(R.string.featured));
tabs.addTab(spec);
spec = tabs.newTabSpec("popular");
spec.setContent(R.id.popular);
spec.setIndicator(getString(R.string.popular));
tabs.addTab(spec);
spec = tabs.newTabSpec("bookmarks");
spec.setContent(R.id.bookmarks);
spec.setIndicator(getString(R.string.bookmarks));
tabs.addTab(spec);
tabs.setCurrentTab(0);
TabWidget tabwidget=tabs.getTabWidget();
for(int i=0; i<tabwidget.getChildCount(); i++){
TextView tv=(TextView) tabwidget.getChildAt(i).findViewById(android.R.id.title);
tv.setTextAppearance(R.style.TabText);
}
RecyclerView domainsView = findViewById(R.id.rvDomains);
int numberOfColumns = 1; int numberOfColumns = 1;
GridLayoutManager gridLayoutMgr = new GridLayoutManager(this, numberOfColumns); GridLayoutManager gridLayoutMgr = new GridLayoutManager(this, numberOfColumns);
domainsView.setLayoutManager(gridLayoutMgr); mDomainsView.setLayoutManager(gridLayoutMgr);
domainAdapter = new DomainAdapter(this, HifiUtils.getInstance().protocolVersionSignature()); mDomainAdapter = new DomainAdapter(this, HifiUtils.getInstance().protocolVersionSignature());
domainAdapter.setClickListener(new DomainAdapter.ItemClickListener() { mDomainAdapter.setClickListener(new DomainAdapter.ItemClickListener() {
@Override @Override
public void onItemClick(View view, int position, DomainAdapter.Domain domain) { public void onItemClick(View view, int position, DomainAdapter.Domain domain) {
gotoDomain(domain.url); gotoDomain(domain.url);
} }
}); });
domainsView.setAdapter(domainAdapter); mDomainAdapter.setListener(new DomainAdapter.AdapterListener() {
@Override
public void onEmptyAdapter() {
searchNoResultsView.setText(R.string.search_no_results);
searchNoResultsView.setVisibility(View.VISIBLE);
mDomainsView.setVisibility(View.GONE);
}
@Override
public void onNonEmptyAdapter() {
searchNoResultsView.setVisibility(View.GONE);
mDomainsView.setVisibility(View.VISIBLE);
}
@Override
public void onError(Exception e, String message) {
}
});
mDomainsView.setAdapter(mDomainAdapter);
EditText searchView = findViewById(R.id.searchView); EditText searchView = findViewById(R.id.searchView);
int searchPlateId = searchView.getContext().getResources().getIdentifier("android:id/search_plate", null, null); int searchPlateId = searchView.getContext().getResources().getIdentifier("android:id/search_plate", null, null);
@ -118,22 +112,19 @@ public class HomeActivity extends AppCompatActivity implements NavigationView.On
@Override @Override
public void afterTextChanged(Editable editable) { public void afterTextChanged(Editable editable) {
domainAdapter.loadDomains(editable.toString()); mDomainAdapter.loadDomains(editable.toString());
} }
}); });
searchView.setOnKeyListener(new View.OnKeyListener() { searchView.setOnKeyListener((view, i, keyEvent) -> {
@Override if (i == KeyEvent.KEYCODE_ENTER) {
public boolean onKey(View view, int i, KeyEvent keyEvent) { String urlString = searchView.getText().toString();
if (i == KeyEvent.KEYCODE_ENTER) { if (!urlString.trim().isEmpty()) {
String urlString = searchView.getText().toString(); urlString = HifiUtils.getInstance().sanitizeHifiUrl(urlString);
if (!urlString.trim().isEmpty()) {
urlString = HifiUtils.getInstance().sanitizeHifiUrl(urlString);
}
gotoDomain(urlString);
return true;
} }
return false; gotoDomain(urlString);
return true;
} }
return false;
}); });
updateLoginMenu(); updateLoginMenu();

View file

@ -4,10 +4,7 @@ import android.util.Log;
import android.util.MutableInt; import android.util.MutableInt;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.function.BinaryOperator;
import java.util.function.Consumer;
import io.highfidelity.hifiinterface.HifiUtils; import io.highfidelity.hifiinterface.HifiUtils;
import io.highfidelity.hifiinterface.view.DomainAdapter; import io.highfidelity.hifiinterface.view.DomainAdapter;
@ -56,9 +53,7 @@ public class UserStoryDomainProvider implements DomainProvider {
getUserStoryPage(1, getUserStoryPage(1,
e -> { e -> {
allStories.subList(counter.value, allStories.size()).forEach(userStory -> { allStories.subList(counter.value, allStories.size()).forEach(userStory -> {
// TODO Report error? e
filter.filterOrAdd(userStory); filter.filterOrAdd(userStory);
// TODO Visibility stuff according to size of suggestions?
}); });
if (domainCallback != null) { if (domainCallback != null) {
domainCallback.retrieveOk(suggestions); //ended domainCallback.retrieveOk(suggestions); //ended
@ -68,7 +63,6 @@ public class UserStoryDomainProvider implements DomainProvider {
allStories.forEach(userStory -> { allStories.forEach(userStory -> {
counter.value++; counter.value++;
filter.filterOrAdd(userStory); filter.filterOrAdd(userStory);
// TODO Visibility stuff according to size of suggestions?
}); });
} }
); );
@ -91,7 +85,7 @@ public class UserStoryDomainProvider implements DomainProvider {
UserStories data = response.body(); UserStories data = response.body();
allStories.addAll(data.user_stories); allStories.addAll(data.user_stories);
if (data.current_page < data.total_pages && data.current_page <= MAX_PAGES_TO_GET) { if (data.current_page < data.total_pages && data.current_page <= MAX_PAGES_TO_GET) {
if (pageNumber == 1 && firstPageCallback!=null) { if (pageNumber == 1 && firstPageCallback != null) {
firstPageCallback.callback(null); firstPageCallback.callback(null);
} }
getUserStoryPage(pageNumber + 1, restOfPagesCallback, null); getUserStoryPage(pageNumber + 1, restOfPagesCallback, null);
@ -209,7 +203,7 @@ public class UserStoryDomainProvider implements DomainProvider {
// New fields? tags, description // New fields? tags, description
String searchText() { String searchText() {
if (searchText==null) { if (searchText == null) {
searchText = place_name == null? "" : place_name.toUpperCase(); searchText = place_name == null? "" : place_name.toUpperCase();
} }
return searchText; return searchText;

View file

@ -37,17 +37,7 @@ public class DomainAdapter extends RecyclerView.Adapter<DomainAdapter.ViewHolder
private ItemClickListener mClickListener; private ItemClickListener mClickListener;
private String mProtocol; private String mProtocol;
private UserStoryDomainProvider domainProvider; private UserStoryDomainProvider domainProvider;
private AdapterListener mAdapterListener;
public static class Domain {
public String name;
public String url;
public String thumbnail;
public Domain(String name, String url, String thumbnail) {
this.name = name;
this.thumbnail = thumbnail;
this.url = url;
}
}
// references to our domains // references to our domains
private Domain[] mDomains = {}; private Domain[] mDomains = {};
@ -60,7 +50,9 @@ public class DomainAdapter extends RecyclerView.Adapter<DomainAdapter.ViewHolder
loadDomains(""); loadDomains("");
} }
public void setListener(AdapterListener adapterListener) {
mAdapterListener = adapterListener;
}
public void loadDomains(String filterText) { public void loadDomains(String filterText) {
domainProvider.retrieve(filterText, new DomainProvider.DomainCallback() { domainProvider.retrieve(filterText, new DomainProvider.DomainCallback() {
@ -69,12 +61,17 @@ public class DomainAdapter extends RecyclerView.Adapter<DomainAdapter.ViewHolder
mDomains = new Domain[domain.size()]; mDomains = new Domain[domain.size()];
mDomains = domain.toArray(mDomains); mDomains = domain.toArray(mDomains);
notifyDataSetChanged(); notifyDataSetChanged();
if (mDomains.length == 0) {
if (mAdapterListener != null) mAdapterListener.onEmptyAdapter();
} else {
if (mAdapterListener != null) mAdapterListener.onNonEmptyAdapter();
}
} }
@Override @Override
public void retrieveError(Exception e, String message) { public void retrieveError(Exception e, String message) {
//
Log.e("DOMAINS", message, e); Log.e("DOMAINS", message, e);
if (mAdapterListener != null) mAdapterListener.onError(e, message);
} }
}); });
} }
@ -159,4 +156,21 @@ public class DomainAdapter extends RecyclerView.Adapter<DomainAdapter.ViewHolder
public interface ItemClickListener { public interface ItemClickListener {
void onItemClick(View view, int position, Domain domain); void onItemClick(View view, int position, Domain domain);
} }
public static class Domain {
public String name;
public String url;
public String thumbnail;
public Domain(String name, String url, String thumbnail) {
this.name = name;
this.thumbnail = thumbnail;
this.url = url;
}
}
public interface AdapterListener {
void onEmptyAdapter();
void onNonEmptyAdapter();
void onError(Exception e, String message);
}
} }

View file

@ -2,76 +2,48 @@
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/contentHomeRoot"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:context="io.highfidelity.hifiinterface.HomeActivity" tools:context="io.highfidelity.hifiinterface.HomeActivity"
tools:showIn="@layout/activity_home"> tools:showIn="@layout/activity_home">
<TabHost <EditText
android:id="@+id/tabhost" android:id="@+id/searchView"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="50dp"
android:layout_marginBottom="8dp" app:layout_constraintTop_toTopOf="@id/contentHomeRoot"
app:layout_constraintBottom_toBottomOf="parent" android:background="@drawable/search_bg"
android:gravity="center_vertical|end"
android:paddingStart="32dp"
android:paddingEnd="32dp"
android:fontFamily="@font/raleway"
android:hint="@string/search_hint"
android:inputType="textUri"
android:imeOptions="actionGo"
/>
<TextView
android:id="@+id/searchNoResultsView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/SearchText"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"> app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/searchView"
android:layout_marginTop="32dp"
android:text="@string/search_no_results"
android:visibility="gone"
/>
<LinearLayout <android.support.v7.widget.RecyclerView
android:layout_width="match_parent" android:id="@+id/rvDomains"
android:layout_height="match_parent" app:layout_constraintTop_toBottomOf="@id/searchView"
android:orientation="vertical"> app:layout_constraintBottom_toBottomOf="@id/contentHomeRoot"
app:layout_constraintStart_toStartOf="@id/contentHomeRoot"
<TabWidget app:layout_constraintEnd_toEndOf="@id/contentHomeRoot"
android:id="@android:id/tabs" android:layout_width="0dp"
android:layout_width="match_parent" android:layout_height="0dp" />
android:layout_height="wrap_content"
android:visibility="gone"
android:background="@color/backgroundDark"/>
<EditText
android:id="@+id/searchView"
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="@drawable/search_bg"
android:gravity="center_vertical|end"
android:paddingStart="32dp"
android:paddingEnd="32dp"
android:hint="@string/search_hint"
android:inputType="textUri"
android:imeOptions="actionGo"
/>
<FrameLayout
android:id="@android:id/tabcontent"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="@+id/featured"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v7.widget.RecyclerView
android:id="@+id/rvDomains"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
<LinearLayout
android:id="@+id/popular"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
</LinearLayout>
<LinearLayout
android:id="@+id/bookmarks"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
</LinearLayout>
</FrameLayout>
</LinearLayout>
</TabHost>
</android.support.constraint.ConstraintLayout> </android.support.constraint.ConstraintLayout>

View file

@ -21,5 +21,6 @@
<string name="login_username_or_password_incorrect">Username or password incorrect.</string> <string name="login_username_or_password_incorrect">Username or password incorrect.</string>
<string name="logging_in">Logging into High Fidelity</string> <string name="logging_in">Logging into High Fidelity</string>
<string name="search_hint"><i>Search for a place by name</i></string> <string name="search_hint"><i>Search for a place by name</i></string>
<string name="search_loading">Loading places…</string>
<string name="search_no_results">No places exist with that name</string>
</resources> </resources>