Page Menu
Home
GitPull.it
Search
Configure Global Search
Log In
Files
F14979935
D259.1790916145.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Award Token
Flag For Later
Authored By
Unknown
Size
54 KB
Referenced Files
None
Subscribers
None
D259.1790916145.diff
View Options
diff --git a/app/src/main/java/it/reyboz/bustorino/adapters/OnStopClickListener.kt b/app/src/main/java/it/reyboz/bustorino/adapters/OnStopClickListener.kt
new file mode 100644
--- /dev/null
+++ b/app/src/main/java/it/reyboz/bustorino/adapters/OnStopClickListener.kt
@@ -0,0 +1,7 @@
+package it.reyboz.bustorino.adapters
+
+import it.reyboz.bustorino.backend.Stop
+
+fun interface OnStopClickListener {
+ fun onStopClick(stop: Stop)
+}
\ No newline at end of file
diff --git a/app/src/main/java/it/reyboz/bustorino/adapters/SquareStopAdapter.java b/app/src/main/java/it/reyboz/bustorino/adapters/StopNearbyAdapter.java
rename from app/src/main/java/it/reyboz/bustorino/adapters/SquareStopAdapter.java
rename to app/src/main/java/it/reyboz/bustorino/adapters/StopNearbyAdapter.java
--- a/app/src/main/java/it/reyboz/bustorino/adapters/SquareStopAdapter.java
+++ b/app/src/main/java/it/reyboz/bustorino/adapters/StopNearbyAdapter.java
@@ -31,21 +31,25 @@
import it.reyboz.bustorino.backend.Stop;
import it.reyboz.bustorino.util.StopSorterByDistance;
import it.reyboz.bustorino.fragments.FragmentListenerMain;
+import org.jetbrains.annotations.NotNull;
-import java.util.Collections;
+import java.util.ArrayList;
import java.util.List;
-public class SquareStopAdapter extends RecyclerView.Adapter<SquareStopAdapter.SquareViewHolder> {
+public class StopNearbyAdapter extends RecyclerView.Adapter<StopNearbyAdapter.SquareViewHolder> {
private final static int layoutRes = R.layout.item_stop_nearby_card;
//private List<Stop> stops;
private @Nullable GPSPoint userPosition;
- private FragmentListenerMain listener;
- private List<Stop> stops;
+ private OnStopClickListener listener;
+ private boolean showLocation;
+ private ArrayList<Stop> stops;
- public SquareStopAdapter(@Nullable List<Stop> stopList, FragmentListenerMain fragmentListener, @Nullable GPSPoint pos) {
+ public StopNearbyAdapter(@NotNull ArrayList<Stop> stopList,
+ @Nullable GPSPoint pos, boolean showLocation, OnStopClickListener fragmentListener) {
listener = fragmentListener;
userPosition = pos;
stops = stopList;
+ this.showLocation = showLocation;
}
@@ -54,21 +58,24 @@
public SquareViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
final View view = LayoutInflater.from(parent.getContext()).inflate(layoutRes, parent, false);
//sort the stops by distance
- if(stops != null && stops.size() > 0)
- Collections.sort(stops,new StopSorterByDistance(userPosition));
+ if (userPosition!=null) {
+ if (stops != null && stops.size() > 0)
+ stops.sort(new StopSorterByDistance(userPosition));
+ }
return new SquareViewHolder(view);
}
@Override
public void onBindViewHolder(SquareViewHolder holder, int position) {
//DO THE ACTUAL WORK TO PUT THE DATA
- if(stops==null || stops.size() == 0) return; //NO STOPS
+ if(stops==null || stops.isEmpty()) return; //NO STOPS
final Stop stop = stops.get(position);
final Context context = holder.itemView.getContext();
if(stop!=null){
- if(stop.getDistanceFromLocation(userPosition)!=Double.POSITIVE_INFINITY){
+ if(userPosition!=null && stop.getDistanceFromLocation(userPosition)!=Double.POSITIVE_INFINITY){
Double distance = stop.getDistanceFromLocation(userPosition);
holder.distancetextView.setText(distance.intValue()+" m");
+ holder.distancetextView.setVisibility(View.VISIBLE);
} else {
holder.distancetextView.setVisibility(View.GONE);
}
@@ -80,10 +87,19 @@
if(whatStopsHere == null) {
holder.routesView.setVisibility(View.GONE);
} else {
- holder.routesView.setText(context.getString(R.string.lines_fill, whatStopsHere));
+ holder.routesView.setText(whatStopsHere);
+ //context.getString(R.string.lines_fill, whatStopsHere));
holder.routesView.setVisibility(View.VISIBLE); // might be GONE due to View Holder Pattern
}
- holder.stopID =stop.ID;
+ holder.itemView.setOnClickListener(view -> {listener.onStopClick(stop);});
+ if (showLocation && !(
+ stop.location==null || stop.location.isEmpty() || stop.location.contains("null"))
+ ){
+ holder.locationTextView.setText(stop.location);
+ holder.locationTextView.setVisibility(View.VISIBLE);
+ } else {
+ holder.locationTextView.setVisibility(View.GONE);
+ }
} else {
Log.w("SquareStopAdapter","!! The selected stop is null !!");
}
@@ -94,27 +110,31 @@
return stops.size();
}
- class SquareViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
+ class SquareViewHolder extends RecyclerView.ViewHolder {
TextView stopIDView;
TextView stopNameView;
+ TextView locationTextView;
TextView routesView;
TextView distancetextView;
- String stopID;
+ //Stop stop;
SquareViewHolder(View holdView){
super(holdView);
- holdView.setOnClickListener(this);
+ //holdView.setOnClickListener(this);
stopIDView = (TextView) holdView.findViewById(R.id.stop_numberText);
stopNameView = (TextView) holdView.findViewById(R.id.stop_nameText);
routesView = (TextView) holdView.findViewById(R.id.stop_linesText);
+ locationTextView = holdView.findViewById(R.id.stop_locationTextView);
distancetextView = (TextView) holdView.findViewById(R.id.stop_distanceTextView);
}
- @Override
+ /*@Override
public void onClick(View v) {
- listener.requestArrivalsForStopID(stopID);
+ listener.onStopClick(stop);
}
+ */
+
}
public void setStops(List<Stop> newStops) {
diff --git a/app/src/main/java/it/reyboz/bustorino/data/NextGenDB.java b/app/src/main/java/it/reyboz/bustorino/data/NextGenDB.java
--- a/app/src/main/java/it/reyboz/bustorino/data/NextGenDB.java
+++ b/app/src/main/java/it/reyboz/bustorino/data/NextGenDB.java
@@ -337,6 +337,28 @@
});
}
+ @NonNull
+ public synchronized List<Stop> searchStopsByCodeOrName(String query, boolean searchById){
+ String escaped = query.replace("\\", "\\\\")
+ .replace("%", "\\%")
+ .replace("_", "\\_");
+ String sql;
+ final String like = "%" + escaped + "%";
+ if (searchById){
+ sql = "SELECT * FROM "+StopsTable.TABLE_NAME+" WHERE "+StopsTable.COL_ID+" LIKE ? ESCAPE '\\'";
+ } else{
+ sql = "SELECT * FROM "+StopsTable.TABLE_NAME+" WHERE "+StopsTable.COL_NAME+" LIKE ? ESCAPE '\\'";
+ }
+ final List<Stop> out = new ArrayList<>();
+ SQLiteDatabase db = getReadableDatabase();
+ try (Cursor c= db.rawQuery(sql, new String[]{like}
+ ) ) {
+ out.addAll(getStopsFromCursorAllFields(c));
+ }
+
+ return out;
+ }
+
/**
* Get the list of stop in the query, with all the possible fields {NextGenDB.QUERY_COLUMN_stops_all}
diff --git a/app/src/main/java/it/reyboz/bustorino/fragments/MainScreenFragment.java b/app/src/main/java/it/reyboz/bustorino/fragments/MainScreenFragment.java
--- a/app/src/main/java/it/reyboz/bustorino/fragments/MainScreenFragment.java
+++ b/app/src/main/java/it/reyboz/bustorino/fragments/MainScreenFragment.java
@@ -22,18 +22,23 @@
import android.content.pm.PackageManager;
import android.os.Bundle;
+import android.text.InputType;
+import android.widget.TextView;
import androidx.activity.result.ActivityResultCallback;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.AppCompatImageButton;
+import androidx.appcompat.widget.SearchView;
import androidx.coordinatorlayout.widget.CoordinatorLayout;
import androidx.core.app.ActivityCompat;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
import androidx.lifecycle.ViewModelProvider;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import android.util.Log;
@@ -48,15 +53,18 @@
import com.google.android.material.floatingactionbutton.FloatingActionButton;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Map;
-import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.LinkedBlockingQueue;
import it.reyboz.bustorino.BuildConfig;
import it.reyboz.bustorino.R;
+import it.reyboz.bustorino.adapters.StopNearbyAdapter;
import it.reyboz.bustorino.backend.*;
import it.reyboz.bustorino.util.Permissions;
import it.reyboz.bustorino.viewmodels.IntroViewModel;
+import it.reyboz.bustorino.viewmodels.SearchStopsDBViewModel;
import org.jetbrains.annotations.NotNull;
import static it.reyboz.bustorino.util.Permissions.LOCATION_PERMISSIONS;
@@ -81,7 +89,7 @@
public final static String FRAGMENT_TAG = "MainScreenFragment";
private enum SearchMode {SEARCH_ID,SEARCH_NAME,INITIAL}
- public enum InternalScreen {
+ public enum InitialScreen {
HOME_BUTTONS(0),
NEARBY_STOPS(1),
ARRIVALS(2),
@@ -89,21 +97,21 @@
NEARBY_ARRIVALS(4);
public final int code;
- InternalScreen(int code) { this.code = code; }
+ InitialScreen(int code) { this.code = code; }
@Nullable
- public static InternalScreen fromCode(int code) {
- for (InternalScreen c : values()) if (c.code == code) return c;
+ public static InitialScreen fromCode(int code) {
+ for (InitialScreen c : values()) if (c.code == code) return c;
return null;
}
@NonNull
- public static InternalScreen fromFragmentKind(@NonNull FragmentKind kind){
+ public static InitialScreen fromFragmentKind(@NonNull FragmentKind kind){
switch (kind){
- case HOME_BUTTONS -> { return InternalScreen.HOME_BUTTONS; }
- case NEARBY_STOPS -> { return InternalScreen.NEARBY_STOPS; }
- case FragmentKind.ARRIVALS -> { return InternalScreen.ARRIVALS; }
- case FragmentKind.STOPS -> { return InternalScreen.STOP_SEARCH; }
- case FragmentKind.NEARBY_ARRIVALS -> { return InternalScreen.NEARBY_ARRIVALS; }
+ case HOME_BUTTONS -> { return InitialScreen.HOME_BUTTONS; }
+ case NEARBY_STOPS -> { return InitialScreen.NEARBY_STOPS; }
+ case FragmentKind.ARRIVALS -> { return InitialScreen.ARRIVALS; }
+ case FragmentKind.STOPS -> { return InitialScreen.STOP_SEARCH; }
+ case FragmentKind.NEARBY_ARRIVALS -> { return InitialScreen.NEARBY_ARRIVALS; }
default -> {
throw new IllegalArgumentException("Unknown fragment kind");
}
@@ -113,13 +121,14 @@
private FragmentHelper fragmentHelper;
private SwipeRefreshLayout swipeRefreshLayout;
- private EditText busStopSearchByIDEditText;
- private EditText busStopSearchByNameEditText;
+ //private EditText busStopSearchByIDEditText;
+ //private EditText busStopSearchByNameEditText;
+
+ private SearchView busStopSearchView;
private ProgressBar progressBar;
private FloatingActionButton floatingActionButton;
- /// VIEW MODELS in BaseFragment
-
+ private SearchStopsDBViewModel searchStopsViewModel;
private boolean setupOnStart = true;
private boolean suppressArrivalsReload = false;
@@ -138,12 +147,23 @@
private String pendingStopID = null;
private String pendingSearchQuery = null;
- private InternalScreen internalScreen = InternalScreen.HOME_BUTTONS;
+ private InitialScreen initialScreen = InitialScreen.HOME_BUTTONS;
private CoordinatorLayout coordLayout;
+ private RecyclerView suggestionsRecyclerView;
+ private StopNearbyAdapter suggestionsAdapter = null;
+ private TextView stopSearchMessageTextView;
+
//this is really a hackish thing, but it works
private final LinkedBlockingQueue<Runnable> thingsToDoOnStart = new LinkedBlockingQueue<>();
+ private boolean isSearchModeById(){
+ return searchMode != SearchMode.SEARCH_NAME;
+ }
+
+ private void emptySearchQueryViewModel(){
+ searchStopsViewModel.searchStops("",isSearchModeById());
+ }
private void refreshStop() {
if(getContext() == null){
@@ -203,14 +223,14 @@
}
- public static MainScreenFragment newInstance(@NonNull InternalScreen kind,
+ public static MainScreenFragment newInstance(@NonNull InitialScreen kind,
@Nullable String stopId,
@Nullable String query) {
MainScreenFragment f = new MainScreenFragment();
f.setArguments(makeArgs(kind, stopId, query));
return f;
}
- public static MainScreenFragment newInstance(@NonNull InternalScreen kind, @Nullable Bundle args){
+ public static MainScreenFragment newInstance(@NonNull InitialScreen kind, @Nullable Bundle args){
MainScreenFragment f = new MainScreenFragment();
if (args != null) {
f.setArguments(args);
@@ -225,7 +245,7 @@
* @param query
* @return
*/
- public static Bundle makeArgs(@NonNull InternalScreen kind, @Nullable String stopId, @Nullable String query) {
+ public static Bundle makeArgs(@NonNull InitialScreen kind, @Nullable String stopId, @Nullable String query) {
Bundle b = new Bundle();
b.putInt(ARG_INITIAL_CONTENT, kind.code);
if (stopId != null) b.putString(ARG_STOP_ID, stopId);
@@ -233,16 +253,16 @@
return b;
}
public static Bundle makeArgsArrivals(@NonNull String stopID){
- return makeArgs(InternalScreen.ARRIVALS, stopID, null);
+ return makeArgs(InitialScreen.ARRIVALS, stopID, null);
}
public static Bundle makeArgsStops(@NonNull String query){
- return makeArgs(InternalScreen.STOP_SEARCH, query, null);
+ return makeArgs(InitialScreen.STOP_SEARCH, query, null);
}
public static Bundle makeArgsNearby(){
- return makeArgs(InternalScreen.NEARBY_STOPS, null, null);
+ return makeArgs(InitialScreen.NEARBY_STOPS, null, null);
}
public static Bundle makeArgsButtonsScreen(){
- return makeArgs(InternalScreen.HOME_BUTTONS, null, null);
+ return makeArgs(InitialScreen.HOME_BUTTONS, null, null);
}
@@ -254,9 +274,9 @@
Log.d(DEBUG_TAG, "ARGS ARE NOT NULL: "+ args);
if (args.containsKey(ARG_INITIAL_CONTENT)) {
- int code = args.getInt(ARG_INITIAL_CONTENT, InternalScreen.HOME_BUTTONS.code);
- InternalScreen parsed = InternalScreen.fromCode(code);
- internalScreen = (parsed != null) ? parsed : InternalScreen.HOME_BUTTONS;
+ int code = args.getInt(ARG_INITIAL_CONTENT, InitialScreen.HOME_BUTTONS.code);
+ InitialScreen parsed = InitialScreen.fromCode(code);
+ initialScreen = (parsed != null) ? parsed : InitialScreen.HOME_BUTTONS;
}
String stopId = args.getString(ARG_STOP_ID);
if (stopId != null)
@@ -266,7 +286,6 @@
}
fragmentHelper = new FragmentHelper(this, getChildFragmentManager(), getContext(), R.id.resultFrame);
-
}
@Override
@@ -285,14 +304,31 @@
// Inflate the layout for this fragment
View root = inflater.inflate(R.layout.fragment_main_screen, container, false);
/// UI ELEMENTS //
- busStopSearchByIDEditText = root.findViewById(R.id.busStopSearchByIDEditText);
- busStopSearchByNameEditText = root.findViewById(R.id.busStopSearchByNameEditText);
+ //busStopSearchByIDEditText = root.findViewById(R.id.busStopSearchByIDEditText);
+ //busStopSearchByNameEditText = root.findViewById(R.id.busStopSearchByNameEditText);
+ busStopSearchView = root.findViewById(R.id.busStopSearchView);
progressBar = root.findViewById(R.id.progressBar);
swipeRefreshLayout = root.findViewById(R.id.listRefreshLayout);
floatingActionButton = root.findViewById(R.id.floatingActionButton);
- busStopSearchByIDEditText.setSelectAllOnFocus(true);
- busStopSearchByIDEditText
+ stopSearchMessageTextView = root.findViewById(R.id.stopSearchMessageTextView);
+ suggestionsRecyclerView = root.findViewById(R.id.suggestionsRecyclerView);
+ suggestionsRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext(),LinearLayoutManager.VERTICAL, false));
+ EditText searchEditText = busStopSearchView.findViewById(androidx.appcompat.R.id.search_src_text);
+ searchEditText.setSelectAllOnFocus(true);
+ searchEditText.setOnFocusChangeListener( (view,hasFocus) ->{
+ if(hasFocus){
+ showFloatingActionButton(true);
+ }
+ });
+
+ busStopSearchView.setOnFocusChangeListener( (view, hasFocus) ->{
+ if(hasFocus){
+ showFloatingActionButton(true);
+ }
+ });
+ //busStopSearchView.setSelectAllOnFocus(true);
+ /*busStopSearchByIDEditText
.setOnEditorActionListener((v, actionId, event) -> {
// IME_ACTION_SEARCH alphabetical option
if (actionId == EditorInfo.IME_ACTION_SEARCH) {
@@ -301,7 +337,9 @@
}
return false;
});
- busStopSearchByNameEditText
+
+ */
+ /*searchEditText
.setOnEditorActionListener((v, actionId, event) -> {
// IME_ACTION_SEARCH alphabetical option
if (actionId == EditorInfo.IME_ACTION_SEARCH) {
@@ -311,6 +349,24 @@
return false;
});
+ */
+
+ busStopSearchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
+ @Override
+ public boolean onQueryTextSubmit(String q) {
+ onSearchClick(null);
+ emptySearchQueryViewModel();
+ return true;
+ }
+
+ @Override
+ public boolean onQueryTextChange(String q) {
+ //Log.d(DEBUG_TAG, "Changed query text");
+ searchStopsViewModel.searchStops(q, isSearchModeById());
+ return true;
+ }
+ });
+
swipeRefreshLayout
.setOnRefreshListener(this::refreshStop);
swipeRefreshLayout.setColorSchemeResources(R.color.blue_500, R.color.orange_500);
@@ -319,7 +375,7 @@
floatingActionButton.setImageResource(R.drawable.magnifying_glass_larger);
floatingActionButton.setOnClickListener((this::onToggleKeyboardLayout));
- busStopSearchByIDEditText.setOnFocusChangeListener((v, hasFocus) -> {
+ /*busStopSearchByIDEditText.setOnFocusChangeListener((v, hasFocus) -> {
//Log.d(DEBUG_TAG, "stop search by ID has focus: " + hasFocus);
if(hasFocus)
setSearchModeBusStopID();
@@ -331,6 +387,8 @@
setSearchModeBusStopName();
});
+ */
+
AppCompatImageButton qrButton = root.findViewById(R.id.QRButton);
qrButton.setOnClickListener(this::onQRButtonClick);
@@ -379,18 +437,14 @@
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
- Log.d(DEBUG_TAG, "onViewCreated, SwipeRefreshLayout visible: "+(swipeRefreshLayout.getVisibility()==View.VISIBLE));
- Log.d(DEBUG_TAG, "Saved instance state is: "+savedInstanceState);
- //Restore instance state
- /*if (savedInstanceState!=null){
- Fragment fragment = getChildFragmentManager().getFragment(savedInstanceState, SAVED_FRAGMENT);
- if (fragment!=null){
- getChildFragmentManager().beginTransaction().add(R.id.resultFrame, fragment).commit();
- setupOnStart = false;
- }
- }
+ Log.d(DEBUG_TAG, "onViewCreated, have savedInstanceState: "+ (savedInstanceState!=null) +
+ "; SwipeRefreshLayout visible: "+(swipeRefreshLayout.getVisibility()==View.VISIBLE));
+ //Log.d(DEBUG_TAG, "Saved instance state is: "+savedInstanceState);
+ searchStopsViewModel = new ViewModelProvider(requireActivity()).get(SearchStopsDBViewModel.class);
+
+ searchStopsViewModel.getFilteredStopsSearch().observe(getViewLifecycleOwner(),
+ stops -> setSuggestionsStopRecyclerView(stops, true));
- */
if (getChildFragmentManager().findFragmentById(R.id.resultFrame)!= null){
swipeRefreshLayout.setVisibility(View.VISIBLE);
// The child FragmentManager has restored its content — don't dispatch again
@@ -399,13 +453,13 @@
if (savedInstanceState != null) return;
- showDifferentSubFragments(internalScreen);
+ showDifferentSubFragments(initialScreen);
}
/**
* Installs the initial child fragment based on the arguments supplied as arguments
*/
- private void showDifferentSubFragments(@NonNull InternalScreen screen) {
+ private void showDifferentSubFragments(@NonNull InitialScreen screen) {
boolean firstTime = !initialScreenShown;
switch (screen) {
case NEARBY_STOPS:
@@ -451,6 +505,39 @@
}
+ public void setSuggestionsStopRecyclerView(List<Stop> stops, boolean showMessage){
+
+ var res = !stops.isEmpty();
+ var query = searchStopsViewModel.getQueryStops();
+ //Log.d(DEBUG_TAG, "received stops suggestions, are "+stops.size());
+ if(res){
+ if(suggestionsAdapter!=null){
+ suggestionsAdapter.setStops(stops);
+ } else{
+ suggestionsAdapter = new StopNearbyAdapter(new ArrayList<>(stops), null, true, (stop)->{
+ requestArrivalsForStopID(stop.ID);
+ //clear query
+ emptySearchQueryViewModel();
+ //setSuggestionsStopRecyclerView(List.of(), false);
+ });
+ suggestionsRecyclerView.setAdapter(suggestionsAdapter);
+ }
+ suggestionsRecyclerView.setVisibility(View.VISIBLE);
+
+ } else{
+ if(suggestionsAdapter !=null) suggestionsAdapter = null;
+ suggestionsRecyclerView.setVisibility(View.GONE);
+ if(showMessage && query!=null && !query.trim().isEmpty()){
+ stopSearchMessageTextView.setText( searchMode == SearchMode.SEARCH_NAME ?
+ R.string.no_stop_found_search_name : R.string.no_stop_found_search_number);
+ stopSearchMessageTextView.setVisibility(View.VISIBLE);
+ } else{
+ stopSearchMessageTextView.setVisibility(View.GONE);
+ }
+
+ }
+ }
+
public void setSuppressArrivalsReload(boolean value){
suppressArrivalsReload = value;
// we have to suppress the reloading of the (possible) ArrivalsFragment
@@ -513,19 +600,20 @@
}
if (setupOnStart) {
if (pendingStopID==null){
-
if(!pendingIntroRun){
//show the fragment
//showButtonsFragment();
}
-
}
else{
///TODO: if there is a stop displayed, we need to hold the update
}
-
setupOnStart = false;
}
+ // this happens when the fragment is recreated and the query is set on the searchView
+ if(!searchStopsViewModel.getShowingSearchSuggestions()){
+ emptySearchQueryViewModel();
+ }
}
private void showButtonsFragment(boolean addInsteadOfReplace){
@@ -621,7 +709,6 @@
requestArrivalsForStopID(pendingStopID);
pendingStopID = null;
}
-
//mListener.readyGUIfor(FragmentKind.MAIN_SCREEN_FRAGMENT);
//fragmentHelper.setBlockAllActivities(false);
@@ -634,6 +721,7 @@
//locationManager.removeLocationRequestFor(requester);
//fragmentHelper.setBlockAllActivities(true);
fragmentHelper.stopLastRequestIfNeeded();
+ searchStopsViewModel.saveOpenSearchSuggestions();
super.onPause();
}
@@ -644,7 +732,8 @@
@Override
public void onQrScanSuccess(@NotNull String busIDToSearch) {
- busStopSearchByIDEditText.setText(busIDToSearch);
+ EditText searchEditText = busStopSearchView.findViewById(androidx.appcompat.R.id.search_src_text);
+ searchEditText.setText(busIDToSearch);
requestArrivalsForStopID(busIDToSearch);
}
@@ -664,13 +753,13 @@
*/
public void onSearchClick(View v) {
//final StopsFinderByName[] stopsFinderByNames = new StopsFinderByName[]{new GTTStopsFetcher(), new FiveTStopsFetcher()};
- if (searchMode == SearchMode.SEARCH_ID) {
- String busStopID = busStopSearchByIDEditText.getText().toString();
+ if (searchMode == SearchMode.SEARCH_ID || searchMode == SearchMode.INITIAL) {
+ String busStopID = busStopSearchView.getQuery().toString();
fragmentHelper.stopLastRequestIfNeeded();
requestArrivalsForStopID(busStopID);
} else if (searchMode == SearchMode.SEARCH_NAME) {
// searchMode == SEARCH_BY_NAME
- String query = busStopSearchByNameEditText.getText().toString();
+ String query = busStopSearchView.getQuery().toString();
query = query.trim();
if(getContext()!=null) {
if (query.length() < 1) {
@@ -688,17 +777,17 @@
public void onToggleKeyboardLayout(View v) {
switch (searchMode){
case SEARCH_ID:
- setSearchModeBusStopName();
- if (busStopSearchByNameEditText.requestFocus()) {
+ setSearchMode(SearchMode.SEARCH_NAME);
+ if (busStopSearchView.requestFocus())
showKeyboard();
- }
+ //}
break;
case SEARCH_NAME:
case INITIAL:
- setSearchModeBusStopID();
- if (busStopSearchByIDEditText.requestFocus()) {
- showKeyboard();
- }
+ setSearchMode(SearchMode.SEARCH_ID);
+ if (busStopSearchView.requestFocus())
+ showKeyboard();
+ //}
}
}
@@ -709,52 +798,52 @@
}
////////////////////////////////////// GUI HELPERS /////////////////////////////////////////////
+
+ private EditText getSearchEditText() {
+ return busStopSearchView.findViewById(androidx.appcompat.R.id.search_src_text);
+ }
public void showKeyboard() {
if(getActivity() == null) return;
- InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
- View view;
- if(searchMode == SearchMode.SEARCH_ID)
- view= busStopSearchByIDEditText;
- else if(searchMode == SearchMode.SEARCH_NAME)
- view = busStopSearchByNameEditText;
- else{
- Log.e(DEBUG_TAG, "Asking to show keyboard but SearchMode is "+searchMode+", ignoring");
- return;
- }
-
- imm.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT);
+ final EditText et = getSearchEditText();
+ et.requestFocus();
+ et.post(() -> {
+ InputMethodManager imm = (InputMethodManager)
+ requireActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
+ if (imm == null) return;
+ imm.restartInput(et); // applica il nuovo inputType
+ imm.showSoftInput(et, InputMethodManager.SHOW_IMPLICIT);
+ });
}
- private void setSearchModeBusStopID() {
- searchMode = SearchMode.SEARCH_ID;
- busStopSearchByNameEditText.setVisibility(View.GONE);
- busStopSearchByNameEditText.setText("");
- busStopSearchByIDEditText.setVisibility(View.VISIBLE);
- floatingActionButton.setImageResource(R.drawable.alphabetical);
- }
- private void setSearchModeBusStopName() {
- searchMode = SearchMode.SEARCH_NAME;
- busStopSearchByIDEditText.setVisibility(View.GONE);
- busStopSearchByIDEditText.setText("");
- busStopSearchByNameEditText.setVisibility(View.VISIBLE);
- floatingActionButton.setImageResource(R.drawable.numeric);
- }
protected boolean isNearbyFragmentShown(){
Fragment fragment = getChildFragmentManager().findFragmentByTag(NearbyStopsFragment.FRAGMENT_TAG);
return (fragment!= null && fragment.isResumed());
}
- /**
+ private void setSearchMode(SearchMode mode) {
+ searchMode = mode;
+ busStopSearchView.setQuery("", false);
+ boolean byId = mode != SearchMode.SEARCH_NAME;
+ busStopSearchView.setInputType(byId ? InputType.TYPE_CLASS_NUMBER : InputType.TYPE_CLASS_TEXT);
+ floatingActionButton.setImageResource(byId ? R.drawable.numeric : R.drawable.alphabetical);
+ busStopSearchView.setQueryHint(getString(byId ? R.string.insert_bus_stop_number : R.string.insert_bus_stop_name));
+ }
+
+ /*
* Having that cursor at the left of the edit text makes me cancer.
*
* @param busStopID bus stop ID
*/
+ //
+ /*
private void setBusStopSearchByIDEditText(String busStopID) {
busStopSearchByIDEditText.setText(busStopID);
busStopSearchByIDEditText.setSelection(busStopID.length());
}
+ */
+
@Nullable
@Override
public View getBaseViewForSnackBar() {
@@ -777,12 +866,16 @@
private void prepareGUIForArrivals() {
swipeRefreshLayout.setEnabled(true);
swipeRefreshLayout.setVisibility(View.VISIBLE);
+ //this is to hide the eventual search results from the text
+ //setSuggestionsStopRecyclerView(List.of(), false);
//actionHelpMenuItem.setVisible(true);
}
private void prepareGUIForBusStops() {
swipeRefreshLayout.setEnabled(false);
swipeRefreshLayout.setVisibility(View.VISIBLE);
+ //setSuggestionsStopRecyclerView(List.of(), false);
+
//actionHelpMenuItem.setVisible(false);
}
@@ -832,6 +925,37 @@
}
+ /*
+ // KEEPING THIS METHODS AS EXAMPLES FOR SHOW
+ boolean searchStopsResultsFragmentShown(){
+ Fragment frag = childFragMan.findFragmentById(R.id.resultFrame);
+ return frag instanceof StopSearchResultFragment;
+ }
+ void showSearchStopsResultsFragment(){
+ final String TAG = "stopSearchResult";
+ Fragment frag = childFragMan.findFragmentById(R.id.resultFrame);
+ if (frag instanceof StopSearchResultFragment){
+ return; //nothing to do
+ }
+ boolean exists = frag != null;
+ var trans = childFragMan.beginTransaction();
+
+ frag = childFragMan.findFragmentByTag(TAG);
+ if (!(frag instanceof StopSearchResultFragment)) {
+ frag = StopSearchResultFragment.newInstance();
+ }
+ if(exists){
+ //show the fragment
+ trans.replace(R.id.resultFrame,frag, TAG);
+ } else{
+ //create new fragment
+ trans.add(R.id.resultFrame,frag, TAG);
+ }
+ trans.addToBackStack(null);
+ trans.commit();
+ }
+ */
+
@Override
public void openLineFromStop(String routeGtfsId, @Nullable String stopIDFrom) {
//pass to activity
diff --git a/app/src/main/java/it/reyboz/bustorino/fragments/NearbyStopsFragment.kt b/app/src/main/java/it/reyboz/bustorino/fragments/NearbyStopsFragment.kt
--- a/app/src/main/java/it/reyboz/bustorino/fragments/NearbyStopsFragment.kt
+++ b/app/src/main/java/it/reyboz/bustorino/fragments/NearbyStopsFragment.kt
@@ -18,7 +18,6 @@
package it.reyboz.bustorino.fragments
import android.content.Context
-import android.content.res.ColorStateList
import android.location.Location
import android.os.Bundle
import android.util.Log
@@ -28,7 +27,6 @@
import android.widget.ProgressBar
import android.widget.TextView
import androidx.appcompat.widget.AppCompatButton
-import androidx.core.content.res.ResourcesCompat
import androidx.fragment.app.viewModels
import androidx.preference.PreferenceManager
import androidx.recyclerview.widget.RecyclerView
@@ -37,7 +35,7 @@
import it.reyboz.bustorino.BuildConfig
import it.reyboz.bustorino.R
import it.reyboz.bustorino.adapters.ArrivalsStopAdapter
-import it.reyboz.bustorino.adapters.SquareStopAdapter
+import it.reyboz.bustorino.adapters.StopNearbyAdapter
import it.reyboz.bustorino.backend.*
import it.reyboz.bustorino.data.DatabaseUpdate
import it.reyboz.bustorino.middleware.AutoFitGridLayoutManager
@@ -46,7 +44,6 @@
import it.reyboz.bustorino.util.Permissions
import it.reyboz.bustorino.util.Permissions.Companion.bothLocationPermissionsGranted
import it.reyboz.bustorino.util.StopSorterByDistance
-import it.reyboz.bustorino.util.ViewUtils
import it.reyboz.bustorino.viewmodels.NearbyStopsViewModel
import java.util.*
import java.util.concurrent.atomic.AtomicBoolean
@@ -81,7 +78,7 @@
private lateinit var gridRecyclerView: RecyclerView
- private var dataAdapter: SquareStopAdapter? = null
+ private var dataAdapter: StopNearbyAdapter? = null
private var gridLayoutManager: AutoFitGridLayoutManager? = null
private var lastPosition: GPSPoint? = null
private var circlingProgressBar: ProgressBar? = null
@@ -732,7 +729,9 @@
Collections.sort(stops, StopSorterByDistance(location))
if (dataAdapter == null) {
- dataAdapter = SquareStopAdapter(stops, mListener, lastPosition)
+ dataAdapter = StopNearbyAdapter(ArrayList(stops), lastPosition, false){
+ stop-> mListener?.requestArrivalsForStopID(stop.ID)
+ }
firstLocForStops = false
} else {
dataAdapter!!.setUserPosition(lastPosition)
diff --git a/app/src/main/java/it/reyboz/bustorino/util/StopSorterSearch.kt b/app/src/main/java/it/reyboz/bustorino/util/StopSorterSearch.kt
new file mode 100644
--- /dev/null
+++ b/app/src/main/java/it/reyboz/bustorino/util/StopSorterSearch.kt
@@ -0,0 +1,30 @@
+package it.reyboz.bustorino.util
+
+import it.reyboz.bustorino.backend.Stop
+
+class StopSorterSearch(val searchById: Boolean): Comparator<Stop> {
+ override fun compare(s0: Stop?, s1: Stop?): Int {
+ if (s0 ==null) {
+ if (s1 != null) return 1
+ else return 0
+ }
+ else if(s1 == null){
+ //s0 is not null
+ return -1
+ }
+ if(s0.location==null){
+ if(s1.location != null) return 1
+ } else if(s1.location==null) return -1
+
+ if(searchById){
+ val lenDiff = s0.ID.length - s1.ID.length
+ if(lenDiff!=0) return lenDiff
+ //second criterion
+ val diff = s0.ID.toInt() - s1.ID.toInt()
+ //if(diff!=0) return diff
+ return diff
+ } else{
+ return -1*(s0.numRoutesStopping - s1.numRoutesStopping)
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/it/reyboz/bustorino/viewmodels/SearchStopsDBViewModel.kt b/app/src/main/java/it/reyboz/bustorino/viewmodels/SearchStopsDBViewModel.kt
new file mode 100644
--- /dev/null
+++ b/app/src/main/java/it/reyboz/bustorino/viewmodels/SearchStopsDBViewModel.kt
@@ -0,0 +1,90 @@
+package it.reyboz.bustorino.viewmodels
+
+import android.app.Application
+import android.util.Log
+import androidx.lifecycle.AndroidViewModel
+import androidx.lifecycle.MediatorLiveData
+import androidx.lifecycle.MutableLiveData
+import androidx.lifecycle.distinctUntilChanged
+import androidx.lifecycle.liveData
+import androidx.lifecycle.map
+import androidx.lifecycle.switchMap
+import androidx.lifecycle.viewModelScope
+import it.reyboz.bustorino.backend.Stop
+import it.reyboz.bustorino.data.NextGenDB
+import it.reyboz.bustorino.util.StopSorterSearch
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.delay
+import kotlin.math.min
+import kotlin.time.Duration.Companion.milliseconds
+
+class SearchStopsDBViewModel(application: Application): AndroidViewModel(application) {
+
+ private data class Request(val q: String, val byId: Boolean)
+
+ private val nextGenDB = NextGenDB.getInstance(application)
+
+ var showingSearchSuggestions = false
+
+
+ private val queryLiveData = MutableLiveData(Request("", true))
+ private val numberLimitStop = MutableLiveData(20)
+ val queryResultsLiveData = queryLiveData.distinctUntilChanged().switchMap { r->
+ liveData(viewModelScope.coroutineContext + Dispatchers.IO, timeoutInMs = 0) {
+ if (r.q.isEmpty()) {
+ //showQueryResult.postValue(false)
+ emit(emptyList<Stop>())
+ }
+ else {
+ delay(250.milliseconds)
+ //showQueryResult.postValue(true)
+ val list = nextGenDB.searchStopsByCodeOrName(r.q, r.byId)
+ /*if (r.byId)
+ emit(list.sortedBy { it.ID })
+ else
+ emit(list.sortedBy { it.numRoutesStopping }.reversed())
+
+ */
+ emit(list.sortedWith(StopSorterSearch(r.byId)))
+ }
+ }
+ }
+
+ val showQueryResult = queryResultsLiveData.map { it.isNotEmpty() }
+
+ fun searchStops(query: String, byId: Boolean){
+ //Log.d(TAG, "setting query $query with id $byId, was previously ${queryLiveData.value}")
+ this.queryLiveData.value = Request(query, byId)
+ }
+ fun getQueryStops(): String?{
+ return queryLiveData.value?.q
+ }
+ fun setLimitSearchStops(num: Int){
+ numberLimitStop.value = num
+ }
+
+
+ val filteredStopsSearch = MediatorLiveData<List<Stop>>()
+ private fun setFilteredStops(stops:List<Stop>, num: Int){
+ filteredStopsSearch.postValue(stops.subList(0, min(num, stops.size)))
+ }
+
+ init {
+ filteredStopsSearch.addSource(queryResultsLiveData) {
+ setFilteredStops(it, numberLimitStop.value!!)
+ }
+ filteredStopsSearch.addSource(numberLimitStop) {
+ queryResultsLiveData.value?.let{ stops ->
+ setFilteredStops(stops, it)
+ }
+ }
+ }
+
+ fun saveOpenSearchSuggestions(){
+ showingSearchSuggestions = showQueryResult.value?: false
+ }
+
+ companion object{
+ private const val TAG = "BusTO-SearchStopsVM"
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_main_screen.xml b/app/src/main/res/layout/fragment_main_screen.xml
--- a/app/src/main/res/layout/fragment_main_screen.xml
+++ b/app/src/main/res/layout/fragment_main_screen.xml
@@ -6,115 +6,156 @@
tools:context=".fragments.MainScreenFragment"
android:paddingTop="10dip"
>
- <ImageButton
- android:id="@+id/QRButton"
- style="?android:attr/borderlessButtonStyle"
- android:layout_width="40dip"
- android:layout_height="40dip"
- android:layout_marginStart="16dp"
- android:background="@drawable/qrcode_button_custom"
- android:contentDescription="@string/scan_qr_code_stop"
- android:scaleType="fitCenter"
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintStart_toStartOf="parent"
- />
- <androidx.constraintlayout.widget.Guideline
- android:id="@+id/leftGuide"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:orientation="vertical"
- app:layout_constraintStart_toEndOf="@id/QRButton"
- />
- <EditText
- android:id="@+id/busStopSearchByIDEditText"
+ <com.google.android.material.card.MaterialCardView
+ android:id="@+id/searchCardView"
android:layout_width="0dp"
android:layout_height="wrap_content"
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintBottom_toTopOf="@id/progressBar"
+ app:cardCornerRadius="24dp"
+ app:cardElevation="3dp"
+ app:cardBackgroundColor="?attr/colorSurface"
android:layout_marginEnd="10dp"
android:layout_marginStart="10dp"
- android:ems="10"
- android:hint="@string/insert_bus_stop_number"
- android:imeOptions="actionSearch"
+ android:layout_marginBottom="5dp"
+ android:paddingBottom="4dp"
+ android:animateLayoutChanges="true"
+ >
+ <androidx.constraintlayout.widget.ConstraintLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal">
+ <androidx.appcompat.widget.SearchView
+ android:id="@+id/busStopSearchView"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="5dp"
+ android:layout_marginEnd="10dp"
+ android:imeOptions="actionSearch"
+ android:inputType="number"
+ app:iconifiedByDefault="false"
+ app:queryHint="@string/insert_bus_stop_number"
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintBottom_toTopOf="@id/barrierSearch"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toStartOf="@id/searchButton"
+ app:queryBackground="@null"
+ app:submitBackground="@null"
- android:inputType="number"
- android:selectAllOnFocus="true"
- android:singleLine="true"
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintStart_toStartOf="@id/leftGuide"
- app:layout_constraintEnd_toStartOf="@id/searchButton"
- >
- </EditText>
+ />
+ <ImageButton
+ android:id="@+id/searchButton"
+ style="?android:attr/borderlessButtonStyle"
+ android:layout_width="43dp"
+ android:layout_height="43dip"
+ android:layout_alignTop="@+id/busStopSearchView"
+ android:layout_marginEnd="5dp"
- <!--android:layout_alignParentLeft="true"
- android:layout_alignParentStart="true"-->
- <EditText
- android:id="@+id/busStopSearchByNameEditText"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_marginEnd="10dp"
- android:layout_marginStart="10dp"
- android:inputType="text"
- android:ems="10"
- android:hint="@string/insert_bus_stop_name"
- android:imeOptions="actionSearch"
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintStart_toStartOf="@id/leftGuide"
- app:layout_constraintEnd_toStartOf="@id/searchButton"
- android:singleLine="true"
- android:visibility="gone">
- </EditText>
+ android:background="@drawable/search_button_custom"
+ android:contentDescription="@string/search"
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintBottom_toTopOf="@id/barrierSearch"
+ app:layout_constraintStart_toEndOf="@id/busStopSearchView"
+ app:layout_constraintEnd_toStartOf="@id/QRButton"
+ android:visibility="gone"
+ />
+ <ImageButton
+ android:id="@+id/QRButton"
+ style="?android:attr/borderlessButtonStyle"
+ android:layout_width="40dip"
+ android:layout_height="40dip"
+ android:layout_marginStart="6dp"
+ android:layout_marginEnd="12dp"
+ android:background="@drawable/qrcode_button_custom"
+ android:contentDescription="@string/scan_qr_code_stop"
+ android:scaleType="fitCenter"
- <ImageButton
- android:id="@+id/searchButton"
- style="?android:attr/borderlessButtonStyle"
- android:layout_width="40dip"
- android:layout_height="40dip"
- android:layout_alignTop="@+id/busStopSearchByIDEditText"
- android:layout_marginEnd="16dp"
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintEnd_toEndOf="parent"
- android:background="@drawable/search_button_custom"
- android:contentDescription="@string/search"
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintBottom_toTopOf="@id/barrierSearch"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toEndOf="@id/searchButton"
/>
+ <androidx.constraintlayout.widget.Barrier
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:id="@+id/barrierSearch"
+ app:barrierDirection="bottom"
+ app:constraint_referenced_ids="searchButton,busStopSearchView,QRButton"
+ />
+ <androidx.recyclerview.widget.RecyclerView
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:id="@+id/suggestionsRecyclerView"
+ android:layout_marginTop="5dp"
+ android:layout_marginStart="10dp"
+ android:layout_marginEnd="10dp"
+ android:layout_marginBottom="10dp"
+ app:layout_constraintTop_toBottomOf="@id/barrierSearch"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintBottom_toTopOf="@id/stopSearchMessageTextView"
+ app:layout_constraintHeight_default="wrap"
+ android:visibility="visible"
+ />
+ <TextView android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:id="@+id/stopSearchMessageTextView"
+ app:layout_constraintTop_toBottomOf="@id/suggestionsRecyclerView"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"
+ android:text="@string/no_stop_found_search_number"
+ android:fontFamily="@font/lato_regular"
+ android:layout_marginTop="10dp"
+ android:layout_marginBottom="5dp"
+ android:visibility="visible"
+ />
+ </androidx.constraintlayout.widget.ConstraintLayout>
+
+
+ </com.google.android.material.card.MaterialCardView>
<ProgressBar
android:id="@+id/progressBar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="8dp"
- android:layout_below="@+id/QRButton"
- android:layout_marginTop="5dp"
+ android:layout_marginTop="3dp"
android:layout_marginEnd="10dp"
android:layout_marginStart="10dp"
android:indeterminateOnly="true"
android:minWidth="10dp"
android:visibility="gone"
- app:layout_constraintTop_toBottomOf="@id/searchButton"
+ app:layout_constraintTop_toBottomOf="@id/searchCardView"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
/>
- <androidx.constraintlayout.widget.Barrier
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:id="@+id/barrierSearch"
- app:barrierDirection="bottom"
- app:constraint_referenced_ids="searchButton,QRButton,busStopSearchByIDEditText,busStopSearchByNameEditText"
- />
+
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:id="@+id/coord_layout"
android:layout_gravity="bottom|end"
android:layout_marginTop="4dp"
- app:layout_constraintTop_toBottomOf="@id/barrierSearch"
+ app:layout_constraintTop_toBottomOf="@id/searchCardView"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:flow_verticalBias="0.0"
app:layout_constraintVertical_bias="0.0"
+ android:animateLayoutChanges="true"
>
- <androidx.swiperefreshlayout.widget.SwipeRefreshLayout
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ >
+
+ <androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/listRefreshLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
@@ -126,10 +167,12 @@
<FrameLayout
android:layout_width="match_parent"
android:id="@+id/resultFrame"
- android:layout_height="fill_parent"
+ android:layout_height="match_parent"
android:layout_marginTop="5dp"
android:layout_alignParentStart="true"/>
- </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
+ </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
+ </LinearLayout>
+
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/floatingActionButton"
diff --git a/app/src/main/res/layout/item_stop_nearby_card.xml b/app/src/main/res/layout/item_stop_nearby_card.xml
--- a/app/src/main/res/layout/item_stop_nearby_card.xml
+++ b/app/src/main/res/layout/item_stop_nearby_card.xml
@@ -28,7 +28,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="7261"
- android:textSize="19sp"
+ android:textSize="20sp"
android:textIsSelectable="true"
android:fontFamily="@font/lato_bold"
android:textColor="@color/stop_number_color"
@@ -56,6 +56,23 @@
app:layout_constraintStart_toEndOf="@id/stop_numberText"
app:layout_constraintEnd_toStartOf="@id/stop_distanceTextView"
/>
+
+ <TextView
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:text="STOP"
+ android:id="@+id/stop_locationTextView"
+ android:gravity="center_vertical|start"
+ android:textSize="15sp"
+ android:fontFamily="@font/lato_regular"
+ android:layout_marginBottom="6dp"
+ android:layout_marginTop="4dp"
+ android:layout_marginStart="30dp"
+ android:layout_marginEnd="20dp"
+ app:layout_constraintTop_toBottomOf="@id/stop_nameText"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toStartOf="@id/stop_distanceTextView"
+ />
<TextView
android:text="200m"
android:layout_width="wrap_content"
@@ -86,6 +103,19 @@
android:layout_marginTop="8dp"
android:layout_marginStart="12dp"
/>-->
+ <ImageView
+ android:id="@+id/cardBusIcon"
+ android:layout_width="26dp"
+ android:layout_height="26dp"
+ android:layout_marginStart="13sp"
+ android:layout_marginTop="5sp"
+
+ android:src="@drawable/ic_bus"
+ android:scaleType="fitCenter"
+ app:tint="@color/black_icon_text"
+ app:layout_constraintTop_toBottomOf="@id/stop_locationTextView"
+ app:layout_constraintStart_toStartOf="parent"
+ />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
@@ -98,13 +128,13 @@
android:layout_marginTop="8dp"
android:layout_marginBottom="10dp"
android:layout_marginEnd="15dp"
+ android:layout_marginStart="6dp"
- app:layout_constraintTop_toBottomOf="@id/stop_nameText"
- app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toBottomOf="@id/stop_locationTextView"
+ app:layout_constraintStart_toEndOf="@id/cardBusIcon"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/stop_distanceTextView"
- android:layout_marginStart="50dp"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
</com.google.android.material.card.MaterialCardView>
\ No newline at end of file
diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml
--- a/app/src/main/res/values-it/strings.xml
+++ b/app/src/main/res/values-it/strings.xml
@@ -267,4 +267,6 @@
<string name="no_trip_info_warning">Nessuna informazione trasmessa sulla direzione o sul viaggio del veicolo.</string>
<string name="downloading_trip_info">Download in corso delle informazioni sul viaggio</string>
+ <string name="no_stop_found_search_name">Nessuna fermata trovata con questo nome</string>
+ <string name="no_stop_found_search_number">Nessuna fermata trovata con questo numero</string>
</resources>
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -164,6 +164,8 @@
<string name="position_searching_message">Finding location</string>
<string name="no_stops_nearby">No stops nearby</string>
+ <string name="no_stop_found_search_name">No stop found matching this name</string>
+ <string name="no_stop_found_search_number">No stop found matching this number</string>
<string name="searching_arrivals_indefinite">Loading arrival times</string>
<string name="no_stops_nearby_arrivals">No stops nearby to search arrival times for</string>
<string name="pref_num_elements">Minimum number of stops</string>
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Oct 2, 06:42 (23 h, 2 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2205113
Default Alt Text
D259.1790916145.diff (54 KB)
Attached To
Mode
D259: Show stop suggestions from the database
Attached
Detach File
Event Timeline