Browse Source

feat: 👍 打卡逻辑完成

master
niushuai233 1 year ago
parent
commit
5c2db9a6a8
  1. 1
      app/build.gradle
  2. 136
      app/src/main/java/cc/niushuai/dididone/ui/calendar/CalendarFragment.java
  3. 134
      app/src/main/java/cc/niushuai/dididone/ui/component/ProjectPopupView.java
  4. 40
      app/src/main/res/layout/fragment_calendar.xml
  5. 30
      app/src/main/res/layout/project_popup_view.xml
  6. 23
      app/src/main/res/layout/project_popup_view_item.xml
  7. 2
      app/src/main/res/values/colors.xml

1
app/build.gradle

@ -73,6 +73,7 @@ dependencies {
implementation 'com.github.clans:fab:1.6.4' implementation 'com.github.clans:fab:1.6.4'
// //
implementation 'com.github.li-xiaojun:XPopup:2.9.19' implementation 'com.github.li-xiaojun:XPopup:2.9.19'
implementation 'com.github.li-xiaojun:EasyAdapter:1.2.9'
// hutool // hutool
implementation 'cn.hutool:hutool-core:5.0.7' implementation 'cn.hutool:hutool-core:5.0.7'

136
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.FloatingActionButton;
import com.github.clans.fab.FloatingActionMenu; 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.IconicsDrawable;
import com.mikepenz.iconics.view.IconicsImageView; import com.mikepenz.iconics.view.IconicsImageView;
import com.necer.calendar.BaseCalendar; import com.necer.calendar.BaseCalendar;
@ -29,6 +32,7 @@ import com.necer.utils.CalendarUtil;
import org.joda.time.LocalDate; import org.joda.time.LocalDate;
import org.reactivestreams.Subscription; import org.reactivestreams.Subscription;
import java.util.Collection;
import java.util.List; import java.util.List;
import cc.niushuai.dididone.R; 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.entity.Record;
import cc.niushuai.dididone.biz.roomx.DBManager; import cc.niushuai.dididone.biz.roomx.DBManager;
import cc.niushuai.dididone.databinding.FragmentCalendarBinding; import cc.niushuai.dididone.databinding.FragmentCalendarBinding;
import cc.niushuai.dididone.ui.component.ProjectPopupView;
import cc.niushuai.dididone.util.IntSnowflake; import cc.niushuai.dididone.util.IntSnowflake;
import cc.niushuai.dididone.util.Toasts; import cc.niushuai.dididone.util.Toasts;
import cc.niushuai.dididone.util.XLog; import cc.niushuai.dididone.util.XLog;
import cn.hutool.core.date.DatePattern; import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateTime; import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil; import cn.hutool.core.date.DateUtil;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import io.reactivex.Completable; import io.reactivex.Completable;
import io.reactivex.CompletableObserver; import io.reactivex.CompletableObserver;
@ -58,7 +64,7 @@ public class CalendarFragment extends Fragment {
private String lastDate; private String lastDate;
private List<Project> floatingActionProjectList; // private List<Project> floatingActionProjectList;
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
CalendarViewModel calendarViewModel = new ViewModelProvider(this).get(CalendarViewModel.class); CalendarViewModel calendarViewModel = new ViewModelProvider(this).get(CalendarViewModel.class);
@ -78,7 +84,9 @@ public class CalendarFragment extends Fragment {
// initPointList(); // initPointList();
// 构建弹出框内容 // 构建弹出框内容
fetchNewestActionButtonData(); // fetchNewestActionButtonData();
// check entry
} }
private void initPointList(List<String> pointList) { private void initPointList(List<String> pointList) {
@ -90,23 +98,61 @@ public class CalendarFragment extends Fragment {
// 日历选择变更事件 // 日历选择变更事件
addCalendarChangeListener(); addCalendarChangeListener();
// floatAction // floatAction
addFloatActionMenuToggleListener(); // addFloatActionMenuToggleListener();
//
addCheckEntryListener();
} }
private void addFloatActionMenuToggleListener() { private void addCheckEntryListener() {
binding.didiCheckMenu.setOnMenuToggleListener(new FloatingActionMenu.OnMenuToggleListener() {
binding.checkEntry.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onMenuToggle(boolean opened) { public void onClick(View v) {
if (opened) { // 按钮置灰
buildFloatActionButtons(floatingActionProjectList, getContext(), binding.didiCheckMenu); // binding.checkEntry.setImageDrawable(new IconicsDrawable(getContext())
} else { // .icon(CommunityMaterial.Icon.cmd_checkbox_marked_circle)
// 关闭时清除所有button // .color(getContext().getColor(R.color.black_less))
binding.didiCheckMenu.removeAllMenuButtons(); // .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<Project> floatingActionProjectList, Context context, FloatingActionMenu didiCheckMenu) { private void buildFloatActionButtons(List<Project> floatingActionProjectList, Context context, FloatingActionMenu didiCheckMenu) {
for (Project project : floatingActionProjectList) { for (Project project : floatingActionProjectList) {
@ -127,33 +173,7 @@ public class CalendarFragment extends Fragment {
didiCheckMenu.close(true); didiCheckMenu.close(true);
// 添加数据 // 添加数据
// tabsPagerAdapter.getHomeFragment().add2Top(CheckTypeEnum.QUICK_ADD, actionButton.getLabelText()); // 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) { private void add2Top(Project project, Record record) {
// 外层layout 白色背景 存在边距 // 外层layout 白色背景 存在边距
RelativeLayout itemLayout = new RelativeLayout(getContext()); RelativeLayout itemLayout = new RelativeLayout(getContext());
@ -291,9 +341,9 @@ public class CalendarFragment extends Fragment {
binding = null; binding = null;
} }
//
private void fetchNewestActionButtonData() { // private void fetchNewestActionButtonData() {
Flowable<List<Project>> listFlowable = DBManager.INSTANCE.projectDao().listAll(); // Flowable<List<Project>> listFlowable = DBManager.INSTANCE.projectDao().listAll();
listFlowable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(projectList -> floatingActionProjectList = projectList); // listFlowable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(projectList -> floatingActionProjectList = projectList);
} // }
} }

134
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<Project> data;
private EasyAdapter<Project> commonAdapter;
private Consumer<Project> callback;
public ProjectPopupView(@NonNull Context context) {
super(context);
}
public ProjectPopupView(@NonNull Context context, Consumer<Project> 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<Project>(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<Project> getProjectList() {
List<Project> 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);
}
}

40
app/src/main/res/layout/fragment_calendar.xml

@ -7,6 +7,7 @@
tools:context=".ui.calendar.CalendarFragment"> tools:context=".ui.calendar.CalendarFragment">
<LinearLayout <LinearLayout
android:id="@+id/linearLayout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:orientation="vertical"> android:orientation="vertical">
@ -16,8 +17,8 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:gravity="center" android:gravity="center"
android:textSize="15dp" android:padding="15dp"
android:padding="15dp" /> android:textSize="15dp" />
<com.necer.view.WeekBar <com.necer.view.WeekBar
android:layout_width="match_parent" android:layout_width="match_parent"
@ -46,8 +47,42 @@
</androidx.core.widget.NestedScrollView> </androidx.core.widget.NestedScrollView>
</com.necer.calendar.Miui10Calendar> </com.necer.calendar.Miui10Calendar>
</LinearLayout> </LinearLayout>
<ImageView
android:id="@+id/check_entry"
android:layout_width="85dp"
android:layout_height="85dp"
android:layout_marginRight="30dp"
android:layout_marginBottom="30dp"
android:elevation="10dp"
android:translationZ="10dp"
android:padding="10dp"
app:ico_color="@color/black"
app:ico_icon="cmd_checkbox_marked_circle"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
<!--
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/floatingActionButton"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_marginRight="30dp"
android:layout_marginBottom="30dp"
android:background="#00000000"
android:clickable="true"
android:padding="10dp"
android:src="@android:drawable/ic_input_add"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
-->
<!--
<com.github.clans.fab.FloatingActionMenu <com.github.clans.fab.FloatingActionMenu
android:id="@+id/didi_check_menu" android:id="@+id/didi_check_menu"
android:layout_width="wrap_content" android:layout_width="wrap_content"
@ -94,5 +129,6 @@
app:menu_shadowXOffset="1dp" app:menu_shadowXOffset="1dp"
app:menu_shadowYOffset="3dp" app:menu_shadowYOffset="3dp"
app:menu_showShadow="true"/> app:menu_showShadow="true"/>
-->
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

30
app/src/main/res/layout/project_popup_view.xml

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bg_miui10"
android:maxHeight="500dp"
android:orientation="vertical">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bg_miui10">
<TextView
android:id="@+id/ppv_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="20dp"
android:text="全部1314条打卡项"
android:textColor="#000"
android:textSize="20sp" />
</com.google.android.material.appbar.AppBarLayout>
<com.lxj.xpopup.widget.VerticalRecyclerView
android:id="@+id/ppv_recyclerView"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
</LinearLayout>

23
app/src/main/res/layout/project_popup_view_item.xml

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/ppv_item_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="20dp">
<ImageView
android:id="@+id/ppv_item_icon"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_centerVertical="true" />
<TextView
android:id="@+id/ppv_item_txt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="20dp"
android:layout_toRightOf="@id/ppv_item_icon"
android:textSize="14dp" />
</RelativeLayout>

2
app/src/main/res/values/colors.xml

@ -18,4 +18,6 @@
<color name="gray_light_less">#D1D1D1</color> <color name="gray_light_less">#D1D1D1</color>
<color name="gray_light">#E8E8E8</color> <color name="gray_light">#E8E8E8</color>
<color name="gray_light_more">#8DE8E8E8</color> <color name="gray_light_more">#8DE8E8E8</color>
<color name="check_btn">#69D5C4</color>
<color name="black_less">#92000000</color>
</resources> </resources>
Loading…
Cancel
Save