improve/all #161

Merged
Fujimatsu merged 47 commits from improve/all into main 2024-07-09 04:43:15 +00:00
18 changed files with 457 additions and 52 deletions

View File

@ -20,7 +20,6 @@ import androidx.drawerlayout.widget.DrawerLayout;
import androidx.fragment.app.FragmentManager;
import androidx.navigation.NavController;
import androidx.navigation.fragment.NavHostFragment;
import androidx.navigation.ui.AppBarConfiguration;
import androidx.navigation.ui.NavigationUI;
import com.google.android.material.bottomnavigation.BottomNavigationView;
@ -37,28 +36,29 @@ import one.nem.kidshift.feature.child.ChildManageMainActivity;
import one.nem.kidshift.utils.FabManager;
import one.nem.kidshift.utils.FeatureFlag;
import one.nem.kidshift.utils.KSLogger;
import one.nem.kidshift.utils.ToolBarManager;
import one.nem.kidshift.utils.factory.KSLoggerFactory;
@AndroidEntryPoint
public class MainActivity extends AppCompatActivity {
@Inject
KSLoggerFactory loggerFactory;
KSLoggerFactory ksLoggerFactory;
@Inject
FabManager fabManager;
@Inject
ToolBarManager toolBarManager;
@Inject
FeatureFlag featureFlag;
private KSLogger logger;
private FloatingActionButton fab;
@Inject
UserSettings userSettings;
private KSLogger logger;
private FloatingActionButton fab;
private Toolbar toolbar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@ -70,7 +70,7 @@ public class MainActivity extends AppCompatActivity {
return insets;
});
logger = loggerFactory.create("MainActivity");
logger = ksLoggerFactory.create("MainActivity");
// Check logged in
if (userSettings.getAppCommonSetting().isLoggedIn()) {
@ -82,8 +82,9 @@ public class MainActivity extends AppCompatActivity {
startActivity(intent);
}
Toolbar toolbar = findViewById(R.id.toolbar);
toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
toolBarManager.setToolbar(toolbar);
DrawerLayout drawerLayout = findViewById(R.id.drawerLayout);
@ -206,5 +207,8 @@ public class MainActivity extends AppCompatActivity {
return divider;
}
public Toolbar getToolbar() { // TODO: toolbarのインスタンス自体を取得するのではなくfabのように操作できるようにする
return toolbar;
}
}

View File

