From 5c2db9a6a852d38b6bd2ddcaf9c6ba6e6be23dd5 Mon Sep 17 00:00:00 2001 From: niushuai233 Date: Tue, 16 Apr 2024 16:56:30 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20:+1:=20=E6=89=93=E5=8D=A1=E9=80=BB?= =?UTF-8?q?=E8=BE=91=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle | 1 + .../ui/calendar/CalendarFragment.java | 138 ++++++++++++------ .../ui/component/ProjectPopupView.java | 134 +++++++++++++++++ app/src/main/res/layout/fragment_calendar.xml | 130 +++++++++++------ .../main/res/layout/project_popup_view.xml | 30 ++++ .../res/layout/project_popup_view_item.xml | 23 +++ app/src/main/res/values/colors.xml | 2 + 7 files changed, 367 insertions(+), 91 deletions(-) create mode 100644 app/src/main/java/cc/niushuai/dididone/ui/component/ProjectPopupView.java create mode 100644 app/src/main/res/layout/project_popup_view.xml create mode 100644 app/src/main/res/layout/project_popup_view_item.xml diff --git a/app/build.gradle b/app/build.gradle index d53a8f1..fd11212 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -73,6 +73,7 @@ dependencies { implementation 'com.github.clans:fab:1.6.4' // 弹窗组件 implementation 'com.github.li-xiaojun:XPopup:2.9.19' + implementation 'com.github.li-xiaojun:EasyAdapter:1.2.9' // hutool 工具 implementation 'cn.hutool:hutool-core:5.0.7' diff --git a/app/src/main/java/cc/niushuai/dididone/ui/calendar/CalendarFragment.java b/app/src/main/java/cc/niushuai/dididone/ui/calendar/CalendarFragment.java index fd76211..73cf1a0 100644 --- a/app/src/main/java/cc/niushuai/dididone/ui/calendar/CalendarFragment.java +++ b/app/src/main/java/cc/niushuai/dididone/ui/calendar/CalendarFragment.java @@ -17,6 +17,9 @@ import androidx.lifecycle.ViewModelProvider; import com.github.clans.fab.FloatingActionButton; import com.github.clans.fab.FloatingActionMenu; +import com.lxj.xpopup.XPopup; +import com.lxj.xpopup.interfaces.OnSelectListener; +import com.mikepenz.community_material_typeface_library.CommunityMaterial; import com.mikepenz.iconics.IconicsDrawable; import com.mikepenz.iconics.view.IconicsImageView; import com.necer.calendar.BaseCalendar; @@ -29,6 +32,7 @@ import com.necer.utils.CalendarUtil; import org.joda.time.LocalDate; import org.reactivestreams.Subscription; +import java.util.Collection; import java.util.List; import cc.niushuai.dididone.R; @@ -37,12 +41,14 @@ import cc.niushuai.dididone.biz.entity.Project; import cc.niushuai.dididone.biz.entity.Record; import cc.niushuai.dididone.biz.roomx.DBManager; import cc.niushuai.dididone.databinding.FragmentCalendarBinding; +import cc.niushuai.dididone.ui.component.ProjectPopupView; import cc.niushuai.dididone.util.IntSnowflake; import cc.niushuai.dididone.util.Toasts; import cc.niushuai.dididone.util.XLog; import cn.hutool.core.date.DatePattern; import cn.hutool.core.date.DateTime; import cn.hutool.core.date.DateUtil; +import cn.hutool.core.thread.ThreadUtil; import cn.hutool.core.util.StrUtil; import io.reactivex.Completable; import io.reactivex.CompletableObserver; @@ -58,7 +64,7 @@ public class CalendarFragment extends Fragment { private String lastDate; - private List floatingActionProjectList; +// private List floatingActionProjectList; public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { CalendarViewModel calendarViewModel = new ViewModelProvider(this).get(CalendarViewModel.class); @@ -78,7 +84,9 @@ public class CalendarFragment extends Fragment { // initPointList(); // 构建弹出框内容 - fetchNewestActionButtonData(); +// fetchNewestActionButtonData(); + + // check entry } private void initPointList(List pointList) { @@ -90,23 +98,61 @@ public class CalendarFragment extends Fragment { // 日历选择变更事件 addCalendarChangeListener(); // floatAction - addFloatActionMenuToggleListener(); +// addFloatActionMenuToggleListener(); + + // + addCheckEntryListener(); + } - private void addFloatActionMenuToggleListener() { - binding.didiCheckMenu.setOnMenuToggleListener(new FloatingActionMenu.OnMenuToggleListener() { + private void addCheckEntryListener() { + + binding.checkEntry.setOnClickListener(new View.OnClickListener() { @Override - public void onMenuToggle(boolean opened) { - if (opened) { - buildFloatActionButtons(floatingActionProjectList, getContext(), binding.didiCheckMenu); - } else { - // 关闭时清除所有button - binding.didiCheckMenu.removeAllMenuButtons(); - } + public void onClick(View v) { + // 按钮置灰 +// binding.checkEntry.setImageDrawable(new IconicsDrawable(getContext()) +// .icon(CommunityMaterial.Icon.cmd_checkbox_marked_circle) +// .color(getContext().getColor(R.color.black_less)) +// .sizeDp(85) +// ); + + // 弹窗 + new XPopup.Builder(getContext()) + .hasShadowBg(true) + .isViewMode(true) + .isDestroyOnDismiss(true) + .asCustom(new ProjectPopupView(getContext(), project -> { + // item click callback + add2Top(project); + })) + .show(); + + // 还原按钮 +// binding.checkEntry.setImageDrawable(new IconicsDrawable(getContext()) +// .icon(CommunityMaterial.Icon.cmd_checkbox_marked_circle) +// .color(getContext().getColor(R.color.black)) +// .sizeDp(85) +// ); } }); + } +// private void addFloatActionMenuToggleListener() { +// binding.didiCheckMenu.setOnMenuToggleListener(new FloatingActionMenu.OnMenuToggleListener() { +// @Override +// public void onMenuToggle(boolean opened) { +// if (opened) { +// buildFloatActionButtons(floatingActionProjectList, getContext(), binding.didiCheckMenu); +// } else { +// // 关闭时清除所有button +// binding.didiCheckMenu.removeAllMenuButtons(); +// } +// } +// }); +// } + private void buildFloatActionButtons(List floatingActionProjectList, Context context, FloatingActionMenu didiCheckMenu) { for (Project project : floatingActionProjectList) { @@ -127,33 +173,7 @@ public class CalendarFragment extends Fragment { didiCheckMenu.close(true); // 添加数据 // tabsPagerAdapter.getHomeFragment().add2Top(CheckTypeEnum.QUICK_ADD, actionButton.getLabelText()); - Record record = new Record(); - record.setProjectId(project.getId()); - record.setName(project.getName()); - record.setCheckDate(DateUtil.parseDate(lastDate).getTime()); - - // 插入数据库 - Completable completable = DBManager.INSTANCE.recordDao().insertAll(record); - completable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new CompletableObserver() { - @Override - public void onSubscribe(Disposable d) { - } - - @Override - public void onComplete() { - XLog.i("[{}]打卡成功", project.getName()); - Toasts.shortShow(getActivity(), "[{}]打卡成功", project.getName()); - - // 更新视图 - add2Top(project, record); - } - - @Override - public void onError(Throwable e) { - XLog.e("[{}]打卡失败, {}", project.getName(), e); - Toasts.shortShow(getActivity(), "[{}]打卡失败, {}", project.getName(), e.getMessage()); - } - }); + } }); @@ -229,6 +249,36 @@ public class CalendarFragment extends Fragment { } + private void add2Top(Project project) { + Record record = new Record(); + record.setProjectId(project.getId()); + record.setName(project.getName()); + record.setCheckDate(DateUtil.parseDate(lastDate).getTime()); + + // 插入数据库 + Completable completable = DBManager.INSTANCE.recordDao().insertAll(record); + completable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new CompletableObserver() { + @Override + public void onSubscribe(Disposable d) { + } + + @Override + public void onComplete() { + XLog.i("[{}]打卡成功", project.getName()); + Toasts.shortShow(getActivity(), "[{}]打卡成功", project.getName()); + + // 更新视图 + add2Top(project, record); + } + + @Override + public void onError(Throwable e) { + XLog.e("[{}]打卡失败, {}", project.getName(), e); + Toasts.shortShow(getActivity(), "[{}]打卡失败, {}", project.getName(), e.getMessage()); + } + }); + } + private void add2Top(Project project, Record record) { // 外层layout 白色背景 存在边距 RelativeLayout itemLayout = new RelativeLayout(getContext()); @@ -291,9 +341,9 @@ public class CalendarFragment extends Fragment { binding = null; } - - private void fetchNewestActionButtonData() { - Flowable> listFlowable = DBManager.INSTANCE.projectDao().listAll(); - listFlowable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(projectList -> floatingActionProjectList = projectList); - } +// +// private void fetchNewestActionButtonData() { +// Flowable> listFlowable = DBManager.INSTANCE.projectDao().listAll(); +// listFlowable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(projectList -> floatingActionProjectList = projectList); +// } } \ No newline at end of file diff --git a/app/src/main/java/cc/niushuai/dididone/ui/component/ProjectPopupView.java b/app/src/main/java/cc/niushuai/dididone/ui/component/ProjectPopupView.java new file mode 100644 index 0000000..c8af590 --- /dev/null +++ b/app/src/main/java/cc/niushuai/dididone/ui/component/ProjectPopupView.java @@ -0,0 +1,134 @@ +package cc.niushuai.dididone.ui.component; + +import android.content.Context; +import android.graphics.Color; +import android.view.View; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.lxj.easyadapter.EasyAdapter; +import com.lxj.easyadapter.MultiItemTypeAdapter; +import com.lxj.easyadapter.ViewHolder; +import com.lxj.xpopup.core.BottomPopupView; +import com.lxj.xpopup.util.XPopupUtils; +import com.lxj.xpopup.widget.VerticalRecyclerView; +import com.mikepenz.iconics.IconicsDrawable; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import java.util.function.Consumer; + +import cc.niushuai.dididone.R; +import cc.niushuai.dididone.biz.BizGlobal; +import cc.niushuai.dididone.biz.entity.Project; +import cc.niushuai.dididone.util.Toasts; +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.StrUtil; + +public class ProjectPopupView extends BottomPopupView { + + private VerticalRecyclerView recyclerView; + private List data; + private EasyAdapter commonAdapter; + + private Consumer callback; + + + public ProjectPopupView(@NonNull Context context) { + super(context); + } + + public ProjectPopupView(@NonNull Context context, Consumer callback) { + super(context); + this.callback = callback; + } + + @Override + protected int getImplLayoutId() { + return R.layout.project_popup_view; + } + + @Override + protected void onCreate() { + super.onCreate(); + + recyclerView = findViewById(R.id.ppv_recyclerView); + data = getProjectList(); + int projectCount = data.size(); + + if (data.isEmpty()) { + Project e = new Project(); + e.setName("先去添加打卡项吧~"); + e.setIcon("cmd_alert_decagram_outline"); + e.setIconColor(Color.RED); + data.add(e); + projectCount = 0; + } + + ((TextView) findViewById(R.id.ppv_title)).setText(StrUtil.format("全部{}条打卡项", projectCount)); + commonAdapter = new EasyAdapter(data, R.layout.project_popup_view_item) { + @Override + protected void bind(@NonNull ViewHolder holder, @NonNull Project item, final int position) { + + Project project = data.get(position); + + ImageView iconView = holder.getView(R.id.ppv_item_icon); + iconView.setImageDrawable( + new IconicsDrawable(getContext()) + .icon(project.getIcon()) + .color(project.getIconColor()) + .sizeDp(50)); + + TextView txtView = holder.getView(R.id.ppv_item_txt); + txtView.setText(project.getName()); + } + }; + commonAdapter.setOnItemClickListener(new MultiItemTypeAdapter.OnItemClickListener() { + @Override + public void onItemClick(@NonNull View view, @NonNull RecyclerView.ViewHolder viewHolder, int position) { + + // 打卡 + callback.accept(data.get(position)); + + dismiss(); + } + + @Override + public boolean onItemLongClick(@NonNull View view, @NonNull RecyclerView.ViewHolder viewHolder, int position) { + return true; + } + }); + + recyclerView.setAdapter(commonAdapter); + } + + private void newRecord(Project project) { + + } + + private List getProjectList() { + List list = CollUtil.list(false, BizGlobal.CACHE_PROJECT.values()); + list.sort((e1, e2) -> e2.getCreateDate().compareTo(e1.getCreateDate())); + return list; + } + + + @Override + protected void onShow() { + super.onShow(); + } + + @Override + protected void onDismiss() { + super.onDismiss(); + } + + @Override + protected int getMaxHeight() { + return (int) (XPopupUtils.getScreenHeight(getContext()) * .5f); + } +} diff --git a/app/src/main/res/layout/fragment_calendar.xml b/app/src/main/res/layout/fragment_calendar.xml index 8220486..919798d 100644 --- a/app/src/main/res/layout/fragment_calendar.xml +++ b/app/src/main/res/layout/fragment_calendar.xml @@ -7,6 +7,7 @@ tools:context=".ui.calendar.CalendarFragment"> @@ -16,8 +17,8 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" - android:textSize="15dp" - android:padding="15dp" /> + android:padding="15dp" + android:textSize="15dp" /> + - + app:layout_constraintEnd_toEndOf="parent" /> + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/project_popup_view.xml b/app/src/main/res/layout/project_popup_view.xml new file mode 100644 index 0000000..af44a11 --- /dev/null +++ b/app/src/main/res/layout/project_popup_view.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/project_popup_view_item.xml b/app/src/main/res/layout/project_popup_view_item.xml new file mode 100644 index 0000000..ea6f178 --- /dev/null +++ b/app/src/main/res/layout/project_popup_view_item.xml @@ -0,0 +1,23 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 69699f9..8d0e58f 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -18,4 +18,6 @@ #D1D1D1 #E8E8E8 #8DE8E8E8 + #69D5C4 + #92000000 \ No newline at end of file