Преглед на файлове

增加学生端我的课程列表小组课tab页

Pq преди 8 месеца
родител
ревизия
8a7f5b1fee

+ 100 - 0
student/src/main/java/com/cooleshow/student/adapter/GroupCourseListAdapter.java

@@ -0,0 +1,100 @@
+package com.cooleshow.student.adapter;
+
+import android.text.TextUtils;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import com.chad.library.adapter.base.BaseQuickAdapter;
+import com.chad.library.adapter.base.module.BaseLoadMoreModule;
+import com.chad.library.adapter.base.module.LoadMoreModule;
+import com.chad.library.adapter.base.viewholder.BaseViewHolder;
+import com.cooleshow.base.constanst.CourseGroupStatusType;
+import com.cooleshow.base.utils.GlideUtils;
+import com.cooleshow.base.utils.StringUtils;
+import com.cooleshow.base.utils.TimeUtils;
+import com.cooleshow.base.utils.UiUtils;
+import com.cooleshow.student.R;
+import com.cooleshow.student.bean.LiveCourseListBean;
+import com.cooleshow.student.constants.CourseConstants;
+
+import androidx.annotation.NonNull;
+
+/**
+ * Author by pq, Date on 2022/4/25.
+ */
+public class GroupCourseListAdapter extends BaseQuickAdapter<LiveCourseListBean.RowsBean, BaseViewHolder> implements LoadMoreModule {
+
+    public GroupCourseListAdapter() {
+        super(R.layout.item_group_course_list_layout);
+        addChildClickViewIds(R.id.iv_chat);
+    }
+
+    @Override
+    protected void convert(@NonNull BaseViewHolder holder, LiveCourseListBean.RowsBean data) {
+        if (data == null) {
+            return;
+        }
+
+        String timeStr = TextUtils.isEmpty(data.startTime) ? "" : TimeUtils.date2String(TimeUtils.string2Date(data.startTime), "yyyy-MM-dd HH:mm");
+        //时间
+        holder.setText(R.id.tv_time, "开课时间:" + timeStr);
+        //title
+        holder.setText(R.id.tv_title, data.name);
+        //subjectName
+        holder.setText(R.id.tv_course_name, data.subjectName);
+        //购买人数
+        holder.setText(R.id.tv_buy_num, data.payCount + "人学习");
+        //头像
+        ImageView iv_bg = holder.getView(R.id.iv_bg);
+        GlideUtils.INSTANCE.loadImage(getContext(), data.cover, iv_bg, com.cooleshow.base.R.drawable.bg_video_placeholder);
+        //老师名称
+        String courseIntroduce = data.getCourseIntroduce();
+        if (TextUtils.isEmpty(courseIntroduce)) {
+            courseIntroduce = "暂无介绍";
+        }
+        courseIntroduce = StringUtils.replaceSpace(courseIntroduce);
+        holder.setText(R.id.tv_des, courseIntroduce);
+
+        String tip = "";
+        TextView tvCourseStatusBt = holder.getView(R.id.tv_course_status);
+        if (TextUtils.equals(CourseConstants.COURSE_STATUS_NOT_START, data.status)) {
+            //未开始
+            holder.setText(R.id.tv_course_status, CourseGroupStatusType.NOT_START.getValue());
+            tvCourseStatusBt.setTextColor(getContext().getResources().getColor(com.cooleshow.base.R.color.color_ff802c));
+            tip = String.format("剩余%d个名额", data.getMaxStudentNum() - data.getStudentCount());
+        }
+
+        if (TextUtils.equals(CourseConstants.COURSE_STATUS_ING, data.status)) {
+            //进行中
+            holder.setText(R.id.tv_course_status, CourseGroupStatusType.ING.getValue());
+            tvCourseStatusBt.setTextColor(getContext().getResources().getColor(com.cooleshow.base.R.color.color_2dc7aa));
+            tip = UiUtils.getBuyNumTip2("", String.valueOf(data.studentCount));
+        }
+
+        if (TextUtils.equals(CourseConstants.COURSE_STATUS_COMPLETE, data.status)) {
+            //已结束
+            holder.setText(R.id.tv_course_status, CourseGroupStatusType.COMPLETE.getValue());
+            tvCourseStatusBt.setTextColor(getContext().getResources().getColor(com.cooleshow.base.R.color.color_999999));
+            tip = UiUtils.getBuyNumTip2("", String.valueOf(data.studentCount));
+        }
+        //购买人数
+        holder.setText(R.id.tv_buy_num, tip);
+
+        //已上课时
+        holder.setText(R.id.tv_course_completed_value, data.getCompleteCourseNum());
+        //总课时
+        holder.setText(R.id.tv_course_total_value, data.getCourseNum());
+
+        //老师头像昵称
+        ImageView iv_avatar = holder.getView(R.id.iv_avatar);
+        GlideUtils.INSTANCE.loadImage(getContext(), data.getAvatar(), iv_avatar, R.drawable.icon_teacher_default_head);
+        TextView tv_teacher_name = holder.getView(R.id.tv_teacher_name);
+        tv_teacher_name.setText(data.realName);
+    }
+
+    @NonNull
+    @Override
+    public BaseLoadMoreModule addLoadMoreModule(@NonNull BaseQuickAdapter<?, ?> baseQuickAdapter) {
+        return new BaseLoadMoreModule(baseQuickAdapter);
+    }
+}