@ -4,14 +4,25 @@ import android.annotation.SuppressLint;
import android.graphics.Color;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.core.view.MenuHost;
import androidx.core.view.MenuProvider;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.TextView;
import android.widget.Toast;
import com.github.sundeepk.compactcalendarview.CompactCalendarView;
@ -20,6 +31,7 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.atomic.AtomicBoolean;
@ -35,6 +47,8 @@ import one.nem.kidshift.model.callback.TaskItemModelCallback;
import one.nem.kidshift.model.tasks.TaskItemModel;
import one.nem.kidshift.utils.FabManager;
import one.nem.kidshift.utils.KSLogger;
import one.nem.kidshift.utils.RecyclerViewAnimUtils;
import one.nem.kidshift.utils.ToolBarManager;
import one.nem.kidshift.utils.factory.KSLoggerFactory;
import one.nem.kidshift.utils.models.FabEventCallback;
@ -53,7 +67,11 @@ public class CommonHomeFragment extends Fragment {
@Inject
FabManager fabManager;
@Inject
ToolBarManager toolBarManager;
@Inject
RewardData rewardData;
@Inject
RecyclerViewAnimUtils recyclerViewAnimUtils;
private boolean isChildMode;
@ -63,6 +81,9 @@ public class CommonHomeFragment extends Fragment {
CompactCalendarView compactCalendarView;
SwipeRefreshLayout swipeRefreshLayout;
TaskListItemAdapter taskListItemAdapter;
TextView calendarTitleTextView;
ImageButton calendarPrevButton;
ImageButton calendarNextButton;
public CommonHomeFragment() {
// Required empty public constructor
@ -118,24 +139,99 @@ public class CommonHomeFragment extends Fragment {
RecyclerView taskListRecyclerView = view.findViewById(R.id.taskListRecyclerView);
taskListRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
taskListRecyclerView.setAdapter(taskListItemAdapter);
recyclerViewAnimUtils.setSlideUpAnimation(taskListRecyclerView);
swipeRefreshLayout = view.findViewById(R.id.swipeRefreshLayout);
swipeRefreshLayout.setOnRefreshListener(this::updateData);
calendarTitleTextView = view.findViewById(R.id.calendarTitleTextView);
calendarPrevButton = view.findViewById(R.id.calendarPrevButton);
calendarNextButton = view.findViewById(R.id.calendarNextButton);
initCalender();
MenuHost menuHost = requireActivity();
menuHost.addMenuProvider(new MenuProvider() {
@Override
public void onCreateMenu(@NonNull Menu menu, @NonNull MenuInflater menuInflater) {
menu.clear();
menuInflater.inflate(R.menu.common_home_toolbar_menu, menu);
}
@Override
public boolean onMenuItemSelected(@NonNull MenuItem menuItem) {
if (menuItem.getItemId() == R.id.toggle_calendar) {
View calendarContainer = view.findViewById(R.id.calendarContainer);
if (calendarContainer.getVisibility() == View.VISIBLE) {
Animation slideUp = AnimationUtils.loadAnimation(getContext(), one.nem.kidshift.shared.R.anim.slide_up);
calendarContainer.startAnimation(slideUp);
slideUp.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
recyclerViewRefresh();
}
@Override
public void onAnimationEnd(Animation animation) {
calendarContainer.setVisibility(View.GONE);
}
@Override
public void onAnimationRepeat(Animation animation) {
}
});
} else {
Animation slideDown = AnimationUtils.loadAnimation(getContext(), one.nem.kidshift.shared.R.anim.slide_down);
calendarContainer.startAnimation(slideDown);
slideDown.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
calendarContainer.setVisibility(View.VISIBLE);
recyclerViewRefresh();
}
@Override
public void onAnimationEnd(Animation animation) {
}
@Override
public void onAnimationRepeat(Animation animation) {
}
});
}
return true;
}
return false;
}
});
initCalender();
updateData();
return view;
}
private void recyclerViewRefresh() {
requireActivity().runOnUiThread(() -> {
taskListItemAdapter.notifyItemRangeRemoved(0, taskListItemAdapter.getItemCount());
taskListItemAdapter.notifyItemRangeInserted(0, taskListItemAdapter.getItemCount());
});
}
@Override
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
}
@Override
public void onResume() {
super.onResume();
updateData();
if (isChildMode) {
setupFabChild();
} else {
setupFabParent();
}
setupToolBar();
}
/**
@ -163,6 +259,15 @@ public class CommonHomeFragment extends Fragment {
fabManager.hide();
}
private void setupToolBar() {
if (isChildMode) {
toolBarManager.setTitle("タスク一覧");
} else {
toolBarManager.setTitle("ホーム");
}
}
/**
* タスク完了確認ダイアログを表示 (子供モード用)
*
@ -223,19 +328,25 @@ public class CommonHomeFragment extends Fragment {
return taskData.getTasks(new TaskItemModelCallback() {
@Override
public void onUnchanged() {
// Do nothing
}
@Override
public void onUpdated(List<TaskItemModel> taskItem) {
public void onUpdated(List<TaskItemModel> taskItem) { // Workaround
taskListItemAdapter.notifyItemRangeRemoved(0, taskListItemAdapter.getItemCount());
taskListItemAdapter.setTaskItemModelList(taskItem);
taskListItemAdapter.notifyItemRangeInserted(0, taskItem.size());
}
@Override
public void onFailed(String message) {
// TODO: ユーザーに丁寧に通知
Toast.makeText(requireContext(), "タスク情報の取得に失敗しました", Toast.LENGTH_SHORT).show(); // Workaround
}
}).thenAccept(taskItemModel -> {
taskListItemAdapter.setTaskItemModelList(taskItemModel);
requireActivity().runOnUiThread(() -> {
taskListItemAdapter.notifyDataSetChanged();
taskListItemAdapter.notifyItemRangeRemoved(0, taskListItemAdapter.getItemCount());
taskListItemAdapter.setTaskItemModelList(taskItemModel);
taskListItemAdapter.notifyItemRangeInserted(0, taskItemModel.size());
});
});
}
@ -266,9 +377,22 @@ public class CommonHomeFragment extends Fragment {
@Override
public void onMonthScroll(Date date) {
// Do nothing
// 0000年00月の形式に変換 getYear/getMonthは非推奨
calendarTitleTextView.setText(String.format("%d年%d月", date.getYear() + 1900, date.getMonth() + 1)); // 統合
}
});
// 初回
Date date = new Date();
calendarTitleTextView.setText(String.format("%d年%d月", date.getYear() + 1900, date.getMonth() + 1)); // 統合
calendarPrevButton.setOnClickListener(v -> {
compactCalendarView.scrollLeft();
});
calendarNextButton.setOnClickListener(v -> {
compactCalendarView.scrollRight();
});
}
/**
@ -277,12 +401,6 @@ public class CommonHomeFragment extends Fragment {
private void updateData() {
swipeRefreshLayout.setRefreshing(true);
CompletableFuture.allOf(updateTaskInfo(), updateCalender()).thenRun(() -> {
// Workaround: リスト更新処理があまりにも重くてアニメーションが壊れるため
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// do nothing
}
swipeRefreshLayout.setRefreshing(false);
});
}

View File

@ -19,7 +19,9 @@ import javax.inject.Inject;
import dagger.hilt.android.AndroidEntryPoint;
import one.nem.kidshift.data.ChildData;
import one.nem.kidshift.feature.common.adapter.SelectShowChildListItemAdapter;
import one.nem.kidshift.utils.FabManager;
import one.nem.kidshift.utils.KSLogger;
import one.nem.kidshift.utils.RecyclerViewAnimUtils;
import one.nem.kidshift.utils.factory.KSLoggerFactory;
@AndroidEntryPoint
@ -29,6 +31,10 @@ public class CommonSelectChildFragment extends Fragment {
KSLoggerFactory loggerFactory;
@Inject
ChildData childData;
@Inject
FabManager fabManager;
@Inject
RecyclerViewAnimUtils recyclerViewAnimUtils;
private KSLogger logger;
private SelectShowChildListItemAdapter adapter;
@ -51,21 +57,29 @@ public class CommonSelectChildFragment extends Fragment {
RecyclerView childListRecyclerView = view.findViewById(R.id.selectShowChildListRecyclerView);
childListRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
childData.getChildListDirect().thenAccept(childList -> {
adapter = new SelectShowChildListItemAdapter(childList);
adapter.setCallback(new SelectShowChildListItemAdapter.CompleteButtonClickedCallback() {
@Override
public void onClicked(String taskId) {
// Navigate to CommonHomeFragment with navigation controller and pass the selected child id
findNavController(view).navigate(CommonSelectChildFragmentDirections.actionCommonSelectChildFragmentToCommonHomeFragmentParentChild(taskId));
}
});
}).thenRun(() -> {
requireActivity().runOnUiThread(() -> {
childListRecyclerView.setAdapter(adapter);
});
recyclerViewAnimUtils.setSlideUpAnimation(childListRecyclerView);
adapter = new SelectShowChildListItemAdapter();
adapter.setCallback(taskId -> {
// 静的解析エラーが発生するのになぜか実行はできる
findNavController(view).navigate(CommonSelectChildFragmentDirections.actionCommonSelectChildFragmentToCommonHomeFragmentParentChild(taskId));
});
CompletableFuture.runAsync(() -> childListRecyclerView.setAdapter(adapter)).thenRun(() -> childData.getChildListDirect().thenAccept(childList -> {
requireActivity().runOnUiThread(() -> {
adapter.setChildDataList(childList);
adapter.notifyItemRangeChanged(0, childList.size());
});
}).exceptionally(e -> {
logger.error("Failed to load child list");
return null;
}));
return view;
}
@Override
public void onResume() {
super.onResume();
fabManager.hide();
}
}

View File

@ -11,22 +11,72 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.github.sundeepk.compactcalendarview.CompactCalendarView
android:id="@+id/calendar"
android:layout_width="fill_parent"
android:layout_height="250dp"
android:paddingLeft="10dp"
android:paddingRight="10dp"
app:compactCalendarBackgroundColor="#ffe95451"
app:compactCalendarCurrentDayBackgroundColor="#B71C1C"
app:compactCalendarCurrentSelectedDayBackgroundColor="#E57373"
app:compactCalendarMultiEventIndicatorColor="#fff"
app:compactCalendarTargetHeight="250dp"
app:compactCalendarTextColor="#fff"
app:compactCalendarTextSize="12sp"
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
app:layout_constraintTop_toTopOf="parent"
android:id="@+id/calendarContainer">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/colorSurface">
<ImageButton
android:id="@+id/calendarPrevButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@android:color/transparent"
android:src="@drawable/arrow_back_24px"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:tint="@color/colorOnSurface"
android:padding="8dp"/>
<TextView
android:id="@+id/calendarTitleTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/colorOnSurface"
android:textSize="20sp"
android:text="2000年1月"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/calendarNextButton"
app:layout_constraintStart_toEndOf="@+id/calendarPrevButton"
app:layout_constraintTop_toTopOf="parent"/>
<ImageButton
android:id="@+id/calendarNextButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@android:color/transparent"
android:src="@drawable/arrow_forward_24px"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:tint="@color/colorOnSurface"
android:padding="8dp"/>
</androidx.constraintlayout.widget.ConstraintLayout>
<com.github.sundeepk.compactcalendarview.CompactCalendarView
android:id="@+id/calendar"
android:layout_width="fill_parent"
android:layout_height="300dp"
android:paddingLeft="10dp"
android:paddingRight="10dp"
app:compactCalendarBackgroundColor="@color/colorSurface"
app:compactCalendarCurrentDayBackgroundColor="@color/colorSurfaceVariant"
app:compactCalendarCurrentSelectedDayBackgroundColor="@color/colorSurfaceVariant"
app:compactCalendarMultiEventIndicatorColor="@color/colorOnSurface"
app:compactCalendarTextColor="@color/colorOnSurface"
app:compactCalendarTextSize="12sp"/>
</LinearLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/taskListRecyclerView"
@ -35,7 +85,7 @@
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/calendar" />
app:layout_constraintTop_toBottomOf="@+id/calendarContainer" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/toggle_calendar"
android:icon="@drawable/calendar_month_24px"
app:showAsAction="ifRoom"
android:title="カレンダー表示切り替え" />
</menu>

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="700"
android:fillAfter="false"
>
<translate
android:interpolator="@android:anim/decelerate_interpolator"
android:fromXDelta="100%p"
android:toXDelta="0"
/>
<alpha
android:fromAlpha="0.5"
android:toAlpha="1"
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
/>
</set>

View File

@ -0,0 +1,11 @@
<set xmlns:android="http://schemas.android.com/apk/res/android">
<alpha
android:fromAlpha="0.0"
android:toAlpha="1.0"
android:duration="300"/>
<translate
android:fromYDelta="-50%"
android:toYDelta="0"
android:duration="300"
android:interpolator="@android:anim/accelerate_interpolator"/>
</set>

View File

@ -0,0 +1,11 @@
<set xmlns:android="http://schemas.android.com/apk/res/android">
<alpha
android:fromAlpha="1.0"
android:toAlpha="0.0"
android:duration="300"/>
<translate
android:fromYDelta="0"
android:toYDelta="-50%"
android:duration="300"
android:interpolator="@android:anim/decelerate_interpolator"/>
</set>

View File

@ -0,0 +1,11 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960"
android:tint="?attr/colorControlNormal"
android:autoMirrored="true">
<path
android:fillColor="@android:color/white"
android:pathData="M313,520L537,744L480,800L160,480L480,160L537,216L313,440L800,440L800,520L313,520Z"/>
</vector>

View File

@ -0,0 +1,11 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960"
android:tint="?attr/colorControlNormal"
android:autoMirrored="true">
<path
android:fillColor="@android:color/white"
android:pathData="M647,520L160,520L160,440L647,440L423,216L480,160L800,480L480,800L423,744L647,520Z"/>
</vector>

View File

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M200,880Q167,880 143.5,856.5Q120,833 120,800L120,240Q120,207 143.5,183.5Q167,160 200,160L240,160L240,80L320,80L320,160L640,160L640,80L720,80L720,160L760,160Q793,160 816.5,183.5Q840,207 840,240L840,800Q840,833 816.5,856.5Q793,880 760,880L200,880ZM200,800L760,800Q760,800 760,800Q760,800 760,800L760,400L200,400L200,800Q200,800 200,800Q200,800 200,800ZM200,320L760,320L760,240Q760,240 760,240Q760,240 760,240L200,240Q200,240 200,240Q200,240 200,240L200,320ZM200,320L200,240Q200,240 200,240Q200,240 200,240L200,240Q200,240 200,240Q200,240 200,240L200,320ZM480,560Q463,560 451.5,548.5Q440,537 440,520Q440,503 451.5,491.5Q463,480 480,480Q497,480 508.5,491.5Q520,503 520,520Q520,537 508.5,548.5Q497,560 480,560ZM320,560Q303,560 291.5,548.5Q280,537 280,520Q280,503 291.5,491.5Q303,480 320,480Q337,480 348.5,491.5Q360,503 360,520Q360,537 348.5,548.5Q337,560 320,560ZM640,560Q623,560 611.5,548.5Q600,537 600,520Q600,503 611.5,491.5Q623,480 640,480Q657,480 668.5,491.5Q680,503 680,520Q680,537 668.5,548.5Q657,560 640,560ZM480,720Q463,720 451.5,708.5Q440,697 440,680Q440,663 451.5,651.5Q463,640 480,640Q497,640 508.5,651.5Q520,663 520,680Q520,697 508.5,708.5Q497,720 480,720ZM320,720Q303,720 291.5,708.5Q280,697 280,680Q280,663 291.5,651.5Q303,640 320,640Q337,640 348.5,651.5Q360,663 360,680Q360,697 348.5,708.5Q337,720 320,720ZM640,720Q623,720 611.5,708.5Q600,697 600,680Q600,663 611.5,651.5Q623,640 640,640Q657,640 668.5,651.5Q680,663 680,680Q680,697 668.5,708.5Q657,720 640,720Z"/>
</vector>

View File

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M640,480L720,560L720,640L520,640L520,880L480,920L440,880L440,640L240,640L240,560L320,480L320,200L280,200L280,120L680,120L680,200L640,200L640,480ZM354,560L606,560L560,514L560,200L400,200L400,514L354,560ZM480,560L480,560L480,560L480,560L480,560L480,560Z"/>
</vector>

View File

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M680,120L680,200L640,200L640,527L560,447L560,200L400,200L400,287L313,200L280,167L280,167L280,120L680,120ZM480,920L440,880L440,640L240,640L240,560L320,480L320,434L56,168L112,112L848,848L790,904L526,640L520,640L520,880L480,920ZM354,560L446,560L402,516L400,514L354,560ZM480,367L480,367L480,367L480,367ZM402,516L402,516L402,516L402,516Z"/>
</vector>

View File

@ -0,0 +1,11 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960"
android:tint="?attr/colorControlNormal"
android:autoMirrored="true">
<path
android:fillColor="@android:color/white"
android:pathData="M200,840Q167,840 143.5,816.5Q120,793 120,760L120,200Q120,167 143.5,143.5Q167,120 200,120L480,120L480,200L200,200Q200,200 200,200Q200,200 200,200L200,760Q200,760 200,760Q200,760 200,760L480,760L480,840L200,840ZM640,680L585,622L687,520L360,520L360,440L687,440L585,338L640,280L840,480L640,680Z"/>
</vector>

View File

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M280,840L280,760L440,760L440,636Q391,625 352.5,594.5Q314,564 296,518Q221,509 170.5,452.5Q120,396 120,320L120,280Q120,247 143.5,223.5Q167,200 200,200L280,200L280,120L680,120L680,200L760,200Q793,200 816.5,223.5Q840,247 840,280L840,320Q840,396 789.5,452.5Q739,509 664,518Q646,564 607.5,594.5Q569,625 520,636L520,760L680,760L680,840L280,840ZM280,432L280,280L200,280L200,320Q200,358 222,388.5Q244,419 280,432ZM480,560Q530,560 565,525Q600,490 600,440L600,200L360,200L360,440Q360,490 395,525Q430,560 480,560ZM680,432Q716,419 738,388.5Q760,358 760,320L760,280L680,280L680,432ZM480,380Q480,380 480,380Q480,380 480,380L480,380L480,380L480,380Q480,380 480,380Q480,380 480,380Z"/>
</vector>

View File

@ -38,6 +38,8 @@ dependencies {
implementation libs.com.google.dagger.hilt.android
annotationProcessor libs.com.google.dagger.hilt.compiler
implementation 'jp.wasabeef:recyclerview-animators:4.0.2'
// Gson
implementation libs.gson
}

View File

@ -0,0 +1,51 @@
package one.nem.kidshift.utils;
import androidx.recyclerview.widget.RecyclerView;
import javax.inject.Inject;
import javax.inject.Singleton;
import jp.wasabeef.recyclerview.animators.FadeInAnimator;
import jp.wasabeef.recyclerview.animators.SlideInUpAnimator;
@Singleton
public class RecyclerViewAnimUtils {
@Inject
public RecyclerViewAnimUtils() {
}
// SlideUp
public void setSlideUpAnimation(RecyclerView recyclerView) {
recyclerView.setItemAnimator(new SlideInUpAnimator());
recyclerView.getItemAnimator().setAddDuration(300);
recyclerView.getItemAnimator().setRemoveDuration(100);
recyclerView.getItemAnimator().setMoveDuration(100);
recyclerView.getItemAnimator().setChangeDuration(100);
}
public void setSlideUpAnimation(RecyclerView recyclerView, int duration) {
recyclerView.setItemAnimator(new SlideInUpAnimator());
recyclerView.getItemAnimator().setAddDuration(duration);
recyclerView.getItemAnimator().setRemoveDuration(duration);
recyclerView.getItemAnimator().setMoveDuration(duration);
recyclerView.getItemAnimator().setChangeDuration(duration);
}
// Fade
public void setFadeAnimation(RecyclerView recyclerView) {
recyclerView.setItemAnimator(new FadeInAnimator());
recyclerView.getItemAnimator().setAddDuration(300);
recyclerView.getItemAnimator().setRemoveDuration(100);
recyclerView.getItemAnimator().setMoveDuration(100);
recyclerView.getItemAnimator().setChangeDuration(100);
}
public void setFadeAnimation(RecyclerView recyclerView, int duration) {
recyclerView.setItemAnimator(new FadeInAnimator());
recyclerView.getItemAnimator().setAddDuration(duration);
recyclerView.getItemAnimator().setRemoveDuration(duration);
recyclerView.getItemAnimator().setMoveDuration(duration);
recyclerView.getItemAnimator().setChangeDuration(duration);
}
}

View File

@ -0,0 +1,40 @@
package one.nem.kidshift.utils;
import androidx.appcompat.widget.Toolbar;
import javax.inject.Inject;
import javax.inject.Singleton;
@Singleton
public class ToolBarManager {
private Toolbar toolbar;
@Inject
public ToolBarManager() {
}
public void setToolbar(Toolbar toolbar) {
this.toolbar = toolbar;
}
private void checkToolbar() {
if (toolbar == null) {
throw new IllegalStateException("Toolbar is not set");
}
}
public void setTitle(String title) {
checkToolbar();
toolbar.setTitle(title);
}
public void setSubtitle(String subtitle) {
checkToolbar();
toolbar.setSubtitle(subtitle);
}
public Toolbar getToolbar() {
return toolbar;
}
}