Current status, list size is working, visibility working, filter mechanism is ready

This commit is contained in:
neslihanturan 2019-10-11 19:11:50 +03:00
parent 56334afe03
commit 7d75c9c589
13 changed files with 279 additions and 116 deletions

View file

@ -6,6 +6,7 @@ import android.graphics.Bitmap;
import androidx.vectordrawable.graphics.drawable.VectorDrawableCompat;
import com.mapbox.mapboxsdk.annotations.IconFactory;
import com.mapbox.mapboxsdk.annotations.Marker;
import java.io.IOException;
import java.util.ArrayList;
@ -33,6 +34,10 @@ public class NearbyController {
public static LatLng latestSearchLocation; // Can be current and camera target on search this area button is used
public static double latestSearchRadius = 10.0; // Any last search radius except closest result search
public static Map<String, Marker> markerLabelMap;
public static Map<Boolean, Marker> markerExistsMap;
public static Map<Boolean, Marker> markerNeedPicMap;
@Inject
public NearbyController(NearbyPlaces nearbyPlaces) {
this.nearbyPlaces = nearbyPlaces;

View file

@ -1,75 +0,0 @@
package fr.free.nrw.commons.nearby;
import android.content.Context;
import android.graphics.drawable.Icon;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.ArrayList;
import fr.free.nrw.commons.R;
public class NearbyFilterSearchListViewAdapter extends ArrayAdapter<Label> {
private final LayoutInflater inflater;
private ViewHolder viewHolder;
private final ArrayList<Label> labels;
public NearbyFilterSearchListViewAdapter(Context context, ArrayList<Label> labels) {
super(context,0, labels);
this.labels = labels;
inflater = LayoutInflater.from(context);
}
@Override
public int getCount() {
return labels.size();
}
@Override
public Label getItem(int position) {
return labels.get(position);
}
@Override
public long getItemId(int position) {
return labels.get(position).hashCode();
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = inflater.inflate(R.layout.nearby_search_list_item, null);
viewHolder = new ViewHolder();
viewHolder.placeLabel = convertView.findViewById(R.id.place_text);
viewHolder.placeIcon = convertView.findViewById(R.id.place_icon);
convertView.setTag(viewHolder);
}
else{
//Get viewholder we already created
viewHolder = (ViewHolder)convertView.getTag();
}
Label label = labels.get(position);
if(label != null){
viewHolder.placeIcon.setImageResource(label.getIcon());
viewHolder.placeLabel.setText(label.toString());
}
return convertView;
}
//View Holder Pattern for better performance
private static class ViewHolder {
TextView placeLabel;
ImageView placeIcon;
}
}

View file

@ -0,0 +1,139 @@
package fr.free.nrw.commons.nearby;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
import fr.free.nrw.commons.R;
public class NearbyFilterSearchRecyclerViewAdapter
extends RecyclerView.Adapter<NearbyFilterSearchRecyclerViewAdapter.RecyclerViewHolder>
implements Filterable {
private final LayoutInflater inflater;
private Context context;
private ArrayList<Label> labels;
private ArrayList<Label> displayedLabels;
public NearbyFilterSearchRecyclerViewAdapter(Context context, ArrayList<Label> labels) {
this.context = context;
this.labels = labels;
this.displayedLabels = labels;
inflater = LayoutInflater.from(context);
}
public class RecyclerViewHolder extends RecyclerView.ViewHolder {
public TextView placeLabel;
public ImageView placeIcon;
public RecyclerViewHolder(View view) {
super(view);
placeLabel = view.findViewById(R.id.place_text);
placeIcon = view.findViewById(R.id.place_icon);
}
}
@NonNull
@Override
public RecyclerViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View itemView = inflater.inflate(R.layout.nearby_search_list_item, parent, false);
return new RecyclerViewHolder(itemView);
}
@Override
public void onBindViewHolder(@NonNull RecyclerViewHolder holder, int position) {
Label label = displayedLabels.get(position);
holder.placeIcon.setImageResource(label.getIcon());
holder.placeLabel.setText(label.toString());
}
@Override
public long getItemId(int position) {
return displayedLabels.get(position).hashCode();
}
@Override
public int getItemCount() {
return displayedLabels.size();
}
@Override
public Filter getFilter() {
return new Filter() {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
ArrayList<Label> filteredArrayList = new ArrayList<>();
if (labels == null) {
labels = new ArrayList<>(displayedLabels);
}
if (constraint == null || constraint.length() == 0) {
// set the Original result to return
results.count = labels.size();
results.values = labels;
} else {
constraint = constraint.toString().toLowerCase();
for (Label label : labels) {
String data = label.toString();
if (data.toLowerCase().startsWith(constraint.toString())) {
filteredArrayList.add(Label.fromText(label.getText()));
}
}
// set the Filtered result to return
results.count = filteredArrayList.size();
results.values = filteredArrayList;
}
return results;
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
displayedLabels = (ArrayList<Label>) results.values; // has the filtered values
notifyDataSetChanged(); // notifies the data with new filtered values
}
};
}
/*
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = inflater.inflate(R.layout.nearby_search_list_item, null);
viewHolder = new RecyclerViewHolder();
viewHolder.placeLabel = convertView.findViewById(R.id.place_text);
viewHolder.placeIcon = convertView.findViewById(R.id.place_icon);
convertView.setTag(viewHolder);
}
else{
//Get viewholder we already created
viewHolder = (RecyclerViewHolder)convertView.getTag();
}
Label label = displayedLabels.get(position);
if(label != null){
viewHolder.placeIcon.setImageResource(label.getIcon());
viewHolder.placeLabel.setText(label.toString());
}
return convertView;
}
*/
}