+ 18 - 0
student/src/main/java/com/cooleshow/student/bean/LiveCourseListBean.java

@@ -106,6 +106,24 @@ public class LiveCourseListBean {
         public String courseNum;
         public String completeCourseNum;
         public String teacherName;
+        public int maxStudentNum;
+        public int studentCount;
+
+        public int getStudentCount() {
+            return studentCount;
+        }
+
+        public void setStudentCount(int studentCount) {
+            this.studentCount = studentCount;
+        }
+
+        public int getMaxStudentNum() {
+            return maxStudentNum;
+        }
+
+        public void setMaxStudentNum(int maxStudentNum) {
+            this.maxStudentNum = maxStudentNum;
+        }
 
         public String getTeacherName() {
             return teacherName;

+ 20 - 0
student/src/main/java/com/cooleshow/student/contract/GroupCourseContract.java

@@ -0,0 +1,20 @@
+package com.cooleshow.student.contract;
+
+import com.cooleshow.base.presenter.view.BaseView;
+import com.cooleshow.student.bean.LiveCourseListBean;
+
+/**
+ * Author by pq, Date on 2022/4/20.
+ */
+public interface GroupCourseContract {
+
+    interface CourseView extends BaseView {
+        void onGetLiveCourseSuccess(int page, LiveCourseListBean liveCourseListBean);
+
+        void onGetCourseError(int page);
+
+    }
+
+    interface Presenter {
+    }
+}

+ 62 - 0
student/src/main/java/com/cooleshow/student/presenter/course/GroupCoursePresenter.java

@@ -0,0 +1,62 @@
+package com.cooleshow.student.presenter.course;
+
+import android.text.TextUtils;
+
+import com.cooleshow.base.constanst.Constants;
+import com.cooleshow.base.constanst.CourseType;
+import com.cooleshow.base.presenter.BasePresenter;
+import com.cooleshow.base.rx.BaseObserver;
+import com.cooleshow.base.utils.RequestBodyUtil;
+import com.cooleshow.student.api.APIService;
+import com.cooleshow.student.bean.LiveCourseListBean;
+import com.cooleshow.student.contract.GroupCourseContract;
+import com.cooleshow.student.contract.LiveCourseContract;
+import com.cooleshow.usercenter.helper.UserHelper;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+/**
+ * 陪练课presenter
+ * Author by pq, Date on 2022/4/20.
+ */
+public class GroupCoursePresenter extends BasePresenter<GroupCourseContract.CourseView> implements GroupCourseContract.Presenter {
+
+    public void queryGroupCourse(boolean isShowLoading, String status, String subjectId, String search, int page) {
+        if (isShowLoading && getView() != null) {
+            getView().showLoading();
+        }
+        JSONObject jsonObject = new JSONObject();
+        try {
+            if (!TextUtils.isEmpty(status)) {
+                jsonObject.putOpt("courseState", status);
+            }
+            if (!TextUtils.isEmpty(subjectId)) {
+                jsonObject.putOpt("subjectId", subjectId);
+            }
+            jsonObject.putOpt("search", search);
+            jsonObject.putOpt("page", page);
+            jsonObject.putOpt("courseType", CourseType.GROUP.getId());
+            jsonObject.putOpt("rows", Constants.DEFAULT_DATA_SIZE);
+            jsonObject.putOpt("studentId", UserHelper.getUserId());
+        } catch (JSONException e) {
+            e.printStackTrace();
+        }
+        addSubscribe(create(APIService.class).getLiveCourses(RequestBodyUtil.convertToRequestBodyJson(jsonObject.toString())), new BaseObserver<LiveCourseListBean>(getView()) {
+            @Override
+            protected void onSuccess(LiveCourseListBean data) {
+                if (getView() != null) {
+                    getView().onGetLiveCourseSuccess(page, data);
+                }
+            }
+
+            @Override
+            public void onError(Throwable e) {
+                super.onError(e);
+                if (getView() != null) {
+                    getView().onGetCourseError(page);
+                }
+            }
+        });
+    }
+}

+ 2 - 0
student/src/main/java/com/cooleshow/student/presenter/course/LiveCoursePresenter.java

@@ -3,6 +3,7 @@ package com.cooleshow.student.presenter.course;
 import android.text.TextUtils;
 
 import com.cooleshow.base.constanst.Constants;
+import com.cooleshow.base.constanst.CourseType;
 import com.cooleshow.base.presenter.BasePresenter;
 import com.cooleshow.base.rx.BaseObserver;
 import com.cooleshow.base.utils.RequestBodyUtil;
@@ -37,6 +38,7 @@ public class LiveCoursePresenter extends BasePresenter<LiveCourseContract.LiveCo
                 jsonObject.putOpt("subjectId", subjectId);
             }
             jsonObject.putOpt("search", search);
+            jsonObject.putOpt("courseType", CourseType.LIVE.getId());
             jsonObject.putOpt("page", page);
             jsonObject.putOpt("rows", Constants.DEFAULT_DATA_SIZE);
             jsonObject.putOpt("studentId", UserHelper.getUserId());

+ 304 - 0
student/src/main/java/com/cooleshow/student/ui/course/GroupCourseGroupFragment.java

@@ -0,0 +1,304 @@
+package com.cooleshow.student.ui.course;
+
+import android.text.TextUtils;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.PopupWindow;
+
+import com.alibaba.android.arouter.launcher.ARouter;
+import com.chad.library.adapter.base.BaseQuickAdapter;
+import com.chad.library.adapter.base.listener.OnItemChildClickListener;
+import com.cooleshow.base.common.WebConstants;
+import com.cooleshow.base.constanst.Constants;
+import com.cooleshow.base.constanst.CourseGroupStatusType;
+import com.cooleshow.base.interfaces.IFilterViewData;
+import com.cooleshow.base.router.RouterPath;
+import com.cooleshow.base.ui.fragment.BaseMVPFragment;
+import com.cooleshow.base.utils.LOG;
+import com.cooleshow.base.utils.PopupUtil;
+import com.cooleshow.base.utils.SizeUtils;
+import com.cooleshow.base.utils.UiUtils;
+import com.cooleshow.base.utils.helper.QMUIDeviceHelper;
+import com.cooleshow.base.widgets.CourseGroupFilterView;
+import com.cooleshow.base.widgets.EmptyViewLayout;
+import com.cooleshow.base.widgets.GridItemDecoration;
+import com.cooleshow.chatmodule.utils.helper.ChatHelper;
+import com.cooleshow.student.R;
+import com.cooleshow.student.adapter.GroupCourseListAdapter;
+import com.cooleshow.student.adapter.LiveCourseListAdapter;
+import com.cooleshow.student.bean.LiveCourseListBean;
+import com.cooleshow.student.bean.QuerySubjectBean;
+import com.cooleshow.student.constants.CourseConstants;
+import com.cooleshow.student.contract.GroupCourseContract;
+import com.cooleshow.student.contract.LiveCourseContract;
+import com.cooleshow.student.databinding.FragmentGroupCourseLayoutBinding;
+import com.cooleshow.student.databinding.FragmentLiveCourseLayoutBinding;
+import com.cooleshow.student.presenter.course.GroupCoursePresenter;
+import com.cooleshow.student.presenter.course.LiveCoursePresenter;
+import com.scwang.smart.refresh.footer.ClassicsFooter;
+import com.scwang.smart.refresh.layout.api.RefreshLayout;
+import com.scwang.smart.refresh.layout.listener.OnRefreshListener;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.GridLayoutManager;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+
+/**
+ * Author by pq, Date on 2022/4/25.
+ */
+public class GroupCourseGroupFragment extends BaseMVPFragment<FragmentGroupCourseLayoutBinding, GroupCoursePresenter> implements GroupCourseContract.CourseView, View.OnClickListener {
+    private String currentCourseFilterStatus = CourseConstants.COURSE_FILTER_ALL;
+    private String currentSubjectId;
+    private String searchCondition;
+    private int currentPage;
+    private GroupCourseListAdapter mAdapter;
+    private EmptyViewLayout mEmptyView;
+    private ArrayList<IFilterViewData> mCourseFilterStatusBeans;
+    private List<IFilterViewData> subjectBeanList = new ArrayList<>();
+    private boolean hasNext = true;
+    private CourseGroupFilterView mCourseGroupFilterView;
+    private PopupWindow mPopupWindow;
+
+    @Override
+    protected FragmentGroupCourseLayoutBinding getLayoutView() {
+        return FragmentGroupCourseLayoutBinding.inflate(getLayoutInflater());
+    }
+
+    @Override
+    protected GroupCoursePresenter createPresenter() {
+        return new GroupCoursePresenter();
+    }
+
+    @Override
+    protected void initView(View rootView) {
+        mViewBinding.refreshLayout.setRefreshFooter(new ClassicsFooter(getContext()));
+    }
+
+
+    @Override
+    public void onResume() {
+        super.onResume();
+    }
+
+    private void buildDefaultCourseStatusFilterList() {
+        CourseGroupStatusType[] values = CourseGroupStatusType.values();
+        List<CourseGroupStatusType> courseGroupStatusTypes = Arrays.asList(values);
+        mCourseFilterStatusBeans = new ArrayList<IFilterViewData>(courseGroupStatusTypes);
+    }
+
+    private void reBuildFilter(String status, String subjectId) {
+        if (!TextUtils.isEmpty(currentCourseFilterStatus) &&
+                !TextUtils.isEmpty(currentSubjectId) &&
+                TextUtils.equals(currentCourseFilterStatus, status) &&
+                TextUtils.equals(currentSubjectId, subjectId)) {
+            //防止重复条件触发
+            return;
+        }
+        currentCourseFilterStatus = !TextUtils.isEmpty(status) ? status : CourseConstants.COURSE_FILTER_ALL;
+        GroupCourseGroupFragment.this.currentSubjectId = subjectId;
+        currentPage = 1;
+        getData(true);
+    }
+
+    @Override
+    protected void initData() {
+        mAdapter = new GroupCourseListAdapter();
+        initListener();
+        if (mEmptyView == null) {
+            mEmptyView = new EmptyViewLayout(getContext());
+        }
+        mEmptyView.setContent(com.cooleshow.base.R.drawable.icon_empty_course, "暂无课程~");
+        mAdapter.setEmptyView(mEmptyView);
+//        mAdapter.getLoadMoreModule().setEnableLoadMoreIfNotFullPage(false);
+        RecyclerView.LayoutManager layoutManager;
+        if(QMUIDeviceHelper.isTablet(getContext())){
+            layoutManager = new GridLayoutManager(getContext(),2);
+            GridItemDecoration itemDecoration =new GridItemDecoration(2,0,0, SizeUtils.dp2px(6));
+            mViewBinding.recyclerViewList.addItemDecoration(itemDecoration);
+        }else{
+            layoutManager =new LinearLayoutManager(getContext());
+        }
+        mViewBinding.recyclerViewList.setLayoutManager(layoutManager);
+        mViewBinding.recyclerViewList.setAdapter(mAdapter);
+        buildDefaultCourseStatusFilterList();
+        reBuildFilter(CourseConstants.COURSE_FILTER_ALL, null);
+    }
+
+    private void initListener() {
+        mViewBinding.tvFilter.setOnClickListener(this);
+        mViewBinding.tvSearch.setOnClickListener(this);
+        mViewBinding.refreshLayout.setOnRefreshListener(new OnRefreshListener() {
+            @Override
+            public void onRefresh(@NonNull RefreshLayout refreshLayout) {
+                currentPage = 1;
+                getData(true);
+            }
+        });
+
+        mViewBinding.refreshLayout.setOnLoadMoreListener(new com.scwang.smart.refresh.layout.listener.OnLoadMoreListener() {
+            @Override
+            public void onLoadMore(@NonNull RefreshLayout refreshLayout) {
+                //上拉加载
+                if (hasNext) {
+                    currentPage++;
+                    getData(false);
+                } else {
+                    mViewBinding.refreshLayout.finishLoadMoreWithNoMoreData();
+                }
+            }
+        });
+
+        mAdapter.setOnItemClickListener((adapter, view, position) -> {
+            LiveCourseListBean.RowsBean item = (LiveCourseListBean.RowsBean) adapter.getItem(position);
+//            ARouter.getInstance()
+//                    .build(RouterPath.WebCenter.ACTIVITY_HTML)
+//                    .withString(WebConstants.WEB_URL, String.format(WebConstants.TEACHER_LIVE_DETAIL_NORMAL_COURSE, item.courseGoupId, item.courseId))
+//                    .navigation();
+        });
+        mAdapter.setOnItemChildClickListener(new OnItemChildClickListener() {
+            @Override
+            public void onItemChildClick(@NonNull BaseQuickAdapter<?, ?> adapter, @NonNull View view, int position) {
+                int id = view.getId();
+                if (id == R.id.iv_chat) {
+                    LiveCourseListBean.RowsBean item = (LiveCourseListBean.RowsBean) adapter.getItem(position);
+                    if (item != null) {
+                        ChatHelper.getInstance().goGroupChat(item.imGroupId, "");
+                    }
+                }
+            }
+        });
+    }
+
+
+    private void getData(boolean isShowLoading) {
+        //根据默认筛选条件查询
+        if (currentPage == 1) {
+            mViewBinding.refreshLayout.resetNoMoreData();
+        }
+        presenter.queryGroupCourse(isShowLoading, currentCourseFilterStatus, currentSubjectId, searchCondition, currentPage);
+    }
+
+    private void checkHasNext(int dataSize) {
+        hasNext = dataSize >= Constants.DEFAULT_DATA_SIZE;
+        mViewBinding.refreshLayout.setNoMoreData(!hasNext);
+    }
+
+
+    @Override
+    public void onGetLiveCourseSuccess(int page, LiveCourseListBean dataList) {
+        if (isDetached()) {
+            return;
+        }
+        LOG.i("pq", "onGetLiveCourseSuccess:" + dataList);
+        if (dataList != null) {
+            if (page == 1) {
+                //第一页
+                mViewBinding.refreshLayout.finishRefresh();
+                if (mAdapter != null) {
+                    mAdapter.getData().clear();
+                    mAdapter.notifyDataSetChanged();
+                    if (dataList.getRows() != null && dataList.getRows().size() > 0) {
+                        checkHasNext(dataList.getRows().size());
+                        mAdapter.setNewInstance(dataList.getRows());
+                    }
+                }
+            } else {
+                //加载更多
+                if (mAdapter != null) {
+                    if (dataList.getRows() != null && dataList.getRows().size() > 0) {
+                        mViewBinding.refreshLayout.finishLoadMore();
+                        checkHasNext(dataList.getRows().size());
+                        mAdapter.addData(dataList.getRows());
+                    } else {
+                        mViewBinding.refreshLayout.finishLoadMoreWithNoMoreData();
+                    }
+                }
+            }
+        }
+    }
+
+    @Override
+    public void onGetCourseError(int page) {
+        if (isDetached()) {
+            return;
+        }
+        if (page == 1) {
+            mViewBinding.refreshLayout.finishRefresh();
+        } else {
+            if (mAdapter != null) {
+                currentPage--;
+                mViewBinding.refreshLayout.finishLoadMore(false);
+            }
+        }
+    }
+
+    @Override
+    public void onClick(View v) {
+        int id = v.getId();
+        if (id == R.id.tv_filter) {
+            //筛选
+            showFilterView();
+            return;
+        }
+
+        if (id == R.id.tv_search) {
+            currentPage = 1;
+            searchCondition = mViewBinding.etTargetName.getText().toString().trim();
+            getData(false);
+            return;
+        }
+    }
+
+
+    private void showFilterView() {
+        if (mCourseGroupFilterView == null) {
+            mCourseGroupFilterView = new CourseGroupFilterView(getContext());
+            mCourseGroupFilterView.setOnEventListener(new CourseGroupFilterView.OnEventListener() {
+                @Override
+                public void onDismiss() {
+                    if (mPopupWindow != null) {
+                        mPopupWindow.dismiss();
+                    }
+                }
+
+                @Override
+                public void onQuery(String obj, String obj2) {
+                    if (mPopupWindow != null) {
+                        mPopupWindow.dismiss();
+                    }
+                    currentPage = 1;
+                    reBuildFilter(obj, obj2);
+                }
+            });
+        }
+        mCourseGroupFilterView.setData(mCourseFilterStatusBeans, subjectBeanList);
+        ViewGroup parent = (ViewGroup) mCourseGroupFilterView.getParent();
+        if (parent != null) {
+            parent.removeView(mCourseGroupFilterView);
+        }
+        mPopupWindow = PopupUtil.showInDropWrapNObg(getContext(), mCourseGroupFilterView, mViewBinding.viewTopLine, new PopupUtil.ShowListener() {
+            @Override
+            public void onShow(View view, PopupWindow popupWindow) {
+                UiUtils.refreshFilterTextStyle(true, mViewBinding.tvFilter);
+            }
+        });
+        mPopupWindow.setOnDismissListener(new PopupWindow.OnDismissListener() {
+            @Override
+            public void onDismiss() {
+                UiUtils.refreshFilterTextStyle(false, mViewBinding.tvFilter);
+            }
+        });
+    }
+
+
+    public void querySubjectItemSuccess(List<QuerySubjectBean> data) {
+        subjectBeanList.clear();
+        subjectBeanList.add(new QuerySubjectBean("全部", ""));
+        subjectBeanList.addAll(data);
+    }
+}

+ 8 - 2
student/src/main/java/com/cooleshow/student/ui/course/MineCourseActivity.java

@@ -44,7 +44,7 @@ public class MineCourseActivity extends BaseMVPActivity<ActivityMineCourseBindin
 
     private TabLayout tabLayout;
     private ViewPager2 viewPager;
-    private List<String> titles = new ArrayList<String>(Arrays.asList("VIP定制课","趣纠课", "直播课", "视频课", "琴房课"));
+    private List<String> titles = new ArrayList<String>(Arrays.asList("VIP定制课", "趣纠课", "小组课", "直播课", "视频课", "琴房课"));
     private List<BaseMVPFragment> fragments = new ArrayList<>();
     private LiveCourseGroupFragment mLiveCourseFragment;
     private VideoCourseGroupFragment mVideoCourseFragment;
@@ -53,6 +53,7 @@ public class MineCourseActivity extends BaseMVPActivity<ActivityMineCourseBindin
     private CourseTipDialog mCourseTipDialog;
     private VIPCourseGroupFragment mVipCourseGroupFragment;
     private InterestCourseGroupFragment mInterestCourseGroupFragment;
+    private GroupCourseGroupFragment mGroupCourseGroupFragment;
 
     @Override
     protected void initView() {
@@ -113,8 +114,10 @@ public class MineCourseActivity extends BaseMVPActivity<ActivityMineCourseBindin
         mLiveCourseFragment = new LiveCourseGroupFragment();
         mVideoCourseFragment = new VideoCourseGroupFragment();
         mPianoRoomCourseFragment = new PianoCourseGroupFragment();
+        mGroupCourseGroupFragment = new GroupCourseGroupFragment();
         fragments.add(mVipCourseGroupFragment);
         fragments.add(mInterestCourseGroupFragment);
+        fragments.add(mGroupCourseGroupFragment);
         fragments.add(mLiveCourseFragment);
         fragments.add(mVideoCourseFragment);
         fragments.add(mPianoRoomCourseFragment);
@@ -124,7 +127,7 @@ public class MineCourseActivity extends BaseMVPActivity<ActivityMineCourseBindin
         viewPager.setOffscreenPageLimit(fragments.size());
     }
 
-    private void initListener(){
+    private void initListener() {
         viewBinding.tablayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
             @Override
             public void onTabSelected(TabLayout.Tab tab) {
@@ -192,6 +195,9 @@ public class MineCourseActivity extends BaseMVPActivity<ActivityMineCourseBindin
         if (mInterestCourseGroupFragment != null) {
             mInterestCourseGroupFragment.querySubjectItemSuccess(data);
         }
+        if (mGroupCourseGroupFragment != null) {
+            mGroupCourseGroupFragment.querySubjectItemSuccess(data);
+        }
         if (mLiveCourseFragment != null) {
             mLiveCourseFragment.querySubjectItemSuccess(data);
         }

+ 112 - 0
student/src/main/res/layout/fragment_group_course_layout.xml

@@ -0,0 +1,112 @@
+<?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"
+    android:layout_width="match_parent"
+    android:paddingTop="10dp"
+    android:layout_height="match_parent">
+
+    <TextView
+        android:id="@+id/tv_filter"
+        android:layout_width="wrap_content"
+        android:layout_height="0dp"
+        android:drawableRight="@drawable/icon_arrow_down"
+        android:drawablePadding="6dp"
+        android:ellipsize="end"
+        android:gravity="center"
+        android:includeFontPadding="false"
+        android:maxLength="6"
+        android:maxLines="1"
+        android:paddingStart="13dp"
+        android:paddingEnd="8dp"
+        android:text="筛选"
+        android:textColor="@color/color_333333"
+        android:textSize="@dimen/sp_14"
+        app:layout_constraintBottom_toBottomOf="@+id/view_search_bg"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintTop_toTopOf="@+id/view_search_bg" />
+
+    <View
+        android:id="@+id/view_search_bg"
+        android:layout_width="0dp"
+        android:layout_height="34dp"
+        android:layout_marginEnd="14dp"
+        android:background="@drawable/bg_white_18dp"
+        app:layout_constraintLeft_toRightOf="@+id/tv_filter"
+        app:layout_constraintRight_toRightOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
+
+    <ImageView
+        android:id="@+id/iv_search_icon"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="12dp"
+        android:src="@drawable/icon_search"
+        app:layout_constraintBottom_toBottomOf="@+id/view_search_bg"
+        app:layout_constraintLeft_toLeftOf="@+id/view_search_bg"
+        app:layout_constraintTop_toTopOf="@+id/view_search_bg" />
+
+    <com.cooleshow.base.widgets.ClearEditText
+        android:id="@+id/et_target_name"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:layout_marginEnd="5dp"
+        android:background="@null"
+        android:ellipsize="end"
+        android:hint="@string/mine_course_search_tip"
+        android:includeFontPadding="false"
+        android:maxLines="1"
+        android:paddingStart="8dp"
+        android:textColorHint="@color/color_66000000"
+        android:textColor="@color/color_333333"
+        android:textCursorDrawable="@drawable/shape_2dc7aa_1dp"
+        android:textSize="@dimen/sp_14"
+        android:theme="@style/MyEditText"
+        app:layout_constraintBottom_toBottomOf="@+id/view_search_bg"
+        app:layout_constraintLeft_toRightOf="@+id/iv_search_icon"
+        app:layout_constraintRight_toLeftOf="@+id/tv_search"
+        app:layout_constraintTop_toTopOf="@+id/view_search_bg" />
+
+    <TextView
+        android:id="@+id/tv_search"
+        android:layout_width="56dp"
+        android:layout_height="28dp"
+        android:layout_marginEnd="3dp"
+        android:background="@drawable/shape_1ecdac_18dp"
+        android:gravity="center"
+        android:includeFontPadding="false"
+        android:text="搜索"
+        android:textColor="@color/white"
+        android:textSize="@dimen/sp_14"
+        app:layout_constraintBottom_toBottomOf="@+id/view_search_bg"
+        app:layout_constraintRight_toRightOf="@+id/view_search_bg"
+        app:layout_constraintTop_toTopOf="@+id/view_search_bg" />
+
+    <View
+        android:layout_marginTop="12dp"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/view_search_bg"
+        android:id="@+id/view_top_line"
+        android:layout_width="match_parent"
+        android:layout_height="1px"/>
+
+    <com.scwang.smart.refresh.layout.SmartRefreshLayout
+        android:id="@+id/refreshLayout"
+        android:layout_width="match_parent"
+        android:layout_height="0dp"
+        app:layout_constraintRight_toRightOf="parent"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/view_top_line"
+        app:srlEnableLoadMore="true">
+
+        <androidx.recyclerview.widget.RecyclerView
+            android:id="@+id/recyclerView_list"
+            android:layout_marginEnd="14dp"
+            android:layout_marginStart="14dp"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:overScrollMode="never"
+            android:scrollbars="none" />
+    </com.scwang.smart.refresh.layout.SmartRefreshLayout>
+
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 285 - 0
student/src/main/res/layout/item_group_course_list_layout.xml

@@ -0,0 +1,285 @@
+<?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:layout_marginBottom="12dp"
+    android:background="@drawable/bg_white_10dp"
+    android:paddingStart="12dp"
+    android:paddingEnd="12dp"
+    android:paddingBottom="14dp">
+
+    <TextView
+        android:drawableStart="@drawable/icon_live_course_time_tag"
+        android:id="@+id/tv_time"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="12dp"
+        android:includeFontPadding="false"
+        android:textColor="@color/color_333333"
+        android:textSize="@dimen/sp_14"
+        android:textStyle="bold"
+        android:drawablePadding="6dp"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintTop_toTopOf="parent"
+        tools:text="开课时间:2024-11-16 09:30" />
+    <TextView
+        android:id="@+id/tv_course_status"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:textColor="@color/color_999999"
+        android:textSize="@dimen/sp_14"
+        app:layout_constraintBottom_toBottomOf="@+id/tv_time"
+        app:layout_constraintRight_toRightOf="parent"
+        app:layout_constraintTop_toTopOf="@+id/tv_time"
+        tools:text="未开始" />
+
+
+    <com.cooleshow.base.widgets.QMUIRadiusImageView
+        android:id="@+id/iv_bg"
+        android:layout_width="0dp"
+        app:layout_constraintDimensionRatio="h,16:9"
+        app:layout_constraintRight_toRightOf="parent"
+        android:layout_height="0dp"
+        android:layout_marginTop="12dp"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/tv_time"
+        app:qmui_corner_radius="6dp" />
+
+    <TextView
+        android:id="@+id/tv_course_name"
+        android:layout_width="wrap_content"
+        android:layout_height="@dimen/dp_19"
+        android:layout_marginTop="8dp"
+        android:layout_marginStart="@dimen/dp_8"
+        android:background="@drawable/shape_66000000_3dp"
+        android:gravity="center"
+        android:includeFontPadding="false"
+        android:paddingStart="@dimen/dp_6"
+        android:paddingEnd="@dimen/dp_6"
+        android:textColor="@color/white"
+        android:textSize="@dimen/sp_12"
+        app:layout_constraintTop_toTopOf="@+id/iv_bg"
+        app:layout_constraintLeft_toLeftOf="@+id/iv_bg"
+        tools:text="单簧管" />
+
+    <TextView
+        android:visibility="gone"
+        android:id="@+id/tv_course_status_tip"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:background="@drawable/shape_ffe7e7_15dp_left"
+        android:gravity="center"
+        android:paddingStart="12dp"
+        android:paddingTop="3dp"
+        android:paddingEnd="12dp"
+        android:paddingBottom="3dp"
+        android:text="销售中"
+        android:textColor="@color/color_ff1919"
+        android:textSize="@dimen/sp_10"
+        app:layout_constraintBottom_toBottomOf="@+id/tv_course_name"
+        app:layout_constraintRight_toRightOf="@+id/iv_bg"
+        app:layout_constraintTop_toTopOf="@+id/tv_course_name" />
+
+
+    <TextView
+        android:id="@+id/tv_title"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:ellipsize="end"
+        android:includeFontPadding="false"
+        android:maxLines="1"
+        android:textColor="@color/color_1a1a1a"
+        android:textSize="@dimen/sp_16"
+        android:textStyle="bold"
+        android:layout_marginTop="8dp"
+        app:layout_constraintLeft_toLeftOf="@+id/iv_bg"
+        app:layout_constraintRight_toRightOf="@+id/iv_bg"
+        app:layout_constraintTop_toBottomOf="@+id/iv_bg"
+        app:layout_constraintVertical_chainStyle="packed"
+        tools:text="张豆张豆豆豆" />
+
+    <TextView
+        android:id="@+id/tv_des"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:ellipsize="end"
+        android:includeFontPadding="false"
+        android:maxLines="1"
+        android:textColor="@color/color_777777"
+        android:textSize="@dimen/sp_14"
+        android:layout_marginTop="4dp"
+        app:layout_constraintLeft_toLeftOf="@+id/iv_bg"
+        app:layout_constraintRight_toRightOf="@+id/iv_bg"
+        app:layout_constraintTop_toBottomOf="@+id/tv_title"
+        tools:text="国际著名长笛演奏家、教育家子珊女士为您讲教育家子珊女士为您讲教育家子珊女士为您讲" />
+
+    <TextView
+        android:id="@+id/tv_buy_num"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:background="@drawable/shape_12ff802c_2dp"
+        android:textColor="@color/color_ff6827"
+        android:textSize="@dimen/sp_12"
+        android:visibility="visible"
+        android:paddingStart="4dp"
+        android:paddingEnd="4dp"
+        android:paddingTop="3dp"
+        android:paddingBottom="3dp"
+        tools:visibility="visible"
+        android:layout_marginEnd="5dp"
+        app:layout_constraintRight_toLeftOf="@+id/iv_course_tag"
+        app:layout_constraintBottom_toBottomOf="@+id/tv_teacher_name"
+        app:layout_constraintTop_toTopOf="@+id/tv_teacher_name"
+        app:layout_constraintLeft_toRightOf="@+id/tv_teacher_name"
+        android:includeFontPadding="false"
+        tools:text="6人已购买" />
+
+
+    <de.hdodenhof.circleimageview.CircleImageView
+        android:id="@+id/iv_avatar"
+        android:layout_width="20dp"
+        android:layout_height="20dp"
+        app:layout_constraintBottom_toBottomOf="@+id/tv_teacher_name"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintTop_toTopOf="@+id/tv_teacher_name" />
+
+    <TextView
+        app:layout_constraintHorizontal_chainStyle="packed"
+        app:layout_constraintRight_toLeftOf="@+id/tv_buy_num"
+        android:id="@+id/tv_teacher_name"
+        android:layout_width="0dp"
+        android:maxLines="1"
+        android:ellipsize="end"
+        android:layout_marginEnd="5dp"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="11dp"
+        android:includeFontPadding="false"
+        android:paddingStart="6dp"
+        android:textColor="@color/color_333333"
+        android:textSize="@dimen/sp_13"
+        android:visibility="visible"
+        app:layout_constraintHorizontal_bias="0"
+        app:layout_constraintWidth_default="wrap"
+        app:layout_constraintLeft_toRightOf="@+id/iv_avatar"
+        app:layout_constraintTop_toBottomOf="@+id/tv_des"
+        tools:text="严老师严严老师严严老师严严老师严严老师严严老师严严老师严严老师严严老师严严老师严严老师严" />
+
+    <TextView
+        android:visibility="gone"
+        android:id="@+id/tv_price"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="120"
+        android:paddingStart="3dp"
+        android:textColor="@color/color_f44541"
+        android:textSize="@dimen/sp_20"
+        android:textStyle="bold"
+        android:includeFontPadding="false"
+        app:layout_constraintTop_toTopOf="@+id/tv_teacher_name"
+        app:layout_constraintBottom_toBottomOf="@+id/tv_teacher_name"
+        app:layout_constraintRight_toLeftOf="@+id/tv_price_unit" />
+
+    <TextView
+        android:visibility="gone"
+        android:id="@+id/tv_price_symbol"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="¥"
+        android:textColor="@color/color_f44541"
+        android:textSize="@dimen/sp_14"
+        android:textStyle="bold"
+        app:layout_constraintBaseline_toBaselineOf="@+id/tv_price"
+        app:layout_constraintRight_toLeftOf="@+id/tv_price" />
+
+    <TextView
+        android:visibility="gone"
+        android:includeFontPadding="false"
+        android:id="@+id/tv_price_unit"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:paddingStart="2dp"
+        android:text="/4课时"
+        android:textColor="@color/color_999999"
+        android:textSize="@dimen/sp_12"
+        app:layout_constraintRight_toRightOf="parent"
+        app:layout_constraintBaseline_toBaselineOf="@+id/tv_price" />
+    <ImageView
+        android:layout_marginEnd="4dp"
+        android:id="@+id/iv_course_tag"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:src="@drawable/icon_course_completed_tag"
+        app:layout_constraintRight_toLeftOf="@+id/tv_course_completed_title"
+        app:layout_constraintBottom_toBottomOf="@+id/tv_course_completed_title"
+        app:layout_constraintTop_toTopOf="@+id/tv_course_completed_title" />
+
+    <TextView
+        android:id="@+id/tv_course_completed_title"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:includeFontPadding="false"
+        android:text="已上课时"
+        android:textColor="@color/color_999999"
+        android:textSize="@dimen/sp_12"
+        app:layout_constraintBaseline_toBaselineOf="@+id/tv_course_completed_value"
+        app:layout_constraintRight_toLeftOf="@+id/tv_course_completed_value" />
+
+
+    <TextView
+        android:id="@+id/tv_course_completed_value"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:includeFontPadding="false"
+        android:paddingStart="3dp"
+        android:paddingEnd="3dp"
+        android:text="0"
+        android:textColor="@color/color_2dc7aa"
+        android:textSize="@dimen/sp_12"
+        android:textStyle="bold"
+        app:layout_constraintBaseline_toBaselineOf="@+id/tv_course_total_title"
+        app:layout_constraintRight_toLeftOf="@+id/tv_course_total_title" />
+
+    <TextView
+        android:id="@+id/tv_course_total_title"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:includeFontPadding="false"
+        android:text="/总课时"
+        android:textColor="@color/color_999999"
+        android:textSize="@dimen/sp_12"
+        app:layout_constraintBaseline_toBaselineOf="@+id/tv_course_total_value"
+        app:layout_constraintRight_toLeftOf="@+id/tv_course_total_value" />
+
+
+    <TextView
+        android:id="@+id/tv_course_total_value"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:includeFontPadding="false"
+        android:paddingStart="3dp"
+        android:paddingEnd="3dp"
+        android:text="0"
+        android:textColor="@color/color_333333"
+        android:textSize="@dimen/sp_12"
+        android:textStyle="bold"
+        app:layout_constraintBottom_toBottomOf="@+id/tv_teacher_name"
+        app:layout_constraintTop_toTopOf="@+id/tv_teacher_name"
+        app:layout_constraintRight_toRightOf="parent" />
+
+
+    <ImageView
+        android:id="@+id/iv_chat"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="5dp"
+        android:src="@drawable/icon_chat_small"
+        android:visibility="gone"
+        app:layout_constraintBottom_toBottomOf="@+id/tv_title"
+        app:layout_constraintLeft_toRightOf="@+id/tv_title"
+        app:layout_constraintTop_toTopOf="@+id/tv_title" />
+
+
+
+</androidx.constraintlayout.widget.ConstraintLayout>