Merge pull request 'feature/improve-history' (#168) from feature/improve-history into main
Reviewed-on: #168
This commit is contained in:
commit
bef4d02dae
|
@ -16,5 +16,7 @@ public interface RewardData {
|
|||
|
||||
CompletableFuture<List<HistoryModel>> getRewardHistoryList(String childId);
|
||||
|
||||
CompletableFuture<Void> payReward(String historyId);
|
||||
|
||||
CompletableFuture<Void> payReward(List<String> historyIds);
|
||||
}
|
||||
|
|
|
@ -159,7 +159,7 @@ public class KSActionsImpl implements KSActions {
|
|||
@Override
|
||||
public CompletableFuture<List<HistoryModel>> syncHistory(String childId) {
|
||||
CompletableFuture<HistoryListResponse> callHistoryApi = CompletableFuture.supplyAsync(() -> {
|
||||
Call<HistoryListResponse> call = kidShiftApiService.getHistory(childId);
|
||||
Call<HistoryListResponse> call = kidShiftApiService.getHistory(childId, true); // TODO: containPaidを引数に
|
||||
try {
|
||||
Response<HistoryListResponse> response = call.execute();
|
||||
if (!response.isSuccessful()) {
|
||||
|
|
|
@ -10,11 +10,13 @@ import one.nem.kidshift.data.ChildData;
|
|||
import one.nem.kidshift.data.KSActions;
|
||||
import one.nem.kidshift.data.RewardData;
|
||||
import one.nem.kidshift.data.UserSettings;
|
||||
import one.nem.kidshift.data.retrofit.KidShiftApiService;
|
||||
import one.nem.kidshift.data.room.utils.CacheWrapper;
|
||||
import one.nem.kidshift.model.ChildModel;
|
||||
import one.nem.kidshift.model.HistoryModel;
|
||||
import one.nem.kidshift.utils.KSLogger;
|
||||
import one.nem.kidshift.utils.factory.KSLoggerFactory;
|
||||
import retrofit2.Call;
|
||||
|
||||
public class RewardDataImpl implements RewardData {
|
||||
|
||||
|
@ -23,14 +25,15 @@ public class RewardDataImpl implements RewardData {
|
|||
private final CacheWrapper cacheWrapper;
|
||||
private final KSLogger logger;
|
||||
private final ChildData childData;
|
||||
|
||||
private final KidShiftApiService kidShiftApiService;
|
||||
|
||||
@Inject
|
||||
public RewardDataImpl(KSLoggerFactory ksLoggerFactory, CacheWrapper cacheWrapper, UserSettings userSettings, KSActions ksActions, ChildData childData) {
|
||||
public RewardDataImpl(KSLoggerFactory ksLoggerFactory, CacheWrapper cacheWrapper, UserSettings userSettings, KSActions ksActions, ChildData childData, KidShiftApiService kidShiftApiService) {
|
||||
this.userSettings = userSettings;
|
||||
this.ksActions = ksActions;
|
||||
this.cacheWrapper = cacheWrapper;
|
||||
this.childData = childData;
|
||||
this.kidShiftApiService = kidShiftApiService;
|
||||
this.logger = ksLoggerFactory.create("RewardDataImpl");
|
||||
}
|
||||
|
||||
|
@ -53,4 +56,30 @@ public class RewardDataImpl implements RewardData {
|
|||
public CompletableFuture<List<HistoryModel>> getRewardHistoryList(String childId) { // TODO: localCacheを使う
|
||||
return CompletableFuture.supplyAsync(() -> ksActions.syncHistory(childId).join());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> payReward(String historyId) {
|
||||
return CompletableFuture.runAsync(() -> {
|
||||
Call<Void> call = kidShiftApiService.payHistory(historyId, true);
|
||||
try {
|
||||
call.execute();
|
||||
} catch (Exception e) {
|
||||
logger.error("Failed to pay reward : " + e.getMessage());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> payReward(List<String> historyIds) {
|
||||
return CompletableFuture.runAsync(() -> {
|
||||
historyIds.forEach(historyId -> { // TODO: API側でリストに対応する
|
||||
Call<Void> call = kidShiftApiService.payHistory(historyId, true);
|
||||
try {
|
||||
call.execute();
|
||||
} catch (Exception e) {
|
||||
logger.error("Failed to pay reward : " + e.getMessage());
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -185,6 +185,9 @@ public interface KidShiftApiService {
|
|||
|
||||
@GET("/task/history/{childId}")
|
||||
@Headers(AuthorizationInterceptor.HEADER_PLACEHOLDER)
|
||||
Call<HistoryListResponse> getHistory(@Path("childId") String childId);
|
||||
Call<HistoryListResponse> getHistory(@Path("childId") String childId, @Query("containPaid") boolean containPaid);
|
||||
|
||||
@POST("/task/history/{historyId}/paid")
|
||||
@Headers(AuthorizationInterceptor.HEADER_PLACEHOLDER)
|
||||
Call<Void> payHistory(@Path("historyId") String historyId, @Query("isPaid") boolean isPaid);
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ public class HistoryModelConverter { // TODO: JavaDoc
|
|||
historyModel.setTaskId(historyResponse.getTaskId());
|
||||
historyModel.setChildId(historyResponse.getChildId());
|
||||
historyModel.setRegisteredAt(historyResponse.getRegisteredAt());
|
||||
historyModel.setPaid(historyResponse.isPaid());
|
||||
return historyModel;
|
||||
}
|
||||
|
||||
|
@ -28,6 +29,7 @@ public class HistoryModelConverter { // TODO: JavaDoc
|
|||
historyResponse.setTaskId(historyModel.getTaskId());
|
||||
historyResponse.setChildId(historyModel.getChildId());
|
||||
historyResponse.setRegisteredAt(historyModel.getRegisteredAt());
|
||||
historyResponse.setPaid(historyModel.isPaid());
|
||||
return historyResponse;
|
||||
}
|
||||
|
||||
|
|
|
@ -7,12 +7,14 @@ public class HistoryBaseItem {
|
|||
private String taskId;
|
||||
private String childId;
|
||||
private Date registeredAt;
|
||||
private boolean isPaid;
|
||||
|
||||
public HistoryBaseItem(String id, String taskId, String childId, Date registeredAt) {
|
||||
public HistoryBaseItem(String id, String taskId, String childId, Date registeredAt, boolean isPaid) {
|
||||
this.id = id;
|
||||
this.taskId = taskId;
|
||||
this.childId = childId;
|
||||
this.registeredAt = registeredAt;
|
||||
this.isPaid = isPaid;
|
||||
}
|
||||
|
||||
public HistoryBaseItem() {
|
||||
|
@ -49,4 +51,12 @@ public class HistoryBaseItem {
|
|||
public void setRegisteredAt(Date registeredAt) {
|
||||
this.registeredAt = registeredAt;
|
||||
}
|
||||
|
||||
public boolean isPaid() {
|
||||
return isPaid;
|
||||
}
|
||||
|
||||
public void setPaid(boolean isPaid) {
|
||||
this.isPaid = isPaid;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,253 @@
|
|||
package one.nem.kidshift.wallet;
|
||||
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import one.nem.kidshift.model.HistoryModel;
|
||||
|
||||
public class HistoryItemListAdapter extends RecyclerView.Adapter<HistoryItemListAdapter.ViewHolder> {
|
||||
|
||||
enum ViewType {
|
||||
WITH_HEADER(1),
|
||||
ITEM(0);
|
||||
|
||||
private final int value;
|
||||
|
||||
ViewType(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public int getValue() {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
public static class HistoryModelExtended extends HistoryModel {
|
||||
private boolean isChecked;
|
||||
|
||||
public boolean isChecked() {
|
||||
return isChecked;
|
||||
}
|
||||
|
||||
public void setChecked(boolean checked) {
|
||||
isChecked = checked;
|
||||
}
|
||||
|
||||
// add isChecked to the constructor
|
||||
public HistoryModelExtended() {
|
||||
super();
|
||||
isChecked = false;
|
||||
}
|
||||
|
||||
// copy constructor
|
||||
public HistoryModelExtended(HistoryModel historyModel) {
|
||||
super();
|
||||
this.setId(historyModel.getId());
|
||||
this.setPaid(historyModel.isPaid());
|
||||
this.setChildId(historyModel.getChildId());
|
||||
this.setRegisteredAt(historyModel.getRegisteredAt());
|
||||
this.setTaskId(historyModel.getTaskId());
|
||||
this.setTaskName(historyModel.getTaskName());
|
||||
this.setReward(historyModel.getReward());
|
||||
this.setChecked(false);
|
||||
}
|
||||
}
|
||||
|
||||
public static class HistoryModelExtendedList {
|
||||
private List<HistoryModelExtended> list;
|
||||
|
||||
public List<HistoryModelExtended> getList() {
|
||||
return list;
|
||||
}
|
||||
|
||||
public void setList(List<HistoryModelExtended> list) {
|
||||
this.list = list;
|
||||
}
|
||||
|
||||
// clear all checked items
|
||||
public void clearChecked() {
|
||||
for (HistoryModelExtended item : list) {
|
||||
item.setChecked(false);
|
||||
}
|
||||
}
|
||||
|
||||
// constructor
|
||||
public HistoryModelExtendedList() {
|
||||
list = new ArrayList<>();
|
||||
}
|
||||
}
|
||||
|
||||
public interface CheckBoxChangedCallback {
|
||||
void onCheckBoxChanged();
|
||||
}
|
||||
|
||||
public boolean hasChecked() {
|
||||
for (HistoryModelExtended historyModelExtended : historyDataList.getList()) {
|
||||
if (historyModelExtended.isChecked()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private HistoryModelExtendedList historyDataList;
|
||||
private CheckBoxChangedCallback callback;
|
||||
private boolean hideCheckBox; // for child mode
|
||||
|
||||
public void setHistoryDataList(List<HistoryModel> historyDataList) {
|
||||
this.historyDataList = new HistoryModelExtendedList();
|
||||
for (HistoryModel historyModel : historyDataList) {
|
||||
this.historyDataList.getList().add(new HistoryModelExtended(historyModel));
|
||||
}
|
||||
}
|
||||
|
||||
public void setCallback(CheckBoxChangedCallback callback) {
|
||||
this.callback = callback;
|
||||
}
|
||||
|
||||
public void setHideCheckBox(boolean hideCheckBox) {
|
||||
this.hideCheckBox = hideCheckBox;
|
||||
}
|
||||
|
||||
public List<HistoryModel> getCheckedHistoryDataList() {
|
||||
List<HistoryModel> checkedHistoryDataList = new ArrayList<>();
|
||||
for (HistoryModelExtended historyModelExtended : historyDataList.getList()) {
|
||||
if (historyModelExtended.isChecked()) {
|
||||
checkedHistoryDataList.add(historyModelExtended);
|
||||
}
|
||||
}
|
||||
return checkedHistoryDataList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemViewType(int position) {
|
||||
if (position == 0) {
|
||||
return ViewType.WITH_HEADER.getValue();
|
||||
} else {
|
||||
if (isFirstOfMonth(historyDataList.getList().get(position))) {
|
||||
return ViewType.WITH_HEADER.getValue();
|
||||
} else {
|
||||
return ViewType.ITEM.getValue();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public HistoryItemListAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
if (viewType == ViewType.WITH_HEADER.getValue()) {
|
||||
LinearLayout view = new LinearLayout(parent.getContext());
|
||||
|
||||
view.setOrientation(LinearLayout.VERTICAL);
|
||||
view.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
|
||||
|
||||
view.addView(LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_history_month_header, parent, false));
|
||||
view.addView(LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_history_list_item, parent, false));
|
||||
return new MonthHeaderViewHolder(view);
|
||||
} else {
|
||||
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_history_list_item, parent, false);
|
||||
return new ViewHolder(view);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull HistoryItemListAdapter.ViewHolder holder, int position) {
|
||||
HistoryModelExtended historyData = this.historyDataList.getList().get(position);
|
||||
if (historyData.isPaid() || hideCheckBox) {
|
||||
holder.historyItemCheckBox.setVisibility(View.GONE);
|
||||
} else {
|
||||
holder.historyItemCheckBox.setVisibility(View.VISIBLE);
|
||||
}
|
||||
holder.historyItemNameTextView.setText(historyData.getTaskName());
|
||||
holder.historyItemRewardTextView.setText(historyData.getReward() + "円");
|
||||
holder.historyItemCheckBox.setChecked(historyData.isChecked());
|
||||
holder.historyItemCheckBox.setOnCheckedChangeListener((buttonView, isChecked) -> {
|
||||
if (holder.historyItemCheckBox.isShown()) {
|
||||
historyData.setChecked(isChecked);
|
||||
callback.onCheckBoxChanged();
|
||||
}
|
||||
});
|
||||
if (holder instanceof MonthHeaderViewHolder) {
|
||||
// ((MonthHeaderViewHolder) holder).monthHeaderTextView.setText(historyData.getRegisteredAt().getMonth() + "月");
|
||||
// DEBUG: 月をまたぐデータがないので
|
||||
((MonthHeaderViewHolder) holder).monthHeaderTitle.setText(historyData.getRegisteredAt().getDate() + "日");
|
||||
((MonthHeaderViewHolder) holder).monthTotalTextView.setText(getMonthTotal(historyData) + "円");
|
||||
((MonthHeaderViewHolder) holder).checkAllButton.setOnClickListener(v -> {
|
||||
Toast.makeText(v.getContext(), "実装中", Toast.LENGTH_SHORT).show();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isFirstOfMonth(HistoryModel historyModel) {
|
||||
// 1個前の要素と比較して月が変わったかどうかを判定する
|
||||
if (historyDataList.getList().indexOf(historyModel) == 0) {
|
||||
return true;
|
||||
} else {
|
||||
HistoryModel previousHistoryModel = historyDataList.getList().get(historyDataList.getList().indexOf(historyModel) - 1);
|
||||
// getMonth()はDeprecated TODO: やめる
|
||||
// return historyModel.getRegisteredAt().getMonth() != previousHistoryModel.getRegisteredAt().getMonth();
|
||||
// DEBUG: 月をまたぐデータがないので
|
||||
return historyModel.getRegisteredAt().getDate() != previousHistoryModel.getRegisteredAt().getDate();
|
||||
}
|
||||
}
|
||||
|
||||
private int getMonthTotal(HistoryModel historyModel) {
|
||||
int total = historyModel.getReward();
|
||||
int index = historyDataList.getList().indexOf(historyModel) + 1;
|
||||
try {
|
||||
while (!isFirstOfMonth(this.historyDataList.getList().get(index))) {
|
||||
total += historyModel.getReward();
|
||||
index++;
|
||||
}
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
// 1個しかない場合 Workaround
|
||||
// TODO: 例外をひねり潰すのではなく,そもそも発生しないようにするべき
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return historyDataList == null ? 0 : historyDataList.getList().size();
|
||||
}
|
||||
|
||||
public static class ViewHolder extends RecyclerView.ViewHolder {
|
||||
TextView historyItemNameTextView;
|
||||
TextView historyItemRewardTextView;
|
||||
CheckBox historyItemCheckBox;
|
||||
public ViewHolder(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
historyItemNameTextView = itemView.findViewById(R.id.historyItemNameTextView);
|
||||
historyItemRewardTextView = itemView.findViewById(R.id.historyItemRewardTextView);
|
||||
historyItemCheckBox = itemView.findViewById(R.id.checkBox);
|
||||
}
|
||||
}
|
||||
|
||||
public static class MonthHeaderViewHolder extends HistoryItemListAdapter.ViewHolder {
|
||||
// かなり邪道な方法だけど,とりあえず取得できるので
|
||||
|
||||
TextView monthHeaderTitle;
|
||||
TextView monthTotalTextView;
|
||||
ImageButton checkAllButton;
|
||||
|
||||
public MonthHeaderViewHolder(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
monthHeaderTitle = itemView.findViewById(R.id.monthHeaderTitle);
|
||||
monthTotalTextView = itemView.findViewById(R.id.monthTotalTextView);
|
||||
checkAllButton = itemView.findViewById(R.id.checkAllButton);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -12,10 +12,15 @@ import dagger.hilt.android.AndroidEntryPoint;
|
|||
import one.nem.kidshift.data.KSActions;
|
||||
import one.nem.kidshift.data.RewardData;
|
||||
import one.nem.kidshift.data.UserSettings;
|
||||
import one.nem.kidshift.model.HistoryModel;
|
||||
import one.nem.kidshift.utils.FabManager;
|
||||
import one.nem.kidshift.utils.KSLogger;
|
||||
import one.nem.kidshift.utils.ToolBarManager;
|
||||
import one.nem.kidshift.utils.factory.KSLoggerFactory;
|
||||
import one.nem.kidshift.utils.models.FabEventCallback;
|
||||
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
|
||||
|
||||
@AndroidEntryPoint
|
||||
|
@ -41,6 +46,8 @@ public class WalletContentFragment extends Fragment {
|
|||
private TextView totalRewardTextView;
|
||||
private SwipeRefreshLayout swipeRefreshLayout;
|
||||
|
||||
private HistoryItemListAdapter historyItemListAdapter;
|
||||
|
||||
public WalletContentFragment() {
|
||||
// Required empty public constructor
|
||||
}
|
||||
|
@ -85,16 +92,76 @@ public class WalletContentFragment extends Fragment {
|
|||
swipeRefreshLayout = view.findViewById(R.id.swipeRefreshLayout);
|
||||
|
||||
swipeRefreshLayout.setOnRefreshListener(() -> {
|
||||
updateTotalReward();
|
||||
// updateTotalReward();
|
||||
updateItems();
|
||||
swipeRefreshLayout.setRefreshing(false);
|
||||
});
|
||||
|
||||
RecyclerView historyItemRecyclerView = view.findViewById(R.id.historyItemRecyclerView);
|
||||
historyItemListAdapter = new HistoryItemListAdapter();
|
||||
historyItemRecyclerView.setAdapter(historyItemListAdapter);
|
||||
historyItemRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext()));
|
||||
|
||||
historyItemListAdapter.setCallback(() -> {
|
||||
if (historyItemListAdapter.hasChecked()) {
|
||||
fabManager.show();
|
||||
initFab();
|
||||
} else {
|
||||
fabManager.hide();
|
||||
}
|
||||
});
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
private void initFab() {
|
||||
fabManager.setFabEventCallback(new FabEventCallback() {
|
||||
@Override
|
||||
public void onClicked() {
|
||||
historyItemListAdapter.getCheckedHistoryDataList().forEach(historyModel -> {
|
||||
rewardData.payReward(historyModel.getId()).thenRun(() -> {
|
||||
logger.debug("Paid reward: " + historyModel.getId());
|
||||
updateItems();
|
||||
}).exceptionally(throwable -> {
|
||||
logger.error("Failed to pay reward: " + throwable.getMessage());
|
||||
return null;
|
||||
});
|
||||
});
|
||||
|
||||
updateItems(); // workaround
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLongClicked() {
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
|
||||
updateItems();
|
||||
}
|
||||
|
||||
private void updateItems() {
|
||||
swipeRefreshLayout.setRefreshing(true);
|
||||
rewardData.getRewardHistoryList(childId).thenAccept(historyList -> {
|
||||
historyItemListAdapter.setHistoryDataList(historyList);
|
||||
// totalRewardTextView.setText(String.valueOf(historyList.stream().mapToInt(HistoryModel::getReward).sum()) + "円");
|
||||
requireActivity().runOnUiThread(() -> {
|
||||
historyItemListAdapter.notifyDataSetChanged();
|
||||
totalRewardTextView.setText(String.valueOf(historyList.stream().filter(HistoryModel::isPaid).mapToInt(HistoryModel::getReward).sum()) + "円");
|
||||
});
|
||||
}).thenRun(() -> {
|
||||
requireActivity().runOnUiThread(() -> {
|
||||
swipeRefreshLayout.setRefreshing(false);
|
||||
});
|
||||
}).exceptionally(throwable -> {
|
||||
logger.error("Failed to get history list: " + throwable.getMessage());
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
private void updateTotalReward() {
|
||||
|
@ -110,13 +177,22 @@ public class WalletContentFragment extends Fragment {
|
|||
logger.error("Failed to get total reward: " + throwable.getMessage());
|
||||
return null;
|
||||
});
|
||||
|
||||
rewardData.getRewardHistoryList(childId).thenAccept(historyList -> { // test
|
||||
historyItemListAdapter.setHistoryDataList(historyList);
|
||||
historyItemListAdapter.notifyDataSetChanged();
|
||||
}).exceptionally(throwable -> {
|
||||
logger.error("Failed to get history list: " + throwable.getMessage());
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
updateTotalReward();
|
||||
fabManager.hide();
|
||||
// updateTotalReward();
|
||||
// updateItems();
|
||||
// fabManager.hide();
|
||||
toolBarManager.setTitle("ウォレット");
|
||||
toolBarManager.setSubtitle(null);
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ import dagger.hilt.android.AndroidEntryPoint;
|
|||
import one.nem.kidshift.data.ChildData;
|
||||
import one.nem.kidshift.data.RewardData;
|
||||
import one.nem.kidshift.model.ChildModel;
|
||||
import one.nem.kidshift.model.callback.ChildModelCallback;
|
||||
import one.nem.kidshift.utils.FabManager;
|
||||
import one.nem.kidshift.utils.KSLogger;
|
||||
import one.nem.kidshift.utils.ToolBarManager;
|
||||
|
@ -51,6 +52,7 @@ public class WalletParentWrapperFragment extends Fragment {
|
|||
|
||||
private TabLayout tabLayout;
|
||||
private ViewPager2 viewPager;
|
||||
private TabAdapter tabAdapter;
|
||||
|
||||
public WalletParentWrapperFragment() {
|
||||
// Required empty public constructor
|
||||
|
@ -70,22 +72,50 @@ public class WalletParentWrapperFragment extends Fragment {
|
|||
tabLayout = view.findViewById(R.id.tabLayout);
|
||||
viewPager = view.findViewById(R.id.viewPager);
|
||||
|
||||
TabAdapter tabAdapter = new TabAdapter(requireActivity());
|
||||
|
||||
// デバッグ用
|
||||
List<ChildModel> childList = childData.getChildListDirect().join();
|
||||
tabAdapter.setChildList(childList);
|
||||
tabAdapter = new TabAdapter(requireActivity());
|
||||
|
||||
viewPager.setAdapter(tabAdapter);
|
||||
|
||||
new TabLayoutMediator(tabLayout, viewPager, (tab, position) -> {
|
||||
tab.setText(childList.get(position).getName());
|
||||
}).attach();
|
||||
|
||||
setupViewPager();
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
private void setupViewPager() {
|
||||
|
||||
// デバッグ用
|
||||
childData.getChildList(new ChildModelCallback() {
|
||||
@Override
|
||||
public void onUnchanged() {
|
||||
// TODO: impl
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdated(List<ChildModel> childModelList) {
|
||||
// TODO: impl
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailed(String message) {
|
||||
// TODO: impl
|
||||
}
|
||||
}).thenAccept(childModels -> {
|
||||
|
||||
// childData.getChildListDirect().thenAccept(childModels -> {
|
||||
|
||||
tabAdapter.setChildList(childModels);
|
||||
requireActivity().runOnUiThread(() -> {
|
||||
|
||||
tabAdapter.notifyDataSetChanged();
|
||||
|
||||
new TabLayoutMediator(tabLayout, viewPager, (tab, position) -> {
|
||||
tab.setText(childModels.get(position).getName());
|
||||
}).attach();
|
||||
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private static class TabAdapter extends FragmentStateAdapter {
|
||||
|
||||
private List<ChildModel> childList;
|
||||
|
|
|
@ -16,9 +16,12 @@
|
|||
android:id="@+id/frameLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="24dp"
|
||||
android:layout_marginBottom="24dp"
|
||||
android:background="@color/colorSurface"
|
||||
android:backgroundTintMode="add"
|
||||
android:elevation="16px"
|
||||
app:layout_constraintBottom_toTopOf="@+id/historyItemRecyclerView"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<LinearLayout
|
||||
|
@ -32,6 +35,7 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:text="今月の支払い総額"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Display1"
|
||||
android:textColor="@color/colorOnSurface"
|
||||
android:textSize="20sp" />
|
||||
|
||||
<TextView
|
||||
|
@ -40,7 +44,8 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:text="0000円"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Display2" />
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Display2"
|
||||
android:textColor="@color/colorOnSurface" />
|
||||
</LinearLayout>
|
||||
</FrameLayout>
|
||||
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="32px">
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/checkBox"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="12dp"
|
||||
android:layout_marginEnd="12dp"
|
||||
android:layout_marginBottom="12dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16px"
|
||||
android:orientation="vertical"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/historyItemNameTextView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="TextView"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Medium" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/historyItemRewardTextView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="TextView"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Small" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -0,0 +1,48 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingHorizontal="48px"
|
||||
android:paddingVertical="24px">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/linearLayout"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/monthHeaderTitle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="ふが月"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Display1" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/monthTotalTextView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="0000000円"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Medium" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/checkAllButton"
|
||||
style="@style/Widget.AppCompat.ImageButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@android:color/transparent"
|
||||
android:padding="24px"
|
||||
android:tint="@color/colorOnBackground"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:srcCompat="@drawable/done_all_24px" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -9,14 +9,16 @@ public class HistoryModel {
|
|||
private String childId;
|
||||
private Date registeredAt;
|
||||
private int reward;
|
||||
private boolean isPaid;
|
||||
|
||||
public HistoryModel(String id, String taskId, String taskName, String childId, Date registeredAt, int reward) {
|
||||
public HistoryModel(String id, String taskId, String taskName, String childId, Date registeredAt, int reward, boolean isPaid) {
|
||||
this.id = id;
|
||||
this.taskId = taskId;
|
||||
this.taskName = taskName;
|
||||
this.childId = childId;
|
||||
this.registeredAt = registeredAt;
|
||||
this.reward = reward;
|
||||
this.isPaid = isPaid;
|
||||
}
|
||||
|
||||
public HistoryModel(String id, String taskId, String childId, Date registeredAt) { // 他モデルとのマージが必要なので
|
||||
|
@ -76,4 +78,12 @@ public class HistoryModel {
|
|||
public void setReward(int reward) {
|
||||
this.reward = reward;
|
||||
}
|
||||
|
||||
public boolean isPaid() {
|
||||
return isPaid;
|
||||
}
|
||||
|
||||
public void setPaid(boolean isPaid) {
|
||||
this.isPaid = isPaid;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user