.
This commit is contained in:
@@ -2,9 +2,20 @@ package com.ssb.simplitend.apputils;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.os.Handler;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.RawRes;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialog;
|
||||
import com.ssb.simplitend.R;
|
||||
import com.ssb.simplitend.databinding.DecisionBottomsheetBinding;
|
||||
import com.ssb.simplitend.databinding.DoneBottomsheetBinding;
|
||||
|
||||
public abstract class AppUtil {
|
||||
|
||||
// closes keyboard
|
||||
@@ -18,4 +29,63 @@ public abstract class AppUtil {
|
||||
}
|
||||
}
|
||||
|
||||
// show decision dialog
|
||||
public static void showSOSDecision(@NonNull Context context,
|
||||
@NonNull String decisionText,
|
||||
@NonNull String positiveText, @NonNull String negativeText,
|
||||
View.OnClickListener positiveClickListener,
|
||||
View.OnClickListener negativeClickListener) {
|
||||
|
||||
DecisionBottomsheetBinding binding = DecisionBottomsheetBinding.inflate(LayoutInflater.from(context));
|
||||
|
||||
BottomSheetDialog bsd = new BottomSheetDialog(context, R.style.BottomSheetDialog);
|
||||
bsd.setContentView(binding.getRoot());
|
||||
bsd.setCancelable(false);
|
||||
|
||||
binding.text.setText(decisionText);
|
||||
|
||||
binding.positiveBtn.setText(positiveText);
|
||||
binding.negativeBtn.setText(negativeText);
|
||||
|
||||
binding.negativeBtn.setOnClickListener(v -> {
|
||||
bsd.dismiss();
|
||||
negativeClickListener.onClick(v);
|
||||
});
|
||||
|
||||
binding.positiveBtn.setOnClickListener(v -> {
|
||||
bsd.dismiss();
|
||||
positiveClickListener.onClick(v);
|
||||
});
|
||||
|
||||
bsd.show();
|
||||
|
||||
}
|
||||
|
||||
public static void showAnimateDBS(@NonNull Context context,
|
||||
@NonNull String title,
|
||||
@RawRes int rawRes, long doneInterval,
|
||||
@NonNull View.OnClickListener doneListener){
|
||||
DoneBottomsheetBinding binding = DoneBottomsheetBinding.inflate(LayoutInflater.from(context));
|
||||
|
||||
BottomSheetDialog bsd = new BottomSheetDialog(context, R.style.BottomSheetDialog);
|
||||
bsd.setContentView(binding.getRoot());
|
||||
bsd.setCancelable(false);
|
||||
|
||||
binding.text.setText(title);
|
||||
|
||||
Glide.with(context)
|
||||
.asGif()
|
||||
.load(rawRes)
|
||||
.into(binding.doneAnim);
|
||||
|
||||
bsd.show();
|
||||
|
||||
new Handler().postDelayed(() -> {
|
||||
|
||||
bsd.dismiss();
|
||||
doneListener.onClick(null);
|
||||
|
||||
}, doneInterval);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.ssb.simplitend.apputils;
|
||||
|
||||
/*
|
||||
This a static data of user's profile progress
|
||||
|
||||
THIS FILE WILL BE DELETED AFTERWARDS
|
||||
*/
|
||||
public class ProfileProgress {
|
||||
|
||||
public static final boolean[] PROFILE_PROGRESS = {false, false, false, false};
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.ssb.simplitend.medicalinfo;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
import com.ssb.simplitend.databinding.AddMedicalInfoBinding;
|
||||
|
||||
public class AddMedicalInfoFragment extends Fragment {
|
||||
|
||||
// view binding
|
||||
protected AddMedicalInfoBinding binding;
|
||||
|
||||
public AddMedicalInfoFragment(){
|
||||
// required empty const.
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
binding = AddMedicalInfoBinding.inflate(inflater, container, false);
|
||||
|
||||
return binding.getRoot();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package com.ssb.simplitend.medicalinfo;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.navigation.Navigation;
|
||||
|
||||
import com.ssb.simplitend.R;
|
||||
import com.ssb.simplitend.databinding.MedicalIntoFragmentBinding;
|
||||
|
||||
public class MedicalInfoFragment extends Fragment {
|
||||
|
||||
// view binding
|
||||
protected MedicalIntoFragmentBinding binding;
|
||||
|
||||
public MedicalInfoFragment(){
|
||||
// required empty const.
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
binding = MedicalIntoFragmentBinding.inflate(inflater, container, false);
|
||||
|
||||
clickEvents();
|
||||
|
||||
return binding.getRoot();
|
||||
}
|
||||
|
||||
private void clickEvents() {
|
||||
|
||||
binding.addMedInfo.setOnClickListener(v ->
|
||||
{
|
||||
Navigation.findNavController(v).navigate(R.id.action_medicalInfoFragment_to_addMedicalInfoFragment);
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,346 @@
|
||||
package com.ssb.simplitend.medreminder;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.DatePickerDialog;
|
||||
import android.app.TimePickerDialog;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.CompoundButton;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.content.res.AppCompatResources;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.navigation.Navigation;
|
||||
|
||||
import com.ssb.simplitend.R;
|
||||
import com.ssb.simplitend.apputils.AppUtil;
|
||||
import com.ssb.simplitend.databinding.AddReminderFragmentBinding;
|
||||
import com.ssb.simplitend.medreminder.mvvm.Reminder;
|
||||
import com.ssb.simplitend.welcome.fragments.contacts.mvvm.Contact;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Locale;
|
||||
|
||||
public class AddReminderFragment extends Fragment implements CompoundButton.OnCheckedChangeListener {
|
||||
|
||||
// view binding
|
||||
protected AddReminderFragmentBinding binding;
|
||||
|
||||
/*
|
||||
week day selection states
|
||||
true -> selected
|
||||
false -> un-selected
|
||||
*/
|
||||
boolean[] week_state;
|
||||
|
||||
// arguments keys
|
||||
public static final String REMINDER_KEY = "reminder_key";
|
||||
|
||||
// model
|
||||
private Reminder reminder;
|
||||
|
||||
public AddReminderFragment() {
|
||||
// required empty const.
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
binding = AddReminderFragmentBinding.inflate(inflater, container, false);
|
||||
|
||||
initViews();
|
||||
|
||||
clickEvents();
|
||||
|
||||
return binding.getRoot();
|
||||
}
|
||||
|
||||
private void clickEvents() {
|
||||
|
||||
binding.getTime.setOnClickListener(v -> {
|
||||
AppUtil.closeKeyboard(requireActivity());
|
||||
getTime();
|
||||
});
|
||||
|
||||
binding.getDate.setOnClickListener(v -> {
|
||||
AppUtil.closeKeyboard(requireActivity());
|
||||
getDate();
|
||||
});
|
||||
|
||||
binding.addReminder.setOnClickListener(v -> {
|
||||
if (reminder == null){
|
||||
Navigation.findNavController(v).popBackStack(R.id.reminderFragment, false, true);
|
||||
}else{
|
||||
AppUtil.showSOSDecision(requireContext(), getString(R.string.make_changes),
|
||||
getString(R.string.yes), getString(R.string.no),
|
||||
v1 -> {
|
||||
// yes click
|
||||
AppUtil.showAnimateDBS(requireContext(),
|
||||
getString(R.string.changes_successful), R.raw.done_anim_primary,
|
||||
3000, v3 -> {
|
||||
// here v3 is null
|
||||
Navigation.findNavController(v).popBackStack(R.id.reminderFragment, false, true);
|
||||
});
|
||||
}, v2 -> {
|
||||
// no click
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
private void initViews() {
|
||||
|
||||
// checking if intent to EDIT or ADD reminder
|
||||
Bundle bundle = getArguments();
|
||||
if (bundle != null) setLayoutDetails(reminder = (Reminder) bundle.getSerializable(REMINDER_KEY));
|
||||
|
||||
// scrolling instruction edit text
|
||||
binding.instructions.setOnTouchListener((v, event) -> {
|
||||
if (binding.instructions.hasFocus()) {
|
||||
v.getParent().requestDisallowInterceptTouchEvent(true);
|
||||
if ((event.getAction() & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_SCROLL) {
|
||||
v.getParent().requestDisallowInterceptTouchEvent(false);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
// load into spinner
|
||||
loadMedType();
|
||||
loadFrequency();
|
||||
|
||||
setUpWeekSelection();
|
||||
|
||||
binding.everydayCheck.setOnCheckedChangeListener(this);
|
||||
|
||||
}
|
||||
|
||||
private void setLayoutDetails(Reminder reminder){
|
||||
if (reminder != null){
|
||||
// intent is to edit the reminder
|
||||
binding.title.setText(getString(R.string.edit_reminder));
|
||||
binding.medicName.setText(reminder.dosage_name);
|
||||
binding.quantity.setText(reminder.quantity);
|
||||
binding.getTime.setText(reminder.time);
|
||||
}
|
||||
}
|
||||
|
||||
// every-dau toggle listener
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
|
||||
for (int i = 0; i < 7; i++) {
|
||||
setSelectionState(i, week_state[i] = isChecked);
|
||||
}
|
||||
}
|
||||
|
||||
// set selection and un-selection of week day
|
||||
private void setUpWeekSelection() {
|
||||
|
||||
week_state = new boolean[7];
|
||||
|
||||
// week day selections
|
||||
binding.sun.setOnClickListener(v -> setSelectionState(0, week_state[0] = !week_state[0]));
|
||||
binding.mon.setOnClickListener(v -> setSelectionState(1, week_state[1] = !week_state[1]));
|
||||
binding.tue.setOnClickListener(v -> setSelectionState(2, week_state[2] = !week_state[2]));
|
||||
binding.wed.setOnClickListener(v -> setSelectionState(3, week_state[3] = !week_state[3]));
|
||||
binding.thu.setOnClickListener(v -> setSelectionState(4, week_state[4] = !week_state[4]));
|
||||
binding.fri.setOnClickListener(v -> setSelectionState(5, week_state[5] = !week_state[5]));
|
||||
binding.sat.setOnClickListener(v -> setSelectionState(6, week_state[6] = !week_state[6]));
|
||||
|
||||
}
|
||||
|
||||
private void setSelectionState(int position, boolean selection) {
|
||||
if (selection) {
|
||||
// selection has to be made
|
||||
switch (position) {
|
||||
case 0:
|
||||
// sun
|
||||
binding.sun.setBackgroundTintList(AppCompatResources.getColorStateList(requireContext(), R.color.color_primary));
|
||||
binding.sun.setTextColor(AppCompatResources.getColorStateList(requireContext(), R.color.white_bg));
|
||||
break;
|
||||
case 1:
|
||||
// mon
|
||||
binding.mon.setBackgroundTintList(AppCompatResources.getColorStateList(requireContext(), R.color.color_primary));
|
||||
binding.mon.setTextColor(AppCompatResources.getColorStateList(requireContext(), R.color.white_bg));
|
||||
break;
|
||||
case 2:
|
||||
// tue
|
||||
binding.tue.setBackgroundTintList(AppCompatResources.getColorStateList(requireContext(), R.color.color_primary));
|
||||
binding.tue.setTextColor(AppCompatResources.getColorStateList(requireContext(), R.color.white_bg));
|
||||
break;
|
||||
case 3:
|
||||
// wed
|
||||
binding.wed.setBackgroundTintList(AppCompatResources.getColorStateList(requireContext(), R.color.color_primary));
|
||||
binding.wed.setTextColor(AppCompatResources.getColorStateList(requireContext(), R.color.white_bg));
|
||||
break;
|
||||
case 4:
|
||||
// thu
|
||||
binding.thu.setBackgroundTintList(AppCompatResources.getColorStateList(requireContext(), R.color.color_primary));
|
||||
binding.thu.setTextColor(AppCompatResources.getColorStateList(requireContext(), R.color.white_bg));
|
||||
break;
|
||||
case 5:
|
||||
// fri
|
||||
binding.fri.setBackgroundTintList(AppCompatResources.getColorStateList(requireContext(), R.color.color_primary));
|
||||
binding.fri.setTextColor(AppCompatResources.getColorStateList(requireContext(), R.color.white_bg));
|
||||
break;
|
||||
case 6:
|
||||
// sat
|
||||
binding.sat.setBackgroundTintList(AppCompatResources.getColorStateList(requireContext(), R.color.color_primary));
|
||||
binding.sat.setTextColor(AppCompatResources.getColorStateList(requireContext(), R.color.white_bg));
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// un-selection has to be made
|
||||
switch (position) {
|
||||
case 0:
|
||||
// sun
|
||||
binding.sun.setBackgroundTintList(null);
|
||||
binding.sun.setTextColor(AppCompatResources.getColorStateList(requireContext(), R.color.black));
|
||||
break;
|
||||
case 1:
|
||||
// mon
|
||||
binding.mon.setBackgroundTintList(null);
|
||||
binding.mon.setTextColor(AppCompatResources.getColorStateList(requireContext(), R.color.black));
|
||||
break;
|
||||
case 2:
|
||||
// tue
|
||||
binding.tue.setBackgroundTintList(null);
|
||||
binding.tue.setTextColor(AppCompatResources.getColorStateList(requireContext(), R.color.black));
|
||||
break;
|
||||
case 3:
|
||||
// wed
|
||||
binding.wed.setBackgroundTintList(null);
|
||||
binding.wed.setTextColor(AppCompatResources.getColorStateList(requireContext(), R.color.black));
|
||||
break;
|
||||
case 4:
|
||||
// thu
|
||||
binding.thu.setBackgroundTintList(null);
|
||||
binding.thu.setTextColor(AppCompatResources.getColorStateList(requireContext(), R.color.black));
|
||||
break;
|
||||
case 5:
|
||||
// fri
|
||||
binding.fri.setBackgroundTintList(null);
|
||||
binding.fri.setTextColor(AppCompatResources.getColorStateList(requireContext(), R.color.black));
|
||||
break;
|
||||
case 6:
|
||||
// sat
|
||||
binding.sat.setBackgroundTintList(null);
|
||||
binding.sat.setTextColor(AppCompatResources.getColorStateList(requireContext(), R.color.black));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// checking if all days are selected or not
|
||||
// thus, updating the Everyday switch accordingly
|
||||
boolean isEveryDay = true;
|
||||
|
||||
for (int i = 0; i < 7; i++) {
|
||||
if (!week_state[i]) {
|
||||
// some day is not selected thus not everyday selection
|
||||
isEveryDay = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
binding.everydayCheck.setOnCheckedChangeListener(null);
|
||||
binding.everydayCheck.setChecked(isEveryDay);
|
||||
binding.everydayCheck.setOnCheckedChangeListener(this);
|
||||
}
|
||||
|
||||
// shows date picker to pick date and set to tv
|
||||
private void getDate() {
|
||||
|
||||
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
|
||||
DatePickerDialog dpd = new DatePickerDialog(requireContext());
|
||||
|
||||
dpd.setOnDateSetListener((view, year, month, dayOfMonth) -> {
|
||||
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.set(Calendar.YEAR, year);
|
||||
cal.set(Calendar.MONTH, month);
|
||||
cal.set(Calendar.DAY_OF_MONTH, dayOfMonth);
|
||||
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("MM-dd-yyyy", Locale.getDefault());
|
||||
|
||||
String selected_time = sdf.format(cal.getTime());
|
||||
binding.getDate.setText(selected_time);
|
||||
|
||||
});
|
||||
|
||||
dpd.show();
|
||||
}
|
||||
|
||||
// TODO: 05-07-2023 for lower version
|
||||
|
||||
}
|
||||
|
||||
// shows time picker to pick time and set to textview
|
||||
private void getTime() {
|
||||
|
||||
Calendar calendar = Calendar.getInstance(Locale.getDefault());
|
||||
|
||||
TimePickerDialog tpd = new TimePickerDialog(requireContext(),
|
||||
(TimePickerDialog.OnTimeSetListener) (view, hourOfDay, minute) -> {
|
||||
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.set(Calendar.HOUR_OF_DAY, hourOfDay);
|
||||
cal.set(Calendar.MINUTE, minute);
|
||||
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("hh:mm a", Locale.getDefault());
|
||||
|
||||
String selected_time = sdf.format(cal.getTime());
|
||||
binding.getTime.setText(selected_time);
|
||||
|
||||
}, calendar.getTime().getHours(), calendar.getTime().getMinutes(), false);
|
||||
|
||||
tpd.show();
|
||||
|
||||
}
|
||||
|
||||
// loading freq. into its resp. spinner
|
||||
private void loadFrequency() {
|
||||
|
||||
// static data
|
||||
ArrayList<String> medTypeList = new ArrayList<>();
|
||||
medTypeList.add("1 time, Daily");
|
||||
medTypeList.add("2 time, Daily");
|
||||
medTypeList.add("3 time, Daily");
|
||||
|
||||
binding.frequencySpinner.setLifecycleOwner(this);
|
||||
|
||||
binding.frequencySpinner.setItems(medTypeList);
|
||||
|
||||
binding.frequencySpinner.setDismissWhenNotifiedItemSelected(true);
|
||||
|
||||
binding.frequencySpinner.setIsFocusable(true);
|
||||
|
||||
}
|
||||
|
||||
// loads med types into its resp. apinner
|
||||
private void loadMedType() {
|
||||
|
||||
// static data
|
||||
ArrayList<String> medTypeList = new ArrayList<>();
|
||||
medTypeList.add("Lorem ipsum");
|
||||
medTypeList.add("Lorem ipsum");
|
||||
medTypeList.add("Lorem ipsum");
|
||||
|
||||
binding.medicationsSpinner.setLifecycleOwner(this);
|
||||
|
||||
binding.medicationsSpinner.setItems(medTypeList);
|
||||
|
||||
binding.medicationsSpinner.setDismissWhenNotifiedItemSelected(true);
|
||||
|
||||
binding.medicationsSpinner.setIsFocusable(true);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.ssb.simplitend.medreminder;
|
||||
|
||||
import android.view.MotionEvent;
|
||||
|
||||
public interface OnActivityTouchListener {
|
||||
void getTouchCoordinates(MotionEvent ev);
|
||||
}
|
||||
@@ -0,0 +1,915 @@
|
||||
package com.ssb.simplitend.medreminder;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.app.Activity;
|
||||
import android.graphics.Rect;
|
||||
import android.os.Handler;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.Log;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.VelocityTracker;
|
||||
import android.view.View;
|
||||
import android.view.ViewConfiguration;
|
||||
import android.view.animation.DecelerateInterpolator;
|
||||
import android.widget.ListView;
|
||||
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class RecyclerTouchListener implements RecyclerView.OnItemTouchListener, OnActivityTouchListener {
|
||||
private static final String TAG = "RecyclerTouchListener";
|
||||
final Handler handler = new Handler();
|
||||
Activity act;
|
||||
List<Integer> unSwipeableRows;
|
||||
/*
|
||||
* independentViews are views on the foreground layer which when clicked, act "independent" from the foreground
|
||||
* ie, they are treated separately from the "row click" action
|
||||
*/
|
||||
List<Integer> independentViews;
|
||||
List<Integer> unClickableRows;
|
||||
List<Integer> optionViews;
|
||||
Set<Integer> ignoredViewTypes;
|
||||
// Cached ViewConfiguration and system-wide constant values
|
||||
private int touchSlop;
|
||||
private int minFlingVel;
|
||||
private int maxFlingVel;
|
||||
private long ANIMATION_STANDARD = 300;
|
||||
private long ANIMATION_CLOSE = 150;
|
||||
// Fixed properties
|
||||
private RecyclerView rView;
|
||||
// private SwipeListener mSwipeListener;
|
||||
private int bgWidth = 1, bgWidthLeft = 1; // 1 and not 0 to prevent dividing by zero
|
||||
// Transient properties
|
||||
// private List<PendingDismissData> mPendingDismisses = new ArrayList<>();
|
||||
private int mDismissAnimationRefCount = 0;
|
||||
private float touchedX;
|
||||
private float touchedY;
|
||||
private boolean isFgSwiping;
|
||||
private int mSwipingSlop;
|
||||
private VelocityTracker mVelocityTracker;
|
||||
private int touchedPosition;
|
||||
private View touchedView;
|
||||
private boolean mPaused;
|
||||
private boolean bgVisible, fgPartialViewClicked;
|
||||
private int bgVisiblePosition;
|
||||
private View bgVisibleView;
|
||||
private boolean isRViewScrolling;
|
||||
private int heightOutsideRView, screenHeight;
|
||||
private boolean mLongClickPerformed;
|
||||
// Foreground view (to be swiped), Background view (to show)
|
||||
private View fgView;
|
||||
private View bgView;
|
||||
//view ID
|
||||
private int fgViewID;
|
||||
private int bgViewID, bgViewIDLeft;
|
||||
private ArrayList<Integer> fadeViews;
|
||||
private OnRowClickListener mRowClickListener;
|
||||
private OnRowLongClickListener mRowLongClickListener;
|
||||
private OnSwipeOptionsClickListener mBgClickListener, mBgClickListenerLeft;
|
||||
// user choices
|
||||
private boolean clickable = false;
|
||||
private boolean longClickable = false;
|
||||
private boolean swipeable = false, swipeableLeftOptions = false;
|
||||
private int LONG_CLICK_DELAY = 800;
|
||||
private boolean longClickVibrate;
|
||||
Runnable mLongPressed = new Runnable() {
|
||||
public void run() {
|
||||
if (!longClickable)
|
||||
return;
|
||||
|
||||
mLongClickPerformed = true;
|
||||
|
||||
if (!bgVisible && touchedPosition >= 0 && !unClickableRows.contains(touchedPosition) && !isRViewScrolling) {
|
||||
if (longClickVibrate) {
|
||||
// Vibrator vibe = (Vibrator) act.getSystemService(Context.VIBRATOR_SERVICE);
|
||||
// vibe.vibrate(100); // do we really need to add vibrate service
|
||||
}
|
||||
mRowLongClickListener.onRowLongClicked(touchedPosition);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public RecyclerTouchListener(Activity a, RecyclerView recyclerView) {
|
||||
this.act = a;
|
||||
ViewConfiguration vc = ViewConfiguration.get(recyclerView.getContext());
|
||||
touchSlop = vc.getScaledTouchSlop();
|
||||
minFlingVel = vc.getScaledMinimumFlingVelocity() * 16;
|
||||
maxFlingVel = vc.getScaledMaximumFlingVelocity();
|
||||
rView = recyclerView;
|
||||
bgVisible = false;
|
||||
bgVisiblePosition = -1;
|
||||
bgVisibleView = null;
|
||||
fgPartialViewClicked = false;
|
||||
unSwipeableRows = new ArrayList<>();
|
||||
unClickableRows = new ArrayList<>();
|
||||
ignoredViewTypes = new HashSet<>();
|
||||
independentViews = new ArrayList<>();
|
||||
optionViews = new ArrayList<>();
|
||||
fadeViews = new ArrayList<>();
|
||||
isRViewScrolling = false;
|
||||
|
||||
// mSwipeListener = listener;
|
||||
|
||||
rView.addOnScrollListener(new RecyclerView.OnScrollListener() {
|
||||
@Override
|
||||
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
|
||||
/**
|
||||
* This will ensure that this RecyclerTouchListener is paused during recycler view scrolling.
|
||||
* If a scroll listener is already assigned, the caller should still pass scroll changes through
|
||||
* to this listener.
|
||||
*/
|
||||
setEnabled(newState != RecyclerView.SCROLL_STATE_DRAGGING);
|
||||
|
||||
/**
|
||||
* This is used so that clicking a row cannot be done while scrolling
|
||||
*/
|
||||
isRViewScrolling = newState != RecyclerView.SCROLL_STATE_IDLE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables or disables (pauses or resumes) watching for swipe-to-dismiss gestures.
|
||||
*
|
||||
* @param enabled Whether or not to watch for gestures.
|
||||
*/
|
||||
public void setEnabled(boolean enabled) {
|
||||
mPaused = !enabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent motionEvent) {
|
||||
return handleTouchEvent(motionEvent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTouchEvent(RecyclerView rv, MotionEvent motionEvent) {
|
||||
handleTouchEvent(motionEvent);
|
||||
}
|
||||
|
||||
/*////////////// Clickable ////////////////////*/
|
||||
|
||||
public RecyclerTouchListener setClickable(OnRowClickListener listener) {
|
||||
this.clickable = true;
|
||||
this.mRowClickListener = listener;
|
||||
return this;
|
||||
}
|
||||
|
||||
public RecyclerTouchListener setClickable(boolean clickable) {
|
||||
this.clickable = clickable;
|
||||
return this;
|
||||
}
|
||||
|
||||
public RecyclerTouchListener setLongClickable(boolean vibrate, OnRowLongClickListener listener) {
|
||||
this.longClickable = true;
|
||||
this.mRowLongClickListener = listener;
|
||||
this.longClickVibrate = vibrate;
|
||||
return this;
|
||||
}
|
||||
public RecyclerTouchListener setLongClickable(boolean longClickable) {
|
||||
this.longClickable = longClickable;
|
||||
return this;
|
||||
}
|
||||
|
||||
public RecyclerTouchListener setIndependentViews(Integer... viewIds) {
|
||||
this.independentViews = new ArrayList<>(Arrays.asList(viewIds));
|
||||
return this;
|
||||
}
|
||||
|
||||
public RecyclerTouchListener setUnClickableRows(Integer... rows) {
|
||||
this.unClickableRows = new ArrayList<>(Arrays.asList(rows));
|
||||
return this;
|
||||
}
|
||||
|
||||
public RecyclerTouchListener setIgnoredViewTypes(Integer... viewTypes) {
|
||||
ignoredViewTypes.clear();
|
||||
ignoredViewTypes.addAll(Arrays.asList(viewTypes));
|
||||
return this;
|
||||
}
|
||||
|
||||
//////////////// Swipeable ////////////////////
|
||||
|
||||
public RecyclerTouchListener setSwipeable(int foregroundID, int backgroundID, OnSwipeOptionsClickListener listener) {
|
||||
this.swipeable = true;
|
||||
if (fgViewID != 0 && foregroundID != fgViewID)
|
||||
throw new IllegalArgumentException("foregroundID does not match previously set ID");
|
||||
fgViewID = foregroundID;
|
||||
bgViewID = backgroundID;
|
||||
this.mBgClickListener = listener;
|
||||
|
||||
if (act instanceof RecyclerTouchListenerHelper)
|
||||
((RecyclerTouchListenerHelper) act).setOnActivityTouchListener(this);
|
||||
|
||||
DisplayMetrics displaymetrics = new DisplayMetrics();
|
||||
act.getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
|
||||
screenHeight = displaymetrics.heightPixels;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public RecyclerTouchListener setSwipeable(boolean value) {
|
||||
this.swipeable = value;
|
||||
if (!value)
|
||||
invalidateSwipeOptions();
|
||||
return this;
|
||||
}
|
||||
|
||||
public RecyclerTouchListener setSwipeOptionViews(Integer... viewIds) {
|
||||
this.optionViews = new ArrayList<>(Arrays.asList(viewIds));
|
||||
return this;
|
||||
}
|
||||
|
||||
public RecyclerTouchListener setUnSwipeableRows(Integer... rows) {
|
||||
this.unSwipeableRows = new ArrayList<>(Arrays.asList(rows));
|
||||
return this;
|
||||
}
|
||||
|
||||
//////////////// Fade Views ////////////////////
|
||||
|
||||
// Set views which are faded out as fg is opened
|
||||
public RecyclerTouchListener setViewsToFade(Integer... viewIds) {
|
||||
this.fadeViews = new ArrayList<>(Arrays.asList(viewIds));
|
||||
return this;
|
||||
}
|
||||
|
||||
// the entire foreground is faded out as it is opened
|
||||
public RecyclerTouchListener setFgFade() {
|
||||
if (!fadeViews.contains(fgViewID))
|
||||
this.fadeViews.add(fgViewID);
|
||||
return this;
|
||||
}
|
||||
|
||||
//-------------- Checkers for preventing ---------------//
|
||||
|
||||
private boolean isIndependentViewClicked(MotionEvent motionEvent) {
|
||||
for (int i = 0; i < independentViews.size(); i++) {
|
||||
if (touchedView != null) {
|
||||
Rect rect = new Rect();
|
||||
int x = (int) motionEvent.getRawX();
|
||||
int y = (int) motionEvent.getRawY();
|
||||
touchedView.findViewById(independentViews.get(i)).getGlobalVisibleRect(rect);
|
||||
if (rect.contains(x, y)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private int getOptionViewID(MotionEvent motionEvent) {
|
||||
for (int i = 0; i < optionViews.size(); i++) {
|
||||
if (touchedView != null) {
|
||||
Rect rect = new Rect();
|
||||
int x = (int) motionEvent.getRawX();
|
||||
int y = (int) motionEvent.getRawY();
|
||||
touchedView.findViewById(optionViews.get(i)).getGlobalVisibleRect(rect);
|
||||
if (rect.contains(x, y)) {
|
||||
return optionViews.get(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
private int getIndependentViewID(MotionEvent motionEvent) {
|
||||
for (int i = 0; i < independentViews.size(); i++) {
|
||||
if (touchedView != null) {
|
||||
Rect rect = new Rect();
|
||||
int x = (int) motionEvent.getRawX();
|
||||
int y = (int) motionEvent.getRawY();
|
||||
touchedView.findViewById(independentViews.get(i)).getGlobalVisibleRect(rect);
|
||||
if (rect.contains(x, y)) {
|
||||
return independentViews.get(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
|
||||
|
||||
}
|
||||
|
||||
public void invalidateSwipeOptions() {
|
||||
bgWidth = 1;
|
||||
}
|
||||
|
||||
public void openSwipeOptions(int position) {
|
||||
if (!swipeable || rView.getChildAt(position) == null
|
||||
|| unSwipeableRows.contains(position) || shouldIgnoreAction(position))
|
||||
return;
|
||||
if (bgWidth < 2) {
|
||||
if (act.findViewById(bgViewID) != null)
|
||||
bgWidth = act.findViewById(bgViewID).getWidth();
|
||||
heightOutsideRView = screenHeight - rView.getHeight();
|
||||
}
|
||||
touchedPosition = position;
|
||||
touchedView = rView.getChildAt(position);
|
||||
fgView = touchedView.findViewById(fgViewID);
|
||||
bgView = touchedView.findViewById(bgViewID);
|
||||
bgView.setMinimumHeight(fgView.getHeight());
|
||||
|
||||
closeVisibleBG(null);
|
||||
animateFG(touchedView, Animation.OPEN, ANIMATION_STANDARD);
|
||||
bgVisible = true;
|
||||
bgVisibleView = fgView;
|
||||
bgVisiblePosition = touchedPosition;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void closeVisibleBG() {
|
||||
if (bgVisibleView == null) {
|
||||
Log.e(TAG, "No rows found for which background options are visible");
|
||||
return;
|
||||
}
|
||||
bgVisibleView.animate()
|
||||
.translationX(0)
|
||||
.setDuration(ANIMATION_CLOSE)
|
||||
.setListener(null);
|
||||
|
||||
animateFadeViews(bgVisibleView, 1f, ANIMATION_CLOSE);
|
||||
bgVisible = false;
|
||||
bgVisibleView = null;
|
||||
bgVisiblePosition = -1;
|
||||
}
|
||||
|
||||
public void closeVisibleBG(final OnSwipeListener mSwipeCloseListener) {
|
||||
if (bgVisibleView == null) {
|
||||
Log.e(TAG, "No rows found for which background options are visible");
|
||||
return;
|
||||
}
|
||||
final ObjectAnimator translateAnimator = ObjectAnimator.ofFloat(bgVisibleView,
|
||||
View.TRANSLATION_X, 0f);
|
||||
translateAnimator.setDuration(ANIMATION_CLOSE);
|
||||
translateAnimator.addListener(new Animator.AnimatorListener() {
|
||||
@Override
|
||||
public void onAnimationStart(Animator animation) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
if (mSwipeCloseListener != null)
|
||||
mSwipeCloseListener.onSwipeOptionsClosed();
|
||||
translateAnimator.removeAllListeners();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationCancel(Animator animation) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationRepeat(Animator animation) {
|
||||
}
|
||||
});
|
||||
translateAnimator.start();
|
||||
|
||||
animateFadeViews(bgVisibleView, 1f, ANIMATION_CLOSE);
|
||||
bgVisible = false;
|
||||
bgVisibleView = null;
|
||||
bgVisiblePosition = -1;
|
||||
}
|
||||
|
||||
private void animateFadeViews(View downView, float alpha, long duration) {
|
||||
if (fadeViews != null) {
|
||||
for (final int viewID : fadeViews) {
|
||||
downView.findViewById(viewID).animate()
|
||||
.alpha(alpha)
|
||||
.setDuration(duration);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void animateFG(View downView, Animation animateType, long duration) {
|
||||
if (animateType == Animation.OPEN) {
|
||||
ObjectAnimator translateAnimator = ObjectAnimator.ofFloat(
|
||||
fgView, View.TRANSLATION_X, -bgWidth);
|
||||
translateAnimator.setDuration(duration);
|
||||
translateAnimator.setInterpolator(new DecelerateInterpolator(1.5f));
|
||||
translateAnimator.start();
|
||||
animateFadeViews(downView, 0f, duration);
|
||||
} else if (animateType == Animation.CLOSE) {
|
||||
ObjectAnimator translateAnimator = ObjectAnimator.ofFloat(
|
||||
fgView, View.TRANSLATION_X, 0f);
|
||||
translateAnimator.setDuration(duration);
|
||||
translateAnimator.setInterpolator(new DecelerateInterpolator(1.5f));
|
||||
translateAnimator.start();
|
||||
animateFadeViews(downView, 1f, duration);
|
||||
}
|
||||
}
|
||||
|
||||
private void animateFG(View downView, final Animation animateType, long duration,
|
||||
final OnSwipeListener mSwipeCloseListener) {
|
||||
final ObjectAnimator translateAnimator;
|
||||
if (animateType == Animation.OPEN) {
|
||||
translateAnimator = ObjectAnimator.ofFloat(fgView, View.TRANSLATION_X, -bgWidth);
|
||||
translateAnimator.setDuration(duration);
|
||||
translateAnimator.setInterpolator(new DecelerateInterpolator(1.5f));
|
||||
translateAnimator.start();
|
||||
animateFadeViews(downView, 0f, duration);
|
||||
} else /*if (animateType == Animation.CLOSE)*/ {
|
||||
translateAnimator = ObjectAnimator.ofFloat(fgView, View.TRANSLATION_X, 0f);
|
||||
translateAnimator.setDuration(duration);
|
||||
translateAnimator.setInterpolator(new DecelerateInterpolator(1.5f));
|
||||
translateAnimator.start();
|
||||
animateFadeViews(downView, 1f, duration);
|
||||
}
|
||||
|
||||
translateAnimator.addListener(new Animator.AnimatorListener() {
|
||||
@Override
|
||||
public void onAnimationStart(Animator animation) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
if (mSwipeCloseListener != null) {
|
||||
if (animateType == Animation.OPEN)
|
||||
mSwipeCloseListener.onSwipeOptionsOpened();
|
||||
else if (animateType == Animation.CLOSE)
|
||||
mSwipeCloseListener.onSwipeOptionsClosed();
|
||||
}
|
||||
translateAnimator.removeAllListeners();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationCancel(Animator animation) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationRepeat(Animator animation) {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private boolean handleTouchEvent(MotionEvent motionEvent) {
|
||||
if (swipeable && bgWidth < 2) {
|
||||
// bgWidth = rView.getWidth();
|
||||
if (act.findViewById(bgViewID) != null)
|
||||
bgWidth = act.findViewById(bgViewID).getWidth();
|
||||
|
||||
heightOutsideRView = screenHeight - rView.getHeight();
|
||||
}
|
||||
|
||||
switch (motionEvent.getActionMasked()) {
|
||||
|
||||
// When finger touches screen
|
||||
case MotionEvent.ACTION_DOWN: {
|
||||
if (mPaused) {
|
||||
break;
|
||||
}
|
||||
|
||||
// Find the child view that was touched (perform a hit test)
|
||||
Rect rect = new Rect();
|
||||
int childCount = rView.getChildCount();
|
||||
int[] listViewCoords = new int[2];
|
||||
rView.getLocationOnScreen(listViewCoords);
|
||||
// x and y values respective to the recycler view
|
||||
int x = (int) motionEvent.getRawX() - listViewCoords[0];
|
||||
int y = (int) motionEvent.getRawY() - listViewCoords[1];
|
||||
View child;
|
||||
|
||||
/*
|
||||
* check for every child (row) in the recycler view whether the touched co-ordinates belong to that
|
||||
* respective child and if it does, register that child as the touched view (touchedView)
|
||||
*/
|
||||
for (int i = 0; i < childCount; i++) {
|
||||
child = rView.getChildAt(i);
|
||||
child.getHitRect(rect);
|
||||
if (rect.contains(x, y)) {
|
||||
touchedView = child;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (touchedView != null) {
|
||||
touchedX = motionEvent.getRawX();
|
||||
touchedY = motionEvent.getRawY();
|
||||
touchedPosition = rView.getChildAdapterPosition(touchedView);
|
||||
|
||||
if (shouldIgnoreAction(touchedPosition)) {
|
||||
touchedPosition = ListView.INVALID_POSITION;
|
||||
return false; // <-- guard here allows for ignoring events, allowing more than one view type and preventing NPE
|
||||
}
|
||||
|
||||
if (longClickable) {
|
||||
mLongClickPerformed = false;
|
||||
handler.postDelayed(mLongPressed, LONG_CLICK_DELAY);
|
||||
}
|
||||
if (swipeable) {
|
||||
mVelocityTracker = VelocityTracker.obtain();
|
||||
mVelocityTracker.addMovement(motionEvent);
|
||||
fgView = touchedView.findViewById(fgViewID);
|
||||
bgView = touchedView.findViewById(bgViewID);
|
||||
// bgView.getLayoutParams().height = fgView.getHeight();
|
||||
bgView.setMinimumHeight(fgView.getHeight());
|
||||
|
||||
/*
|
||||
* bgVisible is true when the options menu is opened
|
||||
* This block is to register fgPartialViewClicked status - Partial view is the view that is still
|
||||
* shown on the screen if the options width is < device width
|
||||
*/
|
||||
if (bgVisible && fgView != null) {
|
||||
handler.removeCallbacks(mLongPressed);
|
||||
x = (int) motionEvent.getRawX();
|
||||
y = (int) motionEvent.getRawY();
|
||||
fgView.getGlobalVisibleRect(rect);
|
||||
fgPartialViewClicked = rect.contains(x, y);
|
||||
} else {
|
||||
fgPartialViewClicked = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If options menu is shown and the touched position is not the same as the row for which the
|
||||
* options is displayed - close the options menu for the row which is displaying it
|
||||
* (bgVisibleView and bgVisiblePosition is used for this purpose which registers which view and
|
||||
* which position has it's options menu opened)
|
||||
*/
|
||||
x = (int) motionEvent.getRawX();
|
||||
y = (int) motionEvent.getRawY();
|
||||
rView.getHitRect(rect);
|
||||
if (swipeable && bgVisible && touchedPosition != bgVisiblePosition) {
|
||||
handler.removeCallbacks(mLongPressed);
|
||||
closeVisibleBG(null);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case MotionEvent.ACTION_CANCEL: {
|
||||
handler.removeCallbacks(mLongPressed);
|
||||
if (mLongClickPerformed)
|
||||
break;
|
||||
|
||||
if (mVelocityTracker == null) {
|
||||
break;
|
||||
}
|
||||
if (swipeable) {
|
||||
if (touchedView != null && isFgSwiping) {
|
||||
// cancel
|
||||
animateFG(touchedView, Animation.CLOSE, ANIMATION_STANDARD);
|
||||
}
|
||||
mVelocityTracker.recycle();
|
||||
mVelocityTracker = null;
|
||||
isFgSwiping = false;
|
||||
bgView = null;
|
||||
}
|
||||
touchedX = 0;
|
||||
touchedY = 0;
|
||||
touchedView = null;
|
||||
touchedPosition = ListView.INVALID_POSITION;
|
||||
break;
|
||||
}
|
||||
|
||||
// When finger is lifted off the screen (after clicking, flinging, swiping, etc..)
|
||||
case MotionEvent.ACTION_UP: {
|
||||
handler.removeCallbacks(mLongPressed);
|
||||
if (mLongClickPerformed)
|
||||
break;
|
||||
|
||||
if (mVelocityTracker == null && swipeable) {
|
||||
break;
|
||||
}
|
||||
if (touchedPosition < 0)
|
||||
break;
|
||||
|
||||
// swipedLeft and swipedRight are true if the user swipes in the respective direction (no conditions)
|
||||
boolean swipedLeft = false;
|
||||
boolean swipedRight = false;
|
||||
/*
|
||||
* swipedLeftProper and swipedRightProper are true if user swipes in the respective direction
|
||||
* and if certain conditions are satisfied (given some few lines below)
|
||||
*/
|
||||
boolean swipedLeftProper = false;
|
||||
boolean swipedRightProper = false;
|
||||
|
||||
float mFinalDelta = motionEvent.getRawX() - touchedX;
|
||||
|
||||
// if swiped in a direction, make that respective variable true
|
||||
if (isFgSwiping) {
|
||||
swipedLeft = mFinalDelta < 0;
|
||||
swipedRight = mFinalDelta > 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the user has swiped more than half of the width of the options menu, or if the
|
||||
* velocity of swiping is between min and max fling values
|
||||
* "proper" variable are set true
|
||||
*/
|
||||
if (Math.abs(mFinalDelta) > bgWidth / 2 && isFgSwiping) {
|
||||
swipedLeftProper = mFinalDelta < 0;
|
||||
swipedRightProper = mFinalDelta > 0;
|
||||
} else if (swipeable) {
|
||||
mVelocityTracker.addMovement(motionEvent);
|
||||
mVelocityTracker.computeCurrentVelocity(1000);
|
||||
float velocityX = mVelocityTracker.getXVelocity();
|
||||
float absVelocityX = Math.abs(velocityX);
|
||||
float absVelocityY = Math.abs(mVelocityTracker.getYVelocity());
|
||||
if (minFlingVel <= absVelocityX && absVelocityX <= maxFlingVel
|
||||
&& absVelocityY < absVelocityX && isFgSwiping) {
|
||||
// dismiss only if flinging in the same direction as dragging
|
||||
swipedLeftProper = (velocityX < 0) == (mFinalDelta < 0);
|
||||
swipedRightProper = (velocityX > 0) == (mFinalDelta > 0);
|
||||
}
|
||||
}
|
||||
|
||||
///////// Manipulation of view based on the 4 variables mentioned above ///////////
|
||||
|
||||
// if swiped left properly and options menu isn't already visible, animate the foreground to the left
|
||||
if (swipeable && !swipedRight && swipedLeftProper && touchedPosition != RecyclerView.NO_POSITION
|
||||
&& !unSwipeableRows.contains(touchedPosition) && !bgVisible) {
|
||||
|
||||
final View downView = touchedView; // touchedView gets null'd before animation ends
|
||||
final int downPosition = touchedPosition;
|
||||
++mDismissAnimationRefCount;
|
||||
//TODO - speed
|
||||
animateFG(touchedView, Animation.OPEN, ANIMATION_STANDARD);
|
||||
bgVisible = true;
|
||||
bgVisibleView = fgView;
|
||||
bgVisiblePosition = downPosition;
|
||||
}
|
||||
// else if swiped right properly when options menu is visible, close the menu and bring the foreground
|
||||
// to it's original position
|
||||
else if (swipeable && !swipedLeft && swipedRightProper && touchedPosition != RecyclerView.NO_POSITION
|
||||
&& !unSwipeableRows.contains(touchedPosition) && bgVisible) {
|
||||
// dismiss
|
||||
final View downView = touchedView; // touchedView gets null'd before animation ends
|
||||
final int downPosition = touchedPosition;
|
||||
|
||||
++mDismissAnimationRefCount;
|
||||
//TODO - speed
|
||||
animateFG(touchedView, Animation.CLOSE, ANIMATION_STANDARD);
|
||||
bgVisible = false;
|
||||
bgVisibleView = null;
|
||||
bgVisiblePosition = -1;
|
||||
}
|
||||
// else if swiped left incorrectly (not satisfying the above conditions), animate the foreground back to
|
||||
// it's original position (spring effect)
|
||||
else if (swipeable && swipedLeft && !bgVisible) {
|
||||
// cancel
|
||||
final View tempBgView = bgView;
|
||||
animateFG(touchedView, Animation.CLOSE, ANIMATION_STANDARD, new OnSwipeListener() {
|
||||
@Override
|
||||
public void onSwipeOptionsClosed() {
|
||||
if (tempBgView != null)
|
||||
tempBgView.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSwipeOptionsOpened() {
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
bgVisible = false;
|
||||
bgVisibleView = null;
|
||||
bgVisiblePosition = -1;
|
||||
}
|
||||
// else if swiped right incorrectly (not satisfying the above conditions), animate the foreground to
|
||||
// it's open position (spring effect)
|
||||
else if (swipeable && swipedRight && bgVisible) {
|
||||
// cancel
|
||||
animateFG(touchedView, Animation.OPEN, ANIMATION_STANDARD);
|
||||
bgVisible = true;
|
||||
bgVisibleView = fgView;
|
||||
bgVisiblePosition = touchedPosition;
|
||||
}
|
||||
// This case deals with an error where the user can swipe left, then right
|
||||
// really fast and the fg is stuck open - so in that case we close the fg
|
||||
else if (swipeable && swipedRight && !bgVisible) {
|
||||
// cancel
|
||||
animateFG(touchedView, Animation.CLOSE, ANIMATION_STANDARD);
|
||||
bgVisible = false;
|
||||
bgVisibleView = null;
|
||||
bgVisiblePosition = -1;
|
||||
}
|
||||
// This case deals with an error where the user can swipe right, then left
|
||||
// really fast and the fg is stuck open - so in that case we open the fg
|
||||
else if (swipeable && swipedLeft && bgVisible) {
|
||||
// cancel
|
||||
animateFG(touchedView, Animation.OPEN, ANIMATION_STANDARD);
|
||||
bgVisible = true;
|
||||
bgVisibleView = fgView;
|
||||
bgVisiblePosition = touchedPosition;
|
||||
}
|
||||
|
||||
// if clicked
|
||||
else if (!swipedRight && !swipedLeft) {
|
||||
// if partial foreground view is clicked (see ACTION_DOWN) bring foreground back to original position
|
||||
// bgVisible is true automatically since it's already checked in ACTION_DOWN block
|
||||
if (swipeable && fgPartialViewClicked) {
|
||||
animateFG(touchedView, Animation.CLOSE, ANIMATION_STANDARD);
|
||||
bgVisible = false;
|
||||
bgVisibleView = null;
|
||||
bgVisiblePosition = -1;
|
||||
}
|
||||
// On Click listener for rows
|
||||
else if (clickable && !bgVisible && touchedPosition >= 0 && !unClickableRows.contains(touchedPosition)
|
||||
&& isIndependentViewClicked(motionEvent) && !isRViewScrolling) {
|
||||
mRowClickListener.onRowClicked(touchedPosition);
|
||||
}
|
||||
// On Click listener for independent views inside the rows
|
||||
else if (clickable && !bgVisible && touchedPosition >= 0 && !unClickableRows.contains(touchedPosition)
|
||||
&& !isIndependentViewClicked(motionEvent) && !isRViewScrolling) {
|
||||
final int independentViewID = getIndependentViewID(motionEvent);
|
||||
if (independentViewID >= 0)
|
||||
mRowClickListener.onIndependentViewClicked(independentViewID, touchedPosition);
|
||||
}
|
||||
// On Click listener for background options
|
||||
else if (swipeable && bgVisible && !fgPartialViewClicked) {
|
||||
final int optionID = getOptionViewID(motionEvent);
|
||||
if (optionID >= 0 && touchedPosition >= 0) {
|
||||
final int downPosition = touchedPosition;
|
||||
closeVisibleBG(new OnSwipeListener() {
|
||||
@Override
|
||||
public void onSwipeOptionsClosed() {
|
||||
mBgClickListener.onSwipeOptionClicked(optionID, downPosition);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSwipeOptionsOpened() {
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// if clicked and not swiped
|
||||
|
||||
if (swipeable) {
|
||||
mVelocityTracker.recycle();
|
||||
mVelocityTracker = null;
|
||||
}
|
||||
touchedX = 0;
|
||||
touchedY = 0;
|
||||
touchedView = null;
|
||||
touchedPosition = ListView.INVALID_POSITION;
|
||||
isFgSwiping = false;
|
||||
bgView = null;
|
||||
break;
|
||||
|
||||
// when finger is moving across the screen (and not yet lifted)
|
||||
case MotionEvent.ACTION_MOVE: {
|
||||
if (mLongClickPerformed)
|
||||
break;
|
||||
if (mVelocityTracker == null || mPaused || !swipeable) {
|
||||
break;
|
||||
}
|
||||
|
||||
mVelocityTracker.addMovement(motionEvent);
|
||||
float deltaX = motionEvent.getRawX() - touchedX;
|
||||
float deltaY = motionEvent.getRawY() - touchedY;
|
||||
|
||||
/*
|
||||
* isFgSwiping variable which is set to true here is used to alter the swipedLeft, swipedRightProper
|
||||
* variables in "ACTION_UP" block by checking if user is actually swiping at present or not
|
||||
*/
|
||||
if (!isFgSwiping && Math.abs(deltaX) > touchSlop && Math.abs(deltaY) < Math.abs(deltaX) / 2) {
|
||||
handler.removeCallbacks(mLongPressed);
|
||||
isFgSwiping = true;
|
||||
mSwipingSlop = (deltaX > 0 ? touchSlop : -touchSlop);
|
||||
}
|
||||
|
||||
// This block moves the foreground along with the finger when swiping
|
||||
if (swipeable && isFgSwiping && !unSwipeableRows.contains(touchedPosition)) {
|
||||
if (bgView == null) {
|
||||
bgView = touchedView.findViewById(bgViewID);
|
||||
bgView.setVisibility(View.VISIBLE);
|
||||
}
|
||||
// if fg is being swiped left
|
||||
if (deltaX < touchSlop && !bgVisible) {
|
||||
float translateAmount = deltaX - mSwipingSlop;
|
||||
// if ((Math.abs(translateAmount) > bgWidth ? -bgWidth : translateAmount) <= 0) {
|
||||
// swipe fg till width of bg. If swiped further, nothing happens (stalls at width of bg)
|
||||
fgView.setTranslationX(Math.abs(translateAmount) > bgWidth ? -bgWidth : translateAmount);
|
||||
if (fgView.getTranslationX() > 0) fgView.setTranslationX(0);
|
||||
// }
|
||||
|
||||
// fades all the fadeViews gradually to 0 alpha as dragged
|
||||
if (fadeViews != null) {
|
||||
for (int viewID : fadeViews) {
|
||||
touchedView.findViewById(viewID).setAlpha(1 - (Math.abs(translateAmount) / bgWidth));
|
||||
}
|
||||
}
|
||||
}
|
||||
// if fg is being swiped right
|
||||
else if (deltaX > 0 && bgVisible) {
|
||||
// for closing rightOptions
|
||||
if (bgVisible) {
|
||||
float translateAmount = (deltaX - mSwipingSlop) - bgWidth;
|
||||
|
||||
// swipe fg till it reaches original position. If swiped further, nothing happens (stalls at 0)
|
||||
fgView.setTranslationX(translateAmount > 0 ? 0 : translateAmount);
|
||||
|
||||
// fades all the fadeViews gradually to 0 alpha as dragged
|
||||
if (fadeViews != null) {
|
||||
for (int viewID : fadeViews) {
|
||||
touchedView.findViewById(viewID).setAlpha(1 - (Math.abs(translateAmount) / bgWidth));
|
||||
}
|
||||
}
|
||||
}
|
||||
// for opening leftOptions
|
||||
else {
|
||||
float translateAmount = (deltaX - mSwipingSlop) - bgWidth;
|
||||
|
||||
// swipe fg till it reaches original position. If swiped further, nothing happens (stalls at 0)
|
||||
fgView.setTranslationX(translateAmount > 0 ? 0 : translateAmount);
|
||||
|
||||
// fades all the fadeViews gradually to 0 alpha as dragged
|
||||
if (fadeViews != null) {
|
||||
for (int viewID : fadeViews) {
|
||||
touchedView.findViewById(viewID).setAlpha(1 - (Math.abs(translateAmount) / bgWidth));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
// moves the fg slightly to give the illusion of an "unswipeable" row
|
||||
else if (swipeable && isFgSwiping && unSwipeableRows.contains(touchedPosition)) {
|
||||
if (deltaX < touchSlop && !bgVisible) {
|
||||
float translateAmount = deltaX - mSwipingSlop;
|
||||
if (bgView == null)
|
||||
bgView = touchedView.findViewById(bgViewID);
|
||||
|
||||
if (bgView != null)
|
||||
bgView.setVisibility(View.GONE);
|
||||
|
||||
// swipe fg till width of bg. If swiped further, nothing happens (stalls at width of bg)
|
||||
fgView.setTranslationX(translateAmount / 5);
|
||||
if (fgView.getTranslationX() > 0) fgView.setTranslationX(0);
|
||||
|
||||
// fades all the fadeViews gradually to 0 alpha as dragged
|
||||
// if (fadeViews != null) {
|
||||
// for (int viewID : fadeViews) {
|
||||
// touchedView.findViewById(viewID).setAlpha(1 - (Math.abs(translateAmount) / bgWidth));
|
||||
// }
|
||||
// }
|
||||
}
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets coordinates from Activity and closes any
|
||||
* swiped rows if touch happens outside the recycler view
|
||||
*/
|
||||
@Override
|
||||
public void getTouchCoordinates(MotionEvent ev) {
|
||||
int y = (int) ev.getRawY();
|
||||
if (swipeable && bgVisible && ev.getActionMasked() == MotionEvent.ACTION_DOWN
|
||||
&& y < heightOutsideRView) closeVisibleBG(null);
|
||||
}
|
||||
|
||||
private boolean shouldIgnoreAction(int touchedPosition) {
|
||||
return rView == null || ignoredViewTypes.contains(rView.getAdapter().getItemViewType(touchedPosition));
|
||||
}
|
||||
|
||||
private enum Animation {
|
||||
OPEN, CLOSE
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////// Interfaces /////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public interface OnRowClickListener {
|
||||
void onRowClicked(int position);
|
||||
|
||||
void onIndependentViewClicked(int independentViewID, int position);
|
||||
}
|
||||
|
||||
public interface OnRowLongClickListener {
|
||||
void onRowLongClicked(int position);
|
||||
}
|
||||
|
||||
public interface OnSwipeOptionsClickListener {
|
||||
void onSwipeOptionClicked(int viewID, int position);
|
||||
}
|
||||
|
||||
public interface RecyclerTouchListenerHelper {
|
||||
void setOnActivityTouchListener(OnActivityTouchListener listener);
|
||||
}
|
||||
|
||||
public interface OnSwipeListener {
|
||||
void onSwipeOptionsClosed();
|
||||
|
||||
void onSwipeOptionsOpened();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,277 @@
|
||||
package com.ssb.simplitend.medreminder;
|
||||
|
||||
import static com.ssb.simplitend.medreminder.AddReminderFragment.REMINDER_KEY;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
import androidx.navigation.Navigation;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
|
||||
import com.ssb.simplitend.R;
|
||||
import com.ssb.simplitend.apputils.AppUtil;
|
||||
import com.ssb.simplitend.apputils.ProfileProgress;
|
||||
import com.ssb.simplitend.databinding.RemindersFragmentBinding;
|
||||
import com.ssb.simplitend.medreminder.mvvm.Reminder;
|
||||
import com.ssb.simplitend.medreminder.mvvm.ReminderViewModel;
|
||||
|
||||
public class ReminderFragment extends Fragment implements RecyclerTouchListener.OnSwipeOptionsClickListener {
|
||||
|
||||
// view binding
|
||||
protected RemindersFragmentBinding binding;
|
||||
|
||||
// reminders viewmodel
|
||||
protected ReminderViewModel reminderViewModel;
|
||||
|
||||
// recycler touch listener for swipe menu
|
||||
protected RecyclerTouchListener recyclerTouchListener;
|
||||
|
||||
// selection state for week days
|
||||
/*
|
||||
true -> date selected
|
||||
false -> date unselected
|
||||
*/
|
||||
private boolean[] selection_state;
|
||||
private static final String SELECTION_STATE_KEY = "selection_state";
|
||||
|
||||
public ReminderFragment(){
|
||||
// required empty const.
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
binding = RemindersFragmentBinding.inflate(inflater, container, false);
|
||||
|
||||
initViews(savedInstanceState);
|
||||
|
||||
clickEvents();
|
||||
|
||||
return binding.getRoot();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSaveInstanceState(@NonNull Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
outState.putBooleanArray(SELECTION_STATE_KEY, selection_state);
|
||||
}
|
||||
|
||||
private void clickEvents() {
|
||||
// date selections
|
||||
binding.sun.setOnClickListener(v -> {
|
||||
setSelectionState(0, selection_state[0] = !selection_state[0]);
|
||||
loadReminderList();
|
||||
});
|
||||
binding.mon.setOnClickListener(v -> {
|
||||
setSelectionState(1, selection_state[1] = !selection_state[1]);
|
||||
loadReminderList();
|
||||
});
|
||||
binding.tue.setOnClickListener(v -> {
|
||||
setSelectionState(2, selection_state[2] = !selection_state[2]);
|
||||
loadReminderList();
|
||||
});
|
||||
binding.wed.setOnClickListener(v -> {
|
||||
setSelectionState(3, selection_state[3] = !selection_state[3]);
|
||||
loadReminderList();
|
||||
});
|
||||
binding.thu.setOnClickListener(v -> {
|
||||
setSelectionState(4, selection_state[4] = !selection_state[4]);
|
||||
loadReminderList();
|
||||
});
|
||||
binding.fri.setOnClickListener(v -> {
|
||||
setSelectionState(5, selection_state[5] = !selection_state[5]);
|
||||
loadReminderList();
|
||||
});
|
||||
binding.sat.setOnClickListener(v -> {
|
||||
setSelectionState(6, selection_state[6] = !selection_state[6]);
|
||||
loadReminderList();
|
||||
});
|
||||
|
||||
// add button
|
||||
binding.addReminder.setOnClickListener(v ->
|
||||
Navigation.findNavController(v).navigate(R.id.action_reminderFragment_to_addReminderFragment)
|
||||
);
|
||||
|
||||
binding.done.setOnClickListener(v -> {
|
||||
Navigation.findNavController(v).popBackStack();
|
||||
ProfileProgress.PROFILE_PROGRESS[0] = true;
|
||||
});
|
||||
|
||||
binding.backBtn.setOnClickListener(v -> Navigation.findNavController(v).popBackStack());
|
||||
|
||||
binding.editBtn.setOnClickListener(v -> {
|
||||
Bundle bundle = new Bundle();
|
||||
Reminder reminder = new Reminder("Vitamin D3", "05:00 PM", "5 Capsules");
|
||||
|
||||
bundle.putSerializable(REMINDER_KEY, reminder);
|
||||
|
||||
Navigation.findNavController(binding.getRoot())
|
||||
.navigate(R.id.action_reminderFragment_to_addReminderFragment, bundle);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private void loadReminderList(){
|
||||
binding.noData.setVisibility(View.GONE);
|
||||
binding.remindersRv.setVisibility(View.VISIBLE);
|
||||
reminderViewModel.getReminderAdapter().submitList(reminderViewModel.getRemindersList());
|
||||
|
||||
// static
|
||||
binding.done.setVisibility(View.VISIBLE);
|
||||
|
||||
}
|
||||
|
||||
private void initViews(Bundle savedInstanceState) {
|
||||
|
||||
if (savedInstanceState != null){
|
||||
selection_state = savedInstanceState.getBooleanArray(SELECTION_STATE_KEY);
|
||||
|
||||
for (int i = 0; i < selection_state.length; i++) {
|
||||
setSelectionState(i, selection_state[i]);
|
||||
}
|
||||
|
||||
}else{
|
||||
selection_state = new boolean[7];
|
||||
}
|
||||
|
||||
reminderViewModel = new ViewModelProvider(this).get(ReminderViewModel.class);
|
||||
|
||||
binding.remindersRv.setLayoutManager(new LinearLayoutManager(requireContext()));
|
||||
binding.remindersRv.setAdapter(reminderViewModel.getReminderAdapter());
|
||||
|
||||
recyclerTouchListener = new RecyclerTouchListener(requireActivity(), binding.remindersRv);
|
||||
|
||||
recyclerTouchListener.setSwipeOptionViews(R.id.reminder_edit, R.id.reminder_delete)
|
||||
.setSwipeable(R.id.rowFG, R.id.rowBG, this);
|
||||
|
||||
binding.remindersRv.addOnItemTouchListener(recyclerTouchListener);
|
||||
|
||||
}
|
||||
|
||||
private void setSelectionState(int position, boolean selection){
|
||||
if (selection){
|
||||
switch (position){
|
||||
case 0:
|
||||
// sun
|
||||
binding.sun.setBackgroundResource(R.drawable.seleted_item_primary);
|
||||
binding.sunT1.setTextColor(getResources().getColor(R.color.white_bg));
|
||||
binding.sunT2.setTextColor(getResources().getColor(R.color.white_bg));
|
||||
break;
|
||||
case 1:
|
||||
// mon
|
||||
binding.mon.setBackgroundResource(R.drawable.seleted_item_primary);
|
||||
binding.monT1.setTextColor(getResources().getColor(R.color.white_bg));
|
||||
binding.monT2.setTextColor(getResources().getColor(R.color.white_bg));
|
||||
break;
|
||||
case 2:
|
||||
// tue
|
||||
binding.tue.setBackgroundResource(R.drawable.seleted_item_primary);
|
||||
binding.tue1.setTextColor(getResources().getColor(R.color.white_bg));
|
||||
binding.tue2.setTextColor(getResources().getColor(R.color.white_bg));
|
||||
break;
|
||||
case 3:
|
||||
// wed
|
||||
binding.wed.setBackgroundResource(R.drawable.seleted_item_primary);
|
||||
binding.wed1.setTextColor(getResources().getColor(R.color.white_bg));
|
||||
binding.wed2.setTextColor(getResources().getColor(R.color.white_bg));
|
||||
break;
|
||||
case 4:
|
||||
// thu
|
||||
binding.thu.setBackgroundResource(R.drawable.seleted_item_primary);
|
||||
binding.thu1.setTextColor(getResources().getColor(R.color.white_bg));
|
||||
binding.thu2.setTextColor(getResources().getColor(R.color.white_bg));
|
||||
break;
|
||||
case 5:
|
||||
// fri
|
||||
binding.fri.setBackgroundResource(R.drawable.seleted_item_primary);
|
||||
binding.fri1.setTextColor(getResources().getColor(R.color.white_bg));
|
||||
binding.fri2.setTextColor(getResources().getColor(R.color.white_bg));
|
||||
break;
|
||||
case 6:
|
||||
// sat
|
||||
binding.sat.setBackgroundResource(R.drawable.seleted_item_primary);
|
||||
binding.sat1.setTextColor(getResources().getColor(R.color.white_bg));
|
||||
binding.sat2.setTextColor(getResources().getColor(R.color.white_bg));
|
||||
break;
|
||||
}
|
||||
}else{
|
||||
switch (position){
|
||||
case 0:
|
||||
// sun
|
||||
binding.sun.setBackgroundColor(getResources().getColor(R.color.white_bg));
|
||||
binding.sunT1.setTextColor(getResources().getColor(R.color.black));
|
||||
binding.sunT2.setTextColor(getResources().getColor(R.color.black));
|
||||
break;
|
||||
case 1:
|
||||
// mon
|
||||
binding.mon.setBackgroundColor(getResources().getColor(R.color.white_bg));
|
||||
binding.monT1.setTextColor(getResources().getColor(R.color.black));
|
||||
binding.monT2.setTextColor(getResources().getColor(R.color.black));
|
||||
break;
|
||||
case 2:
|
||||
// tue
|
||||
binding.tue.setBackgroundColor(getResources().getColor(R.color.white_bg));
|
||||
binding.tue1.setTextColor(getResources().getColor(R.color.black));
|
||||
binding.tue2.setTextColor(getResources().getColor(R.color.black));
|
||||
break;
|
||||
case 3:
|
||||
// wed
|
||||
binding.wed.setBackgroundColor(getResources().getColor(R.color.white_bg));
|
||||
binding.wed1.setTextColor(getResources().getColor(R.color.black));
|
||||
binding.wed2.setTextColor(getResources().getColor(R.color.black));
|
||||
break;
|
||||
case 4:
|
||||
// thu
|
||||
binding.thu.setBackgroundColor(getResources().getColor(R.color.white_bg));
|
||||
binding.thu1.setTextColor(getResources().getColor(R.color.black));
|
||||
binding.thu2.setTextColor(getResources().getColor(R.color.black));
|
||||
break;
|
||||
case 5:
|
||||
// fri
|
||||
binding.fri.setBackgroundColor(getResources().getColor(R.color.white_bg));
|
||||
binding.fri1.setTextColor(getResources().getColor(R.color.black));
|
||||
binding.fri2.setTextColor(getResources().getColor(R.color.black));
|
||||
break;
|
||||
case 6:
|
||||
// sat
|
||||
binding.sat.setBackgroundColor(getResources().getColor(R.color.white_bg));
|
||||
binding.sat1.setTextColor(getResources().getColor(R.color.black));
|
||||
binding.sat2.setTextColor(getResources().getColor(R.color.black));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// swipe option menu click listener for reminder list
|
||||
@Override
|
||||
public void onSwipeOptionClicked(int viewID, int position) {
|
||||
if (viewID == R.id.reminder_delete){
|
||||
|
||||
AppUtil.showSOSDecision(requireContext(),
|
||||
getString(R.string.delete_med_reminder),
|
||||
getString(R.string.yes), getString(R.string.no),
|
||||
v -> {
|
||||
// yes button clicked
|
||||
Toast.makeText(requireContext(), "Delete " + position, Toast.LENGTH_SHORT).show();
|
||||
}, v -> {
|
||||
// no button clicked
|
||||
});
|
||||
|
||||
}else if (viewID == R.id.reminder_edit){
|
||||
Bundle bundle = new Bundle();
|
||||
Reminder reminder = reminderViewModel.getRemindersList().get(position);
|
||||
|
||||
bundle.putSerializable(REMINDER_KEY, reminder);
|
||||
|
||||
Navigation.findNavController(binding.getRoot())
|
||||
.navigate(R.id.action_reminderFragment_to_addReminderFragment, bundle);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.ssb.simplitend.medreminder.mvvm;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Objects;
|
||||
|
||||
public class Reminder implements Serializable {
|
||||
|
||||
public String dosage_name, time, quantity;
|
||||
|
||||
public Reminder(){}
|
||||
|
||||
public Reminder(String dosage_name, String time, String quantity) {
|
||||
this.dosage_name = dosage_name;
|
||||
this.time = time;
|
||||
this.quantity = quantity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
Reminder reminder = (Reminder) o;
|
||||
return Objects.equals(dosage_name, reminder.dosage_name) && Objects.equals(time, reminder.time) && Objects.equals(quantity, reminder.quantity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(dosage_name, time, quantity);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
package com.ssb.simplitend.medreminder.mvvm;
|
||||
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.content.res.AppCompatResources;
|
||||
import androidx.recyclerview.widget.DiffUtil;
|
||||
import androidx.recyclerview.widget.ListAdapter;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.ssb.simplitend.R;
|
||||
import com.ssb.simplitend.databinding.ReminderViewholderBinding;
|
||||
|
||||
public class ReminderAdapter extends ListAdapter<Reminder, ReminderAdapter.ReminderViewHolder> {
|
||||
|
||||
private static final DiffUtil.ItemCallback<Reminder> DIFF_CALLBACK = new DiffUtil.ItemCallback<Reminder>() {
|
||||
@Override
|
||||
public boolean areItemsTheSame(@NonNull Reminder oldItem, @NonNull Reminder newItem) {
|
||||
return oldItem.equals(newItem);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean areContentsTheSame(@NonNull Reminder oldItem, @NonNull Reminder newItem) {
|
||||
return oldItem.equals(newItem);
|
||||
}
|
||||
};
|
||||
|
||||
// static thing for selection status
|
||||
public final boolean[] selection_state;
|
||||
|
||||
public ReminderAdapter(){
|
||||
super(DIFF_CALLBACK);
|
||||
this.selection_state = new boolean[2];
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public ReminderViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
ReminderViewholderBinding binding = ReminderViewholderBinding.inflate(LayoutInflater.from(parent.getContext()));
|
||||
return new ReminderViewHolder(binding, selection_state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull ReminderViewHolder holder, int position) {
|
||||
holder.setReminder(getItem(position), position);
|
||||
}
|
||||
|
||||
public static class ReminderViewHolder extends RecyclerView.ViewHolder{
|
||||
|
||||
public ReminderViewholderBinding binding;
|
||||
|
||||
private final boolean[] selection_state;
|
||||
|
||||
public ReminderViewHolder(ReminderViewholderBinding binding, boolean[] selection_state){
|
||||
super(binding.getRoot());
|
||||
this.binding = binding;
|
||||
this.selection_state = selection_state;
|
||||
}
|
||||
|
||||
public void setReminder(Reminder reminder, int position){
|
||||
binding.medName.setText(reminder.dosage_name);
|
||||
binding.time.setText(reminder.time);
|
||||
binding.quantity.setText(reminder.quantity);
|
||||
|
||||
// static image
|
||||
if (position == 0){
|
||||
binding.medImg.setImageResource(R.drawable.img_med_type_1);
|
||||
}else{
|
||||
binding.medImg.setImageResource(R.drawable.img_med_type_2);
|
||||
}
|
||||
|
||||
binding.done.setOnClickListener(v -> {
|
||||
if (selection_state[position]){
|
||||
// item selected. un-selecting now
|
||||
binding.sideBar.setBackgroundTintList(null);
|
||||
binding.card.setCardBackgroundColor(AppCompatResources.getColorStateList(itemView.getContext(), R.color.white_bg));
|
||||
binding.done.setImageResource(R.drawable.ic_done_accent);
|
||||
}else{
|
||||
// item un-selected. selecting now
|
||||
binding.sideBar.setBackgroundTintList(AppCompatResources.getColorStateList(itemView.getContext(), R.color.color_primary));
|
||||
binding.card.setCardBackgroundColor(AppCompatResources.getColorStateList(itemView.getContext(), R.color.color_accent));
|
||||
binding.done.setImageResource(R.drawable.ic_done_accent_2);
|
||||
}
|
||||
|
||||
selection_state[position] = !selection_state[position];
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.ssb.simplitend.medreminder.mvvm;
|
||||
|
||||
import androidx.lifecycle.ViewModel;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class ReminderViewModel extends ViewModel {
|
||||
|
||||
private final ArrayList<Reminder> remindersList;
|
||||
|
||||
// reminder list adapter
|
||||
private final ReminderAdapter reminderAdapter;
|
||||
|
||||
public ReminderViewModel(){
|
||||
// fetch reminder list
|
||||
|
||||
reminderAdapter = new ReminderAdapter();
|
||||
|
||||
// static for now
|
||||
// TODO: 06-07-2023
|
||||
|
||||
remindersList = new ArrayList<>();
|
||||
remindersList.add(new Reminder("Vitamin D3", "02:00 pm", "2 capsules"));
|
||||
remindersList.add(new Reminder("Sinupret", "09:00 pm", "1 capsules"));
|
||||
}
|
||||
|
||||
public ArrayList<Reminder> getRemindersList() {
|
||||
return remindersList;
|
||||
}
|
||||
|
||||
public ReminderAdapter getReminderAdapter() {
|
||||
return reminderAdapter;
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,9 @@ import android.view.ViewGroup;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.navigation.Navigation;
|
||||
|
||||
import com.ssb.simplitend.R;
|
||||
import com.ssb.simplitend.databinding.ProfileProgressFragmentBinding;
|
||||
|
||||
public class ProfileProgressFragment extends Fragment {
|
||||
@@ -25,6 +27,25 @@ public class ProfileProgressFragment extends Fragment {
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
binding = ProfileProgressFragmentBinding.inflate(inflater, container, false);
|
||||
|
||||
initProgress();
|
||||
|
||||
clickEvents();
|
||||
|
||||
return binding.getRoot();
|
||||
}
|
||||
|
||||
private void initProgress() {
|
||||
}
|
||||
|
||||
private void clickEvents() {
|
||||
|
||||
binding.medicReminder.setOnClickListener(v ->
|
||||
Navigation.findNavController(v).navigate(R.id.action_profileProgressFragment_to_reminderFragment)
|
||||
);
|
||||
|
||||
binding.medicInfo.setOnClickListener(v ->
|
||||
Navigation.findNavController(v).navigate(R.id.action_profileProgressFragment_to_medicalInfoFragment)
|
||||
);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.ssb.simplitend.welcome.activities;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.appcompat.app.AppCompatDelegate;
|
||||
|
||||
import android.os.Bundle;
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.ssb.simplitend.welcome.fragments;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.text.InputType;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
@@ -27,11 +28,16 @@ public class SignInFragment extends Fragment {
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
binding = SignInFragmentBinding.inflate(inflater, container, false);
|
||||
|
||||
initViews();
|
||||
|
||||
clickEvents();
|
||||
|
||||
return binding.getRoot();
|
||||
}
|
||||
|
||||
private void initViews() {
|
||||
}
|
||||
|
||||
private void clickEvents() {
|
||||
|
||||
binding.forgotPin.setOnClickListener(v ->
|
||||
|
||||
@@ -4,6 +4,7 @@ import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
@@ -9,15 +9,24 @@ import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.navigation.Navigation;
|
||||
import androidx.recyclerview.widget.GridLayoutManager;
|
||||
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialog;
|
||||
import com.ssb.simplitend.R;
|
||||
import com.ssb.simplitend.databinding.AddContactFragmentBinding;
|
||||
import com.ssb.simplitend.databinding.DoneBottomsheetBinding;
|
||||
import com.ssb.simplitend.welcome.fragments.contacts.mvvm.AddContactAdapter;
|
||||
import com.ssb.simplitend.welcome.fragments.contacts.mvvm.Contact;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class AddContactFragment extends Fragment {
|
||||
|
||||
// view binding
|
||||
protected AddContactFragmentBinding binding;
|
||||
|
||||
protected AddContactAdapter contactAdapter;
|
||||
|
||||
public AddContactFragment(){
|
||||
// required empty const.
|
||||
}
|
||||
@@ -26,25 +35,67 @@ public class AddContactFragment extends Fragment {
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
binding = AddContactFragmentBinding.inflate(inflater, container, false);
|
||||
|
||||
|
||||
initViews();
|
||||
|
||||
clickEvents();
|
||||
|
||||
return binding.getRoot();
|
||||
}
|
||||
|
||||
private void initViews() {
|
||||
|
||||
binding.contactRv.setLayoutManager(new GridLayoutManager(requireContext(), 2));
|
||||
contactAdapter = new AddContactAdapter();
|
||||
binding.contactRv.setAdapter(contactAdapter);
|
||||
|
||||
loadContacts();
|
||||
|
||||
}
|
||||
|
||||
private void loadContacts() {
|
||||
// static data
|
||||
ArrayList<Contact> contacts = new ArrayList<>();
|
||||
// adding 10 contacts
|
||||
contacts.add(new Contact("Akansha Surve", "phone number"));
|
||||
contacts.add(new Contact("Akansha Surve", "phone number"));
|
||||
contacts.add(new Contact("Akansha Surve", "phone number"));
|
||||
contacts.add(new Contact("Akansha Surve", "phone number"));
|
||||
contacts.add(new Contact("Akansha Surve", "phone number"));
|
||||
contacts.add(new Contact("Akansha Surve", "phone number"));
|
||||
contacts.add(new Contact("Akansha Surve", "phone number"));
|
||||
contacts.add(new Contact("Akansha Surve", "phone number"));
|
||||
contacts.add(new Contact("Akansha Surve", "phone number"));
|
||||
contacts.add(new Contact("Akansha Surve", "phone number"));
|
||||
|
||||
contactAdapter.submitList(contacts);
|
||||
|
||||
}
|
||||
|
||||
private void clickEvents() {
|
||||
|
||||
binding.static1.setOnClickListener(v ->
|
||||
Navigation.findNavController(v).navigate(R.id.action_addContactFragment_to_contactInfoFragment)
|
||||
);
|
||||
|
||||
binding.static2.setOnClickListener(v ->
|
||||
Navigation.findNavController(v).navigate(R.id.action_addContactFragment_to_contactListFragment)
|
||||
);
|
||||
binding.backBtn.setOnClickListener(v -> Navigation.findNavController(v).popBackStack());
|
||||
|
||||
binding.nextBtn.setOnClickListener(v ->
|
||||
Navigation.findNavController(v).navigate(R.id.action_addContactFragment_to_profileProgressFragment)
|
||||
);
|
||||
Navigation.findNavController(v).navigate(R.id.action_addContactFragment_to_profileProgressFragment));
|
||||
|
||||
}
|
||||
|
||||
private void showEmailSentAnim() {
|
||||
|
||||
DoneBottomsheetBinding binding = DoneBottomsheetBinding.inflate(getLayoutInflater());
|
||||
|
||||
BottomSheetDialog bsd = new BottomSheetDialog(requireContext(), R.style.BottomSheetDialog);
|
||||
bsd.setContentView(binding.getRoot());
|
||||
|
||||
// TODO: 05-07-2023 animation part
|
||||
|
||||
binding.text.setText(getString(R.string.email_sent_to_caregiver));
|
||||
|
||||
binding.subText.setVisibility(View.VISIBLE);
|
||||
binding.subText.setText(getString(R.string.continue_and_complete_profile));
|
||||
|
||||
bsd.show();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import android.view.ViewGroup;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.navigation.Navigation;
|
||||
|
||||
import com.ssb.simplitend.databinding.ContactInfoFragmentBinding;
|
||||
|
||||
@@ -25,6 +26,14 @@ public class ContactInfoFragment extends Fragment {
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
binding = ContactInfoFragmentBinding.inflate(inflater, container, false);
|
||||
|
||||
clickEvents();
|
||||
|
||||
return binding.getRoot();
|
||||
}
|
||||
|
||||
private void clickEvents() {
|
||||
|
||||
binding.backBtn.setOnClickListener(v -> Navigation.findNavController(v).popBackStack());
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,8 +4,12 @@ import static com.ssb.simplitend.welcome.fragments.contacts.CreateContactFragmen
|
||||
import static com.ssb.simplitend.welcome.fragments.contacts.CreateContactFragment.TO_EDIT_KEY;
|
||||
|
||||
import android.Manifest;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Bundle;
|
||||
import android.provider.ContactsContract;
|
||||
import android.text.Editable;
|
||||
import android.text.TextWatcher;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
@@ -41,10 +45,18 @@ public class ContactListFragment extends Fragment {
|
||||
|
||||
protected ActivityResultLauncher<String> permissionLauncher;
|
||||
|
||||
private ArrayList<Contact> contactList;
|
||||
|
||||
public ContactListFragment() {
|
||||
// required empty const.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
loadContacts();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
@@ -63,9 +75,10 @@ public class ContactListFragment extends Fragment {
|
||||
|
||||
binding.createContact.setOnClickListener(v ->
|
||||
{
|
||||
Bundle arguments = new Bundle();
|
||||
arguments.putBoolean(TO_EDIT_KEY, false);
|
||||
Navigation.findNavController(v).navigate(R.id.action_contactListFragment_to_createContactFragment, arguments);
|
||||
// insert contact intent
|
||||
Intent intent = new Intent(Intent.ACTION_INSERT);
|
||||
intent.setType(ContactsContract.Contacts.CONTENT_TYPE);
|
||||
startActivity(intent);
|
||||
}
|
||||
);
|
||||
|
||||
@@ -78,6 +91,55 @@ public class ContactListFragment extends Fragment {
|
||||
}
|
||||
);
|
||||
|
||||
binding.search.addTextChangedListener(new TextWatcher() {
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(Editable s) {
|
||||
filterContactList(s.toString().trim().toLowerCase());
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
// filters contact list w.r.t searchInput
|
||||
private void filterContactList(String searchInput) {
|
||||
|
||||
if(searchInput.isEmpty()) {
|
||||
contactListAdapter.submitList(contactList);
|
||||
return;
|
||||
}
|
||||
|
||||
ArrayList<Contact> filteredList = new ArrayList<>();
|
||||
|
||||
for (Contact contact: contactList){
|
||||
if (contact.name != null && contact.name.trim().toLowerCase().contains(searchInput)){
|
||||
filteredList.add(contact);
|
||||
}else if (contact.phoneNumber != null && contact.phoneNumber.trim().contains(searchInput)){
|
||||
filteredList.add(contact);
|
||||
}else if (contact.email != null && contact.email.trim().toLowerCase().contains(searchInput)){
|
||||
filteredList.add(contact);
|
||||
}else if (contact.relationship != null && contact.relationship.trim().toLowerCase().contains(searchInput)){
|
||||
filteredList.add(contact);
|
||||
}
|
||||
}
|
||||
|
||||
if (filteredList.isEmpty()) {
|
||||
Toast.makeText(requireContext(), "No match found", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
|
||||
contactListAdapter.submitList(filteredList);
|
||||
|
||||
binding.contactRv.smoothScrollToPosition(0);
|
||||
|
||||
}
|
||||
|
||||
private void initializeViews() {
|
||||
@@ -98,8 +160,6 @@ public class ContactListFragment extends Fragment {
|
||||
}
|
||||
);
|
||||
|
||||
loadContacts();
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -114,6 +174,14 @@ public class ContactListFragment extends Fragment {
|
||||
contactViewModel = new ViewModelProvider(this).get(ContactViewModel.class);
|
||||
Log.d(TAG, "initializeViews: viewmodel " + contactViewModel);
|
||||
|
||||
contactListAdapter.submitList(contactViewModel.getContactList());
|
||||
contactList = null;
|
||||
contactList = contactViewModel.getContactList(requireContext());
|
||||
|
||||
if (binding.search.getText().toString().trim().isEmpty())
|
||||
contactListAdapter.submitList(contactList);
|
||||
else
|
||||
filterContactList(binding.search.getText().toString().trim().toLowerCase());
|
||||
|
||||
binding.contactRv.smoothScrollToPosition(0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,27 +1,21 @@
|
||||
package com.ssb.simplitend.welcome.fragments.contacts;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.activity.result.ActivityResultLauncher;
|
||||
import androidx.activity.result.contract.ActivityResultContracts;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.navigation.Navigation;
|
||||
import androidx.vectordrawable.graphics.drawable.Animatable2Compat;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.bumptech.glide.load.DataSource;
|
||||
import com.bumptech.glide.load.engine.GlideException;
|
||||
import com.bumptech.glide.load.resource.gif.GifDrawable;
|
||||
import com.bumptech.glide.request.RequestListener;
|
||||
import com.bumptech.glide.request.target.Target;
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialog;
|
||||
import com.ssb.simplitend.R;
|
||||
import com.ssb.simplitend.databinding.CreateEditContactFragmentBinding;
|
||||
@@ -29,7 +23,19 @@ import com.ssb.simplitend.databinding.DecisionBottomsheetBinding;
|
||||
import com.ssb.simplitend.databinding.DoneBottomsheetBinding;
|
||||
import com.ssb.simplitend.welcome.fragments.contacts.mvvm.Contact;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class CreateContactFragment extends Fragment {
|
||||
|
||||
// log tag
|
||||
private static final String TAG = "CreateContactFragment";
|
||||
|
||||
// view binding
|
||||
protected CreateEditContactFragmentBinding binding;
|
||||
@@ -41,6 +47,9 @@ public class CreateContactFragment extends Fragment {
|
||||
// flag if current instance is to edit or create contact
|
||||
boolean to_edit;
|
||||
|
||||
// image selector launcher
|
||||
private ActivityResultLauncher<String> imageSelector;
|
||||
|
||||
public CreateContactFragment() {
|
||||
// required empty const.
|
||||
}
|
||||
@@ -59,6 +68,8 @@ public class CreateContactFragment extends Fragment {
|
||||
|
||||
private void clickEvents() {
|
||||
|
||||
binding.backBtn.setOnClickListener(v -> Navigation.findNavController(v).popBackStack());
|
||||
|
||||
binding.nextBtn.setOnClickListener(v -> {
|
||||
|
||||
if (to_edit){
|
||||
@@ -66,11 +77,13 @@ public class CreateContactFragment extends Fragment {
|
||||
showSaveEditDecision();
|
||||
}else {
|
||||
// saving new contact
|
||||
gotoAddContactFragment();
|
||||
Navigation.findNavController(v).popBackStack();
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
binding.image.setOnClickListener(v -> imageSelector.launch("image/*"));
|
||||
|
||||
}
|
||||
|
||||
private void showSaveEditDecision() {
|
||||
@@ -105,35 +118,25 @@ public class CreateContactFragment extends Fragment {
|
||||
|
||||
binding.text.setText(getString(R.string.changes_successful));
|
||||
|
||||
binding.anim.addAnimatorListener(new Animator.AnimatorListener() {
|
||||
@Override
|
||||
public void onAnimationStart(@NonNull Animator animation) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationEnd(@NonNull Animator animation) {
|
||||
bsd.dismiss();
|
||||
gotoAddContactFragment();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationCancel(@NonNull Animator animation) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationRepeat(@NonNull Animator animation) {
|
||||
}
|
||||
});
|
||||
Glide.with(requireContext())
|
||||
.asGif()
|
||||
.load(R.raw.done_anim_primary)
|
||||
.into(binding.doneAnim);
|
||||
|
||||
bsd.show();
|
||||
|
||||
gotoAddContactFragment(3000, bsd);
|
||||
|
||||
}
|
||||
|
||||
private void gotoAddContactFragment(){
|
||||
Navigation.findNavController(binding.getRoot())
|
||||
.navigate(R.id.action_createContactFragment_to_addContactFragment);
|
||||
private void gotoAddContactFragment(long inMsm, BottomSheetDialog bsd){
|
||||
|
||||
new Handler().postDelayed(() -> {
|
||||
if (bsd != null) bsd.dismiss();
|
||||
Navigation.findNavController(binding.getRoot())
|
||||
.navigate(R.id.action_createContactFragment_to_addContactFragment);
|
||||
|
||||
}, inMsm);
|
||||
}
|
||||
|
||||
private void showSOSDecision() {
|
||||
@@ -142,6 +145,7 @@ public class CreateContactFragment extends Fragment {
|
||||
|
||||
BottomSheetDialog bsd = new BottomSheetDialog(requireContext(), R.style.BottomSheetDialog);
|
||||
bsd.setContentView(binding.getRoot());
|
||||
bsd.setCancelable(false);
|
||||
|
||||
binding.text.setText(getString(R.string.make_sos));
|
||||
|
||||
@@ -186,6 +190,81 @@ public class CreateContactFragment extends Fragment {
|
||||
}
|
||||
});
|
||||
|
||||
loadCountryCodeDropDown();
|
||||
|
||||
// image selector launcher
|
||||
imageSelector = registerForActivityResult(new ActivityResultContracts.GetContent(),
|
||||
uri -> {
|
||||
if (uri != null){
|
||||
binding.image.setImageURI(null);
|
||||
binding.image.setImageURI(uri);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private void loadCountryCodeDropDown() {
|
||||
|
||||
ArrayList<String> countryCodeList = new ArrayList<>();
|
||||
|
||||
try {
|
||||
|
||||
String countryCodeStr = readCountryCodes(requireContext());
|
||||
JSONArray jsonArray = new JSONArray(countryCodeStr);
|
||||
|
||||
for (int i = 0; i < jsonArray.length(); i++) {
|
||||
|
||||
JSONObject code = jsonArray.getJSONObject(i);
|
||||
|
||||
countryCodeList.add(code.getString("dial_code"));
|
||||
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
|
||||
// if cannot load all country codes showing only india's dial code
|
||||
countryCodeList.add("+91");
|
||||
|
||||
Log.e(TAG, "loadCountryCodeDropDown: ", e);
|
||||
}
|
||||
|
||||
binding.countryCodes.setLifecycleOwner(this);
|
||||
|
||||
binding.countryCodes.setItems(countryCodeList);
|
||||
|
||||
binding.countryCodes.selectItemByIndex(countryCodeList.indexOf("+91"));
|
||||
|
||||
binding.countryCodes.setDismissWhenNotifiedItemSelected(true);
|
||||
|
||||
binding.countryCodes.setIsFocusable(true);
|
||||
|
||||
}
|
||||
|
||||
public String readCountryCodes(Context context) throws IOException {
|
||||
StringBuilder returnString = new StringBuilder();
|
||||
|
||||
InputStream fIn = context.getResources().openRawResource(R.raw.country_code);
|
||||
InputStreamReader isr = new InputStreamReader(fIn);
|
||||
BufferedReader input = new BufferedReader(isr);
|
||||
|
||||
String line = "";
|
||||
|
||||
while ((line = input.readLine()) != null) {
|
||||
returnString.append(line);
|
||||
}
|
||||
|
||||
try {
|
||||
isr.close();
|
||||
|
||||
if (fIn != null) fIn.close();
|
||||
|
||||
input.close();
|
||||
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "readCountryCodes: ", e);
|
||||
}
|
||||
|
||||
return returnString.toString();
|
||||
}
|
||||
|
||||
private void setDetails(Contact contact) {
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
package com.ssb.simplitend.welcome.fragments.contacts.mvvm;
|
||||
|
||||
import static com.ssb.simplitend.welcome.fragments.contacts.CreateContactFragment.CONTACT_KEY;
|
||||
import static com.ssb.simplitend.welcome.fragments.contacts.CreateContactFragment.TO_EDIT_KEY;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.graphics.Color;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.navigation.Navigation;
|
||||
import androidx.recyclerview.widget.DiffUtil;
|
||||
import androidx.recyclerview.widget.ListAdapter;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.ssb.simplitend.R;
|
||||
import com.ssb.simplitend.databinding.AddContactViewholderBinding;
|
||||
|
||||
public class AddContactAdapter extends ListAdapter<Contact, AddContactAdapter.ContactViewHolder> {
|
||||
|
||||
private static final DiffUtil.ItemCallback<Contact> DIFF_UTIL = new DiffUtil.ItemCallback<Contact>() {
|
||||
@Override
|
||||
public boolean areItemsTheSame(@NonNull Contact oldItem, @NonNull Contact newItem) {
|
||||
return oldItem.name.equals(newItem.name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean areContentsTheSame(@NonNull Contact oldItem, @NonNull Contact newItem) {
|
||||
return oldItem.equals(newItem);
|
||||
}
|
||||
};
|
||||
|
||||
public AddContactAdapter() {
|
||||
super(DIFF_UTIL);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public ContactViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
AddContactViewholderBinding binding = AddContactViewholderBinding.inflate(LayoutInflater.from(parent.getContext()));
|
||||
return new ContactViewHolder(binding);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull ContactViewHolder holder, int position) {
|
||||
holder.setData(getItem(position), position);
|
||||
}
|
||||
|
||||
public static class ContactViewHolder extends RecyclerView.ViewHolder {
|
||||
public AddContactViewholderBinding binding;
|
||||
|
||||
private AlertDialog contactDialog;
|
||||
|
||||
public ContactViewHolder(AddContactViewholderBinding binding) {
|
||||
super(binding.getRoot());
|
||||
this.binding = binding;
|
||||
this.contactDialog = new AlertDialog.Builder(itemView.getContext())
|
||||
.setTitle("Add contact")
|
||||
.setMessage("Select an option to add contact")
|
||||
.setPositiveButton("Add manually", ((dialog1, which) -> {
|
||||
|
||||
// navigating to add contact fragment
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putBoolean(TO_EDIT_KEY, false);
|
||||
Navigation.findNavController(binding.getRoot()).navigate(R.id.action_addContactFragment_to_createContactFragment, bundle);
|
||||
|
||||
}))
|
||||
.setNegativeButton("Select contact", ((dialog1, which) -> {
|
||||
Navigation.findNavController(binding.getRoot()).navigate(R.id.action_addContactFragment_to_contactListFragment);
|
||||
}))
|
||||
.create();
|
||||
}
|
||||
|
||||
public void setData(Contact contact, int position) {
|
||||
|
||||
if (position == 0) {
|
||||
binding.sos.setVisibility(View.VISIBLE);
|
||||
binding.card.setCardBackgroundColor(Color.WHITE);
|
||||
binding.name.setText("Akansha Surve");
|
||||
binding.imag.setImageResource(R.drawable.contact_img_static);
|
||||
|
||||
binding.card.setOnClickListener(v -> {
|
||||
Navigation.findNavController(v).navigate(R.id.action_addContactFragment_to_contactInfoFragment);
|
||||
});
|
||||
|
||||
} else {
|
||||
binding.name.setText("Add contact");
|
||||
|
||||
binding.card.setOnClickListener(v -> {
|
||||
|
||||
contactDialog.show();
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -4,23 +4,20 @@ import android.app.Application;
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.lifecycle.AndroidViewModel;
|
||||
import androidx.lifecycle.ViewModel;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class ContactViewModel extends AndroidViewModel {
|
||||
|
||||
private final ArrayList<Contact> contactList;
|
||||
private final UserContactRepository contactRepository;
|
||||
|
||||
public ContactViewModel(Application application){
|
||||
super(application);
|
||||
this.contactRepository = new UserContactRepository();
|
||||
this.contactList = this.contactRepository.getContactList(application.getApplicationContext());
|
||||
}
|
||||
|
||||
public ArrayList<Contact> getContactList() {
|
||||
return contactList;
|
||||
public ArrayList<Contact> getContactList(Context context) {
|
||||
return this.contactRepository.getContactList(context.getApplicationContext());
|
||||
}
|
||||
|
||||
public UserContactRepository getContactRepository() {
|
||||
|
||||
@@ -2,13 +2,19 @@ package com.ssb.simplitend.welcome.fragments.contacts.mvvm;
|
||||
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.database.ContentObserver;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.provider.ContactsContract;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.ssb.simplitend.welcome.fragments.contacts.mvvm.Contact;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
|
||||
public class UserContactRepository {
|
||||
@@ -16,7 +22,8 @@ public class UserContactRepository {
|
||||
private static final String[] PROJECTION = new String[]{
|
||||
ContactsContract.CommonDataKinds.Phone.CONTACT_ID,
|
||||
ContactsContract.Contacts.DISPLAY_NAME,
|
||||
ContactsContract.CommonDataKinds.Phone.NUMBER
|
||||
ContactsContract.CommonDataKinds.Phone.NUMBER,
|
||||
ContactsContract.CommonDataKinds.Phone.PHOTO_URI
|
||||
};
|
||||
|
||||
public UserContactRepository(){}
|
||||
|
||||
@@ -12,6 +12,7 @@ import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.navigation.Navigation;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.ssb.simplitend.R;
|
||||
import com.ssb.simplitend.apputils.AppUtil;
|
||||
import com.ssb.simplitend.databinding.CheckMailFragmentBinding;
|
||||
@@ -39,6 +40,13 @@ public class CheckMailFragment extends Fragment {
|
||||
|
||||
private void initViews() {
|
||||
|
||||
// showing gif
|
||||
Glide.with(binding.image)
|
||||
.asGif()
|
||||
.load(R.raw.email_sending_anim)
|
||||
.placeholder(R.drawable.forgot_pin_email_img)
|
||||
.into(binding.image);
|
||||
|
||||
initOTPBoxes();
|
||||
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.navigation.Navigation;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.ssb.simplitend.R;
|
||||
import com.ssb.simplitend.databinding.ForgotPinFragmentBinding;
|
||||
|
||||
@@ -26,11 +27,22 @@ public class ForgotPinFragment extends Fragment {
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
binding = ForgotPinFragmentBinding.inflate(inflater, container, false);
|
||||
|
||||
initViews();
|
||||
|
||||
clickEvents();
|
||||
|
||||
return binding.getRoot();
|
||||
}
|
||||
|
||||
private void initViews() {
|
||||
// showing gif
|
||||
Glide.with(binding.image)
|
||||
.asGif()
|
||||
.load(R.raw.email_sending_anim)
|
||||
.placeholder(R.drawable.forgot_pin_email_img)
|
||||
.into(binding.image);
|
||||
}
|
||||
|
||||
private void clickEvents() {
|
||||
|
||||
binding.backBtn.setOnClickListener(v ->
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package com.ssb.simplitend.welcome.fragments.register;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
@@ -10,14 +12,34 @@ import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.navigation.Navigation;
|
||||
|
||||
import com.skydoves.powerspinner.OnSpinnerItemSelectedListener;
|
||||
import com.ssb.simplitend.R;
|
||||
import com.ssb.simplitend.databinding.LocationFragmentBinding;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
|
||||
public class LocationFragment extends Fragment {
|
||||
|
||||
private static final String TAG = "LocationFragment";
|
||||
|
||||
// view binding
|
||||
protected LocationFragmentBinding binding;
|
||||
|
||||
// country list
|
||||
ArrayList<String> countryList;
|
||||
|
||||
// Map for country and their states
|
||||
HashMap<String, ArrayList<String>> country_N_states_map;
|
||||
|
||||
public LocationFragment(){
|
||||
// required empty const.
|
||||
}
|
||||
@@ -27,11 +49,113 @@ public class LocationFragment extends Fragment {
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
binding = LocationFragmentBinding.inflate(inflater, container, false);
|
||||
|
||||
initViews();
|
||||
|
||||
clickEvents();
|
||||
|
||||
return binding.getRoot();
|
||||
}
|
||||
|
||||
private void initViews() {
|
||||
|
||||
loadCountriesAndStates();
|
||||
|
||||
}
|
||||
|
||||
// loads all countries and their states into the spinners
|
||||
private void loadCountriesAndStates() {
|
||||
|
||||
countryList = new ArrayList<>();
|
||||
|
||||
country_N_states_map = new HashMap<>();
|
||||
|
||||
try {
|
||||
|
||||
String country_n_states_str = readCountryNStates(requireContext());
|
||||
|
||||
JSONArray country_n_states = new JSONObject(country_n_states_str).getJSONArray("countries");
|
||||
|
||||
Log.d(TAG, "loadCountriesAndStates: " + country_n_states);
|
||||
|
||||
for (int i = 0; i < country_n_states.length(); i++) {
|
||||
|
||||
String country = country_n_states.getJSONObject(i).getString("country");
|
||||
countryList.add(country);
|
||||
|
||||
JSONArray states = country_n_states.getJSONObject(i).getJSONArray("states");
|
||||
|
||||
ArrayList<String> stateList = new ArrayList<>();
|
||||
|
||||
for (int j = 0; j < states.length(); j++) {
|
||||
stateList.add(states.getString(j));
|
||||
}
|
||||
|
||||
country_N_states_map.put(country, stateList);
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
|
||||
Log.e(TAG, "load country and states: ", e);
|
||||
}
|
||||
|
||||
Log.d(TAG, "loadCountriesAndStates: " + countryList);
|
||||
|
||||
binding.stateSpinner.setLifecycleOwner(this);
|
||||
binding.countrySpinner.setLifecycleOwner(this);
|
||||
|
||||
binding.countrySpinner.setItems(countryList);
|
||||
|
||||
binding.stateSpinner.setDismissWhenNotifiedItemSelected(true);
|
||||
binding.countrySpinner.setDismissWhenNotifiedItemSelected(true);
|
||||
|
||||
binding.stateSpinner.setIsFocusable(true);
|
||||
binding.countrySpinner.setIsFocusable(true);
|
||||
|
||||
binding.countrySpinner.setOnSpinnerItemSelectedListener((OnSpinnerItemSelectedListener<String>) (i, s, i1, t1) -> {
|
||||
|
||||
ArrayList<String> stateList;
|
||||
|
||||
if (country_N_states_map.containsKey(t1) && country_N_states_map.get(t1) != null){
|
||||
stateList = country_N_states_map.get(t1);
|
||||
}else{
|
||||
stateList = new ArrayList<>();
|
||||
}
|
||||
|
||||
if (stateList != null) {
|
||||
binding.stateSpinner.setItems(stateList);
|
||||
binding.stateSpinner.clearSelectedItem();
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
public String readCountryNStates(Context context) throws IOException {
|
||||
StringBuilder returnString = new StringBuilder();
|
||||
|
||||
InputStream fIn = context.getResources().openRawResource(R.raw.country_n_states);
|
||||
InputStreamReader isr = new InputStreamReader(fIn);
|
||||
BufferedReader input = new BufferedReader(isr);
|
||||
|
||||
String line = "";
|
||||
|
||||
while ((line = input.readLine()) != null) {
|
||||
returnString.append(line);
|
||||
}
|
||||
|
||||
try {
|
||||
isr.close();
|
||||
|
||||
if (fIn != null) fIn.close();
|
||||
|
||||
input.close();
|
||||
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "readCountryNStates: ", e);
|
||||
}
|
||||
|
||||
return returnString.toString();
|
||||
}
|
||||
|
||||
private void clickEvents() {
|
||||
|
||||
binding.backBtn.setOnClickListener(v -> Navigation.findNavController(v).popBackStack());
|
||||
|
||||
@@ -1,23 +1,44 @@
|
||||
package com.ssb.simplitend.welcome.fragments.register;
|
||||
|
||||
import android.app.DatePickerDialog;
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.RequiresApi;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.navigation.Navigation;
|
||||
|
||||
import com.skydoves.powerspinner.OnSpinnerDismissListener;
|
||||
import com.ssb.simplitend.R;
|
||||
import com.ssb.simplitend.apputils.AppUtil;
|
||||
import com.ssb.simplitend.databinding.RegisterFragmentBinding;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Locale;
|
||||
|
||||
public class RegisterFragment extends Fragment {
|
||||
|
||||
private static final String TAG = "RegisterFragment";
|
||||
|
||||
protected RegisterFragmentBinding binding;
|
||||
|
||||
public RegisterFragment(){
|
||||
public RegisterFragment() {
|
||||
// required empty const.
|
||||
}
|
||||
|
||||
@@ -26,11 +47,19 @@ public class RegisterFragment extends Fragment {
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
binding = RegisterFragmentBinding.inflate(inflater, container, false);
|
||||
|
||||
initViews();
|
||||
|
||||
clickEvents();
|
||||
|
||||
return binding.getRoot();
|
||||
}
|
||||
|
||||
private void initViews() {
|
||||
|
||||
loadCountryCodeDropDown();
|
||||
|
||||
}
|
||||
|
||||
private void clickEvents() {
|
||||
|
||||
binding.backBtn.setOnClickListener(v -> Navigation.findNavController(v).popBackStack());
|
||||
@@ -38,5 +67,102 @@ public class RegisterFragment extends Fragment {
|
||||
binding.nextBtn.setOnClickListener(v ->
|
||||
Navigation.findNavController(v).navigate(R.id.action_registerFragment_to_locationFragment));
|
||||
|
||||
binding.dob.setOnClickListener(v -> {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
AppUtil.closeKeyboard(requireActivity());
|
||||
pickDate();
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private void loadCountryCodeDropDown() {
|
||||
|
||||
ArrayList<String> countryCodeList = new ArrayList<>();
|
||||
|
||||
try {
|
||||
|
||||
String countryCodeStr = readCountryCodes(requireContext());
|
||||
JSONArray jsonArray = new JSONArray(countryCodeStr);
|
||||
|
||||
for (int i = 0; i < jsonArray.length(); i++) {
|
||||
|
||||
JSONObject code = jsonArray.getJSONObject(i);
|
||||
|
||||
countryCodeList.add(code.getString("dial_code"));
|
||||
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
|
||||
// if cannot load all country codes showing only india's dial code
|
||||
countryCodeList.add("+91");
|
||||
|
||||
Log.e(TAG, "loadCountryCodeDropDown: ", e);
|
||||
}
|
||||
|
||||
binding.countryCodes.setLifecycleOwner(this);
|
||||
|
||||
binding.countryCodes.setItems(countryCodeList);
|
||||
|
||||
binding.countryCodes.selectItemByIndex(countryCodeList.indexOf("+91"));
|
||||
|
||||
binding.countryCodes.setDismissWhenNotifiedItemSelected(true);
|
||||
|
||||
binding.countryCodes.setIsFocusable(true);
|
||||
|
||||
}
|
||||
|
||||
public String readCountryCodes(Context context) throws IOException {
|
||||
StringBuilder returnString = new StringBuilder();
|
||||
|
||||
InputStream fIn = context.getResources().openRawResource(R.raw.country_code);
|
||||
InputStreamReader isr = new InputStreamReader(fIn);
|
||||
BufferedReader input = new BufferedReader(isr);
|
||||
|
||||
String line = "";
|
||||
|
||||
while ((line = input.readLine()) != null) {
|
||||
returnString.append(line);
|
||||
}
|
||||
|
||||
try {
|
||||
isr.close();
|
||||
|
||||
if (fIn != null) fIn.close();
|
||||
|
||||
input.close();
|
||||
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "readCountryCodes: ", e);
|
||||
}
|
||||
|
||||
return returnString.toString();
|
||||
}
|
||||
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.N)
|
||||
private void pickDate() {
|
||||
|
||||
DatePickerDialog datePickerDialog = new DatePickerDialog(requireContext());
|
||||
|
||||
datePickerDialog.setOnDateSetListener((view, year, month, dayOfMonth) -> {
|
||||
setDOB(year, month, dayOfMonth);
|
||||
});
|
||||
|
||||
datePickerDialog.show();
|
||||
|
||||
}
|
||||
|
||||
private void setDOB(int year, int month, int dayOfMonth) {
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.set(Calendar.YEAR, year);
|
||||
cal.set(Calendar.MONTH, month);
|
||||
cal.set(Calendar.DAY_OF_MONTH, dayOfMonth);
|
||||
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("MM-dd-yyyy", Locale.getDefault());
|
||||
|
||||
String selected_time = sdf.format(cal.getTime());
|
||||
binding.dob.setText(selected_time);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
package com.ssb.simplitend.welcome.fragments.register;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.navigation.Navigation;
|
||||
|
||||
import com.ssb.simplitend.R;
|
||||
import com.ssb.simplitend.databinding.SplashFragmentBinding;
|
||||
|
||||
public class SplashFragment extends Fragment {
|
||||
|
||||
// view binding
|
||||
protected SplashFragmentBinding binding;
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
binding = SplashFragmentBinding.inflate(inflater, container, false);
|
||||
|
||||
new Handler().postDelayed(() -> {
|
||||
|
||||
Navigation.findNavController(binding.mainIcon).navigate(R.id.action_splashFragment_to_welcomeFragment);
|
||||
|
||||
}, 1000);
|
||||
|
||||
return binding.getRoot();
|
||||
}
|
||||
}
|
||||
@@ -11,10 +11,7 @@ import androidx.fragment.app.Fragment;
|
||||
import androidx.navigation.Navigation;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.bumptech.glide.load.engine.DiskCacheStrategy;
|
||||
import com.squareup.picasso.Picasso;
|
||||
import com.ssb.simplitend.R;
|
||||
import com.ssb.simplitend.databinding.LocationFragmentBinding;
|
||||
import com.ssb.simplitend.databinding.ThankYouFragmentBinding;
|
||||
|
||||
public class ThankYouFragment extends Fragment {
|
||||
@@ -39,6 +36,11 @@ public class ThankYouFragment extends Fragment {
|
||||
}
|
||||
|
||||
private void initializeViews(Bundle savedInstanceState) {
|
||||
// showing anim
|
||||
Glide.with(requireContext())
|
||||
.asGif()
|
||||
.load(R.raw.done_anim)
|
||||
.into(binding.animIv);
|
||||
}
|
||||
|
||||
private void clickEvents() {
|
||||
|
||||
Reference in New Issue
Block a user