View file

@ -27,5 +27,7 @@ public interface NearbyMapContract {
void addOnCameraMoveListener(MapboxMap.OnCameraMoveListener onCameraMoveListener);
void centerMapToPlace(Place place, boolean isPortraitMode);
void removeCurrentLocationMarker();
List<NearbyBaseMarker> getBaseMarkerOptions();
void filterMarkersByLabels(NearbyBaseMarker nearbyBaseMarker);
}
}

View file

@ -49,6 +49,7 @@ public interface NearbyParentFragmentContract {
void setActionListeners(JsonKvStore applicationKvStore);
void backButtonClicked();
MapboxMap.OnCameraMoveListener onCameraMove(MapboxMap mapboxMap);
void filterByMarkerType(String placeType);
}
interface ViewsAreReadyCallback {

View file

@ -2,8 +2,11 @@ package fr.free.nrw.commons.nearby.fragments;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.VectorDrawable;
import android.os.Bundle;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@ -12,6 +15,7 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.vectordrawable.graphics.drawable.VectorDrawableCompat;
import com.mapbox.geojson.Feature;
import com.mapbox.mapboxsdk.annotations.Icon;
import com.mapbox.mapboxsdk.annotations.IconFactory;
import com.mapbox.mapboxsdk.annotations.Marker;
@ -25,10 +29,13 @@ import com.mapbox.mapboxsdk.maps.MapView;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.maps.MapboxMapOptions;
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
import com.mapbox.mapboxsdk.style.layers.SymbolLayer;
import com.mapbox.mapboxsdk.utils.MapFragmentUtils;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.inject.Inject;
@ -75,6 +82,7 @@ public class NearbyMapFragment extends CommonsDaggerSupportFragment
private MapView map;
private Marker currentLocationMarker;
private Polygon currentLocationPolygon;
private List<NearbyBaseMarker> customBaseMarkerOptions;
private final double CAMERA_TARGET_SHIFT_FACTOR_PORTRAIT = 0.005;
private final double CAMERA_TARGET_SHIFT_FACTOR_LANDSCAPE = 0.004;
@ -273,7 +281,7 @@ public class NearbyMapFragment extends CommonsDaggerSupportFragment
, Marker selectedMarker
, NearbyParentFragmentPresenter nearbyParentFragmentPresenter) {
Timber.d("Updates map markers");
List<NearbyBaseMarker> customBaseMarkerOptions = NearbyController
customBaseMarkerOptions = NearbyController
.loadAttractionsFromLocationToBaseMarkerOptions(latLng, // Curlatlang will be used to calculate distances
placeList,
getActivity(),
@ -336,6 +344,22 @@ public class NearbyMapFragment extends CommonsDaggerSupportFragment
mapboxMap.removePolygon(currentLocationPolygon);
}
@Override
public void filterMarkersByLabels(NearbyBaseMarker nearbyBaseMarker) {
Log.d("deneme55","name:"+nearbyBaseMarker.getPlace().getLabel().toString());
VectorDrawableCompat vectorDrawable = VectorDrawableCompat.create(
getContext().getResources(), R.drawable.ic_custom_greyed_out_marker, getContext().getTheme());
Bitmap icon = UiUtils.getBitmap(vectorDrawable);
NearbyController.markerLabelMap.get(nearbyBaseMarker.getPlace().getLabel().toString()).setIcon(IconFactory.getInstance(getContext()).fromBitmap(icon));
}
@Override
public List<NearbyBaseMarker> getBaseMarkerOptions() {
return customBaseMarkerOptions;
}
/**
* Adds markers to map
* @param baseMarkerList is markers will be added
@ -346,7 +370,21 @@ public class NearbyMapFragment extends CommonsDaggerSupportFragment
public void addNearbyMarkersToMapBoxMap(@Nullable List<NearbyBaseMarker> baseMarkerList
, Marker selectedMarker
, NearbyParentFragmentPresenter nearbyParentFragmentPresenter) {
mapboxMap.addMarkers(baseMarkerList);
List<Marker> markers = mapboxMap.addMarkers(baseMarkerList);
Log.d("deneme66","markers:"+markers.get(0).getTitle()+", baseMarkers:"+baseMarkerList.get(0).getPlace().getName());
Log.d("deneme66","markers:"+markers.get(1).getTitle()+", baseMarkers:"+baseMarkerList.get(1).getPlace().getName());
NearbyController.markerLabelMap = new HashMap<String, Marker>();
NearbyController.markerExistsMap = new HashMap<Boolean, Marker>();
NearbyController.markerNeedPicMap = new HashMap<Boolean, Marker>();
for (int i = 0; i < baseMarkerList.size(); i++) {
// An example item: <Park, marker of that park>
NearbyController.markerLabelMap.put(baseMarkerList.get(i).getPlace().getLabel().toString(), markers.get(i));
NearbyController.markerExistsMap.put((baseMarkerList.get(i).getPlace().hasWikidataLink()), markers.get(i));
NearbyController.markerNeedPicMap.put(((baseMarkerList.get(i).getPlace().pic == null) ? true : false), markers.get(i));
}
map.getMapAsync(mapboxMap -> {
mapboxMap.addMarkers(baseMarkerList);
setMapMarkerActions(selectedMarker, nearbyParentFragmentPresenter);
@ -457,5 +495,7 @@ public class NearbyMapFragment extends CommonsDaggerSupportFragment
.build();
mapboxMap.animateCamera(CameraUpdateFactory.newCameraPosition(position), 1000);
}
}

View file

@ -15,12 +15,10 @@ import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.SearchView;
import android.widget.TextView;
@ -30,6 +28,8 @@ import androidx.annotation.NonNull;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.bottomsheet.BottomSheetBehavior;
import com.google.android.material.chip.Chip;
@ -64,9 +64,8 @@ import fr.free.nrw.commons.contributions.MainActivity;
import fr.free.nrw.commons.di.CommonsDaggerSupportFragment;
import fr.free.nrw.commons.kvstore.JsonKvStore;
import fr.free.nrw.commons.location.LocationServiceManager;
import fr.free.nrw.commons.nearby.Label;
import fr.free.nrw.commons.nearby.NearbyController;
import fr.free.nrw.commons.nearby.NearbyFilterSearchListViewAdapter;
import fr.free.nrw.commons.nearby.NearbyFilterSearchRecyclerViewAdapter;
import fr.free.nrw.commons.nearby.NearbyMarker;
import fr.free.nrw.commons.nearby.Place;
import fr.free.nrw.commons.nearby.contract.NearbyParentFragmentContract;
@ -123,8 +122,8 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
@BindView(R.id.choice_chip_exists) Chip chipExists;
@BindView(R.id.choice_chip_needs_photo) Chip chipNeedsPhoto;
@BindView(R.id.search_view) SearchView searchView;
@BindView(R.id.search_list_view) ListView searchListView;
@BindView(R.id.nearby_filter_list_layout) LinearLayout nearbyFilterListLayout;
@BindView(R.id.search_list_view) RecyclerView searchListView;
@BindView(R.id.nearby_filter_list) View nearbyFilterList;
@Inject LocationServiceManager locationManager;
@Inject NearbyController nearbyController;
@ -176,7 +175,6 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
super.onResume();
nearbyMapFragment = getNearbyMapFragment();
nearbyListFragment = getListFragment();
initNearbyFilter();
}
@ -200,26 +198,41 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
}
public void initNearbyFilter() {
nearbyFilterList.setVisibility(View.GONE);
NearbyFilterSearchListViewAdapter nearbyFilterSearchListViewAdapter
= new NearbyFilterSearchListViewAdapter(getContext(),new ArrayList<>(TEXT_TO_DESCRIPTION.values()));
searchListView.setAdapter(nearbyFilterSearchListViewAdapter);
LayoutUtils.setLayoutHeightAllignedToWidth(1, nearbyFilterListLayout);
searchView.setOnQueryTextFocusChangeListener((v, hasFocus) -> {
if (hasFocus) {
//Log.d("deneme33","11-"+searchListView.getAdapter().getCount());
nearbyFilterList.setVisibility(View.VISIBLE);
} else {
// Log.d("deneme33","22-"+searchListView.getAdapter().getCount());
nearbyFilterList.setVisibility(View.GONE);
}
});
searchListView.setHasFixedSize(true);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity());
linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
searchListView.setLayoutManager(linearLayoutManager);
NearbyFilterSearchRecyclerViewAdapter nearbyFilterSearchRecyclerViewAdapter
= new NearbyFilterSearchRecyclerViewAdapter(getContext(),new ArrayList<>(TEXT_TO_DESCRIPTION.values()));
nearbyFilterList.getLayoutParams().width = (int) LayoutUtils.getScreenWidth(getActivity(), 0.75);
searchListView.setAdapter(nearbyFilterSearchRecyclerViewAdapter);
LayoutUtils.setLayoutHeightAllignedToWidth(1, nearbyFilterList);
/*searchListView.setOnItemClickListener((parent, view, position, id) -> {
Log.d("deneme33","item clicked:"+ nearbyFilterSearchRecyclerViewAdapter.get(position).toString());
nearbyParentFragmentPresenter.filterByMarkerType(nearbyFilterSearchRecyclerViewAdapter.getItem(position).toString());
});*/
compositeDisposable.add(RxSearchView.queryTextChanges(searchView)
.takeUntil(RxView.detaches(searchView))
.debounce(500, TimeUnit.MILLISECONDS)
.observeOn(AndroidSchedulers.mainThread())
.subscribe( query -> {
Log.d("deneme4","query:"+query);
if (!query.equals("")) {
Log.d("deneme4","query if:"+query);
nearbyFilterListLayout.setVisibility(View.VISIBLE);
} else {
nearbyFilterListLayout.setVisibility(View.GONE);
}
}
));
((NearbyFilterSearchRecyclerViewAdapter)searchListView.getAdapter()).getFilter().filter(query.toString());
}));
}
/**
@ -429,6 +442,7 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
nearbyParentFragmentPresenter.nearbyFragmentsAreReady();
initViews();
nearbyParentFragmentPresenter.setActionListeners(applicationKvStore);
initNearbyFilter();
}
@Override

View file

@ -1,14 +1,18 @@
package fr.free.nrw.commons.nearby.presenter;
import android.util.Log;
import android.view.View;
import com.mapbox.mapboxsdk.annotations.Marker;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import java.util.List;
import fr.free.nrw.commons.kvstore.JsonKvStore;
import fr.free.nrw.commons.location.LatLng;
import fr.free.nrw.commons.location.LocationServiceManager;
import fr.free.nrw.commons.location.LocationUpdateListener;
import fr.free.nrw.commons.nearby.NearbyBaseMarker;
import fr.free.nrw.commons.nearby.NearbyController;
import fr.free.nrw.commons.nearby.Place;
import fr.free.nrw.commons.nearby.contract.NearbyMapContract;
@ -345,6 +349,18 @@ public class NearbyParentFragmentPresenter
};
}
@Override
public void filterByMarkerType(String placeType) {
List<NearbyBaseMarker> nearbyBaseMarkerList = nearbyMapFragmentView.getBaseMarkerOptions();
for (NearbyBaseMarker nearbyBaseMarker : nearbyBaseMarkerList) {
// filter from existing markers
if (!nearbyBaseMarker.getPlace().getLabel().toString().equals(placeType)) {
Log.d("deneme44",nearbyBaseMarker.getPlace().name);
nearbyMapFragmentView.filterMarkersByLabels(nearbyBaseMarker);
}
}
}
public View.OnClickListener onSearchThisAreaClicked() {
return v -> {
// Lock map operations during search this area operation

View file

@ -1,5 +1,8 @@
package fr.free.nrw.commons.utils;
import android.app.Activity;
import android.content.Context;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
@ -49,4 +52,10 @@ public class LayoutUtils {
}
});
}
public static double getScreenWidth(Context context, double rate) {
DisplayMetrics displayMetrics = new DisplayMetrics();
((Activity)context).getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
return displayMetrics.widthPixels * rate;
}
}

View file

@ -0,0 +1,23 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="28dp"
android:viewportWidth="24.0"
android:viewportHeight="28.0">
<path
android:fillAlpha="0.1"
android:fillColor="#48000000"
android:pathData="M6.072,22.223a6.031,3.672 0,1 0,12.062 0a6.031,3.672 0,1 0,-12.062 0z"
android:strokeWidth="1" />
<path
android:fillAlpha="1"
android:fillColor="#4D000000"
android:pathData="M11.575,11.62C10.689,11.462 9.902,10.759 9.625,9.878 9.553,9.65 9.535,9.499 9.538,9.14c0.004,-0.397 0.019,-0.492 0.13,-0.787 0.236,-0.631 0.646,-1.099 1.212,-1.382 0.386,-0.193 0.709,-0.272 1.116,-0.272 0.676,0 1.263,0.247 1.744,0.734 0.355,0.359 0.541,0.682 0.657,1.136 0.327,1.278 -0.442,2.611 -1.723,2.987 -0.282,0.083 -0.817,0.114 -1.099,0.063z"
android:strokeWidth="1" />
<path
android:fillAlpha="1"
android:fillColor="#7CE4E0D9"
android:pathData="M11.617,21.707C10.518,20.424 9.338,18.864 8.395,17.449 6.524,14.641 5.455,12.305 5.102,10.255 5.014,9.744 5.006,8.628 5.088,8.137 5.348,6.561 6.043,5.221 7.158,4.148 9.148,2.231 12.016,1.668 14.593,2.688c2.043,0.809 3.607,2.581 4.162,4.719 0.174,0.67 0.204,0.933 0.203,1.761 -0.001,0.81 -0.035,1.098 -0.22,1.857 -0.614,2.524 -2.571,5.977 -5.383,9.501 -0.645,0.809 -1.321,1.61 -1.358,1.61 -0.008,0 -0.179,-0.193 -0.381,-0.428zM12.617,11.603c0.783,-0.188 1.457,-0.795 1.738,-1.564 0.516,-1.415 -0.317,-2.962 -1.783,-3.312 -0.216,-0.052 -0.317,-0.059 -0.661,-0.047 -0.354,0.012 -0.441,0.025 -0.682,0.104 -0.673,0.221 -1.205,0.695 -1.506,1.344 -0.176,0.38 -0.218,0.584 -0.217,1.054 0.001,0.324 0.014,0.452 0.064,0.635 0.266,0.97 1.077,1.689 2.079,1.844 0.243,0.038 0.68,0.012 0.968,-0.057z"
android:strokeAlpha="1"
android:strokeColor="#54003B59"
android:strokeWidth="1" />
</vector>

View file

@ -16,9 +16,11 @@
android:id="@+id/nearby_filter"/>
<include layout="@layout/nearby_filter_list"
android:id="@+id/nearby_filter_list"
android:layout_below="@id/nearby_filter"
android:layout_height="wrap_content"
android:layout_width="wrap_content" />
android:layout_height="160dp"
android:layout_width="160dp"
android:layout_alignParentEnd="true"/>
<FrameLayout
android:id="@+id/container"

View file

@ -3,23 +3,12 @@
android:id="@+id/nearby_filter_list_layout"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_marginStart="72dp"
android:elevation="6dp">
android:elevation="8dp"
android:background="@color/white">
<ListView
android:id="@+id/selected_items_list_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@android:color/darker_gray"/>
<ListView
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/search_list_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"

View file

@ -1,8 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_alignParentEnd="true"
android:layout_alignParentLeft="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content">