[android] Added DataPicker views on filter screen

This commit is contained in:
Александр Зацепин 2018-01-31 15:18:19 +03:00 committed by Arsentiy Milchakov
parent 1c752071cc
commit a47da1f052
3 changed files with 219 additions and 4 deletions

View file

@ -101,6 +101,16 @@
style="@style/MwmTextAppearance.BookingFilter.DateTextView"/>
</LinearLayout>
</LinearLayout>
<TextView
android:id="@+id/offlineWarning"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/margin_base"
android:layout_marginRight="@dimen/margin_base"
android:layout_marginTop="@dimen/margin_half_plus"
android:visibility="gone"
android:text="@string/booking_filters_offline"
android:textAppearance="@style/MwmTextAppearance.BookingFilter.Warning"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"

View file

@ -216,6 +216,11 @@
<item name="android:textAllCaps">true</item>
</style>
<style name="MwmTextAppearance.BookingFilter.Warning" parent="MwmTextAppearance.Body3">
<item name="android:fontFamily" tools:ignore="NewApi">@string/robotoMedium</item>
<item name="android:textColor">@color/button_red</item>
</style>
<style name="MwmTextAppearance.BookingFilter.DateTextView" parent="MwmTextAppearance.Body3">
<item name="android:singleLine">true</item>
<item name="android:ellipsize">end</item>

View file

@ -1,7 +1,12 @@
package com.mapswithme.maps.search;
import android.app.DatePickerDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.drawable.Drawable;
import android.net.ConnectivityManager;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
@ -10,6 +15,7 @@ import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.mapswithme.maps.MwmApplication;
import com.mapswithme.maps.R;
@ -18,15 +24,26 @@ import com.mapswithme.maps.base.BaseMwmToolbarFragment;
import com.mapswithme.maps.widget.ToolbarController;
import com.mapswithme.maps.widget.recycler.TagItemDecoration;
import com.mapswithme.maps.widget.recycler.TagLayoutManager;
import com.mapswithme.util.ConnectionState;
import com.mapswithme.util.UiUtils;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Locale;
import java.util.Set;
import java.util.concurrent.TimeUnit;
public class FilterFragment extends BaseMwmToolbarFragment
implements HotelsTypeAdapter.OnTypeSelectedListener
{
static final DateFormat DATE_FORMATTER = new SimpleDateFormat("EEE, MMM d", Locale.getDefault());
static final String ARG_FILTER = "arg_filter";
static final String ARG_FILTER_PARAMS = "arg_filter_params";
private static final int MAX_STAYING_DAYS = 30;
private static final int MAX_CHECKIN_WINDOW_IN_DAYS = 360;
@Nullable
private CustomNavigateUpListener mNavigateUpListener;
@Nullable
@ -39,12 +56,67 @@ public class FilterFragment extends BaseMwmToolbarFragment
private PriceFilterView mPrice;
@SuppressWarnings("NullableProblems")
@NonNull
private TextView mCheckIn;
@SuppressWarnings("NullableProblems")
@NonNull
private TextView mCheckOut;
@SuppressWarnings("NullableProblems")
@NonNull
private TextView mOfflineWarning;
@NonNull
private final Drawable mTagsDecorator
= ContextCompat.getDrawable(MwmApplication.get(), R.drawable.divider_transparent_half);
@NonNull
private final Set<HotelsFilter.HotelType> mHotelTypes = new HashSet<>();
@Nullable
private HotelsTypeAdapter mTypeAdapter;
@NonNull
private Calendar mCheckinDate = Calendar.getInstance();
@NonNull
private Calendar mCheckoutDate = getDayAfter(mCheckinDate);
@NonNull
private final DatePickerDialog.OnDateSetListener mCheckinListener = (view, year, monthOfYear,
dayOfMonth) ->
{
Calendar chosenDate = Calendar.getInstance();
chosenDate.set(year, monthOfYear, dayOfMonth);
mCheckinDate = chosenDate;
if (mCheckinDate.after(mCheckoutDate))
{
mCheckoutDate = getDayAfter(mCheckinDate);
mCheckOut.setText(DATE_FORMATTER.format(mCheckoutDate.getTime()));
}
else
{
long difference = mCheckoutDate.getTimeInMillis() - mCheckinDate.getTimeInMillis();
int days = (int) TimeUnit.MILLISECONDS.toDays(difference);
if (days > MAX_STAYING_DAYS)
{
mCheckoutDate = getMaxDateForCheckout(mCheckinDate);
mCheckOut.setText(DATE_FORMATTER.format(mCheckoutDate.getTime()));
}
}
mCheckIn.setText(DATE_FORMATTER.format(chosenDate.getTime()));
};
@NonNull
private final DatePickerDialog.OnDateSetListener mCheckoutListener = (view, year, monthOfYear,
dayOfMonth) ->
{
Calendar chosenDate = Calendar.getInstance();
chosenDate.set(year, monthOfYear, dayOfMonth);
mCheckoutDate = chosenDate;
mCheckOut.setText(DATE_FORMATTER.format(mCheckoutDate.getTime()));
};
@NonNull
private final BroadcastReceiver mNetworkStateReceiver = new BroadcastReceiver()
{
@Override
public void onReceive(Context context, Intent intent)
{
enableDateViewsIfConnected();
}
};
@Override
public void onAttach(Context context)
@ -66,6 +138,21 @@ public class FilterFragment extends BaseMwmToolbarFragment
mListener = null;
}
@Override
public void onStart()
{
super.onStart();
IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
getActivity().registerReceiver(mNetworkStateReceiver, filter);
}
@Override
public void onStop()
{
getActivity().unregisterReceiver(mNetworkStateReceiver);
super.onStop();
}
@Override
protected ToolbarController onCreateToolbarController(@NonNull View root)
{
@ -88,8 +175,11 @@ public class FilterFragment extends BaseMwmToolbarFragment
@Nullable Bundle savedInstanceState)
{
View root = inflater.inflate(R.layout.fragment_search_filter, container, false);
initDateViews(root);
mRating = root.findViewById(R.id.rating);
mPrice = root.findViewById(R.id.price);
// Explicit casting is needed in this case, otherwise the crash is obtained in runtime,
// seems like a bug in current compiler (Java 8)
mPrice = root.<PriceFilterView>findViewById(R.id.price);
View content = root.findViewById(R.id.content);
RecyclerView type = content.findViewById(R.id.type);
type.setLayoutManager(new TagLayoutManager());
@ -106,20 +196,105 @@ public class FilterFragment extends BaseMwmToolbarFragment
HotelsFilter filter = populateFilter();
mListener.onFilterApply(filter);
});
Bundle args = getArguments();
HotelsFilter filter = null;
BookingFilterParams params = null;
if (args != null)
{
filter = args.getParcelable(ARG_FILTER);
updateViews(filter);
params = args.getParcelable(ARG_FILTER_PARAMS);
}
updateViews(filter, params);
return root;
}
private void initDateViews(View root)
{
mCheckIn = root.findViewById(R.id.checkIn);
mCheckIn.setOnClickListener(
v ->
{
DatePickerDialog dialog =
new DatePickerDialog(getActivity(), mCheckinListener, mCheckinDate.get(Calendar.YEAR),
mCheckinDate.get(Calendar.MONTH),
mCheckinDate.get(Calendar.DAY_OF_MONTH));
dialog.getDatePicker().setMinDate(getMinDateForCheckin().getTimeInMillis());
dialog.getDatePicker().setMaxDate(getMaxDateForCheckin().getTimeInMillis());
dialog.show();
});
mCheckOut = root.findViewById(R.id.checkOut);
mCheckOut.setOnClickListener(
v ->
{
DatePickerDialog dialog
= new DatePickerDialog(getActivity(), mCheckoutListener,
mCheckoutDate.get(Calendar.YEAR),
mCheckoutDate.get(Calendar.MONTH),
mCheckoutDate.get(Calendar.DAY_OF_MONTH));
dialog.getDatePicker().setMinDate(getDayAfter(mCheckinDate).getTimeInMillis());
dialog.getDatePicker().setMaxDate(getMaxDateForCheckout(mCheckinDate).getTimeInMillis());
dialog.show();
});
mOfflineWarning = root.findViewById(R.id.offlineWarning);
enableDateViewsIfConnected();
}
private void enableDateViewsIfConnected()
{
UiUtils.showIf(!ConnectionState.isConnected(), mOfflineWarning);
mCheckIn.setEnabled(ConnectionState.isConnected());
mCheckOut.setEnabled(ConnectionState.isConnected());
}
@NonNull
private static Calendar getMinDateForCheckin()
{
Calendar date = Calendar.getInstance();
// This little subtraction is needed to avoid the crash on old androids (e.g. 4.4).
date.add(Calendar.SECOND, -1);
return date;
}
@NonNull
private static Calendar getMaxDateForCheckin()
{
Calendar date = Calendar.getInstance();
date.add(Calendar.DAY_OF_YEAR, MAX_CHECKIN_WINDOW_IN_DAYS);
return date;
}
@NonNull
private static Calendar getMaxDateForCheckout(@NonNull Calendar checkin)
{
long difference = checkin.getTimeInMillis() - System.currentTimeMillis();
int daysToCheckin = (int) TimeUnit.MILLISECONDS.toDays(difference);
int leftDays = MAX_CHECKIN_WINDOW_IN_DAYS - daysToCheckin;
Calendar date = Calendar.getInstance();
date.setTime(checkin.getTime());
date.add(Calendar.DAY_OF_YEAR, leftDays >= MAX_STAYING_DAYS ? MAX_STAYING_DAYS : leftDays);
return date;
}
@NonNull
private static Calendar getDayAfter(@NonNull Calendar date)
{
Calendar dayAfter = Calendar.getInstance();
dayAfter.setTime(date.getTime());
dayAfter.add(Calendar.DAY_OF_YEAR, 1);
return dayAfter;
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState)
{
super.onViewCreated(view, savedInstanceState);
mToolbarController.setTitle(R.string.booking_filters);
mToolbarController.findViewById(R.id.reset).setOnClickListener(v -> updateViews(null));
mToolbarController.findViewById(R.id.reset)
.setOnClickListener(v -> updateViews(null, null));
}
@Nullable
@ -162,7 +337,7 @@ public class FilterFragment extends BaseMwmToolbarFragment
return result;
}
private void updateViews(@Nullable HotelsFilter filter)
private void updateViews(@Nullable HotelsFilter filter, @Nullable BookingFilterParams params)
{
if (filter == null)
{
@ -178,6 +353,31 @@ public class FilterFragment extends BaseMwmToolbarFragment
if (mTypeAdapter != null)
updateTypeAdapter(mTypeAdapter, findTypeFilter(filter));
}
updateDateViews(params);
}
private void updateDateViews(@Nullable BookingFilterParams params)
{
if (params == null)
{
mCheckinDate = Calendar.getInstance();
mCheckIn.setText(DATE_FORMATTER.format(mCheckinDate.getTime()));
mCheckoutDate = getDayAfter(mCheckinDate);
mCheckOut.setText(DATE_FORMATTER.format(mCheckoutDate.getTime()));
}
else
{
Calendar checkin = Calendar.getInstance();
checkin.setTimeInMillis(params.getCheckinMillisec());
mCheckinDate = checkin;
mCheckIn.setText(DATE_FORMATTER.format(mCheckinDate.getTime()));
Calendar checkout = Calendar.getInstance();
checkout.setTimeInMillis(params.getCheckoutMillisec());
mCheckinDate = checkout;
mCheckOut.setText(DATE_FORMATTER.format(mCheckoutDate.getTime()));
}
}
@Nullable