浏览代码

增加老师端我的课程琴房课程组列表页面

Pq 3 月之前
父节点
当前提交
0b6654df4f

+ 1 - 0
BaseLibrary/src/main/java/com/cooleshow/base/constanst/Constants.java

@@ -34,5 +34,6 @@ public class Constants {
 
     public static final String VIP_COURSE_TAG = "VIP";//VIP课type参数
     public static final String INTEREST_COURSE_TAG = "PRACTICE";//趣纠课type参数
+    public static final String PIANO_COURSE_TAG = "PIANO_ROOM_CLASS";//琴房课type参数
 
 }

+ 54 - 0
teacher/src/main/java/com/cooleshow/teacher/adapter/PianoCourseGroupAdapter.java

@@ -0,0 +1,54 @@
+package com.cooleshow.teacher.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.viewholder.BaseViewHolder;
+import com.cooleshow.base.constanst.CourseGroupStatusType;
+import com.cooleshow.base.utils.GlideUtils;
+import com.cooleshow.teacher.R;
+import com.cooleshow.teacher.bean.VIPCourseGroupListBean;
+
+import androidx.annotation.NonNull;
+
+/**
+ * Author by pq, Date on 2024/11/20.
+ */
+public class PianoCourseGroupAdapter extends BaseQuickAdapter<VIPCourseGroupListBean.RowsBean, BaseViewHolder> {
+    public PianoCourseGroupAdapter() {
+        super(R.layout.item_piano_course_group_layout);
+    }
+
+    @Override
+    protected void convert(@NonNull BaseViewHolder holder, VIPCourseGroupListBean.RowsBean bean) {
+        ImageView iv_avatar = holder.getView(R.id.iv_avatar);
+
+        holder.setText(R.id.tv_title, bean.getCourseGroupName());
+        holder.setText(R.id.tv_name, bean.getStudentName());
+        holder.setText(R.id.tv_course_completed_value, bean.getCompleteCourseNum());
+        holder.setText(R.id.tv_course_total_value, bean.getCourseNum());
+        holder.setText(R.id.tv_course_name, bean.getSubjectName());
+
+        TextView tv_status = holder.getView(R.id.tv_status);
+        String status = bean.getStatus();
+        if (TextUtils.equals(status, CourseGroupStatusType.ING.getId())) {
+            //进行中
+            tv_status.setText(CourseGroupStatusType.ING.getValue());
+            tv_status.setTextColor(getContext().getResources().getColor(com.cooleshow.base.R.color.color_2dc7aa));
+        } else if (TextUtils.equals(status, CourseGroupStatusType.NOT_START.getId())) {
+            //未开始
+            tv_status.setText(CourseGroupStatusType.NOT_START.getValue());
+            tv_status.setTextColor(getContext().getResources().getColor(com.cooleshow.base.R.color.color_ff802c));
+        } else if (TextUtils.equals(status, CourseGroupStatusType.COMPLETE.getId())) {
+            //已结课
+            tv_status.setText(CourseGroupStatusType.COMPLETE.getValue());
+            tv_status.setTextColor(getContext().getResources().getColor(com.cooleshow.base.R.color.color_999999));
+        } else if (TextUtils.equals(status, CourseGroupStatusType.CANCEL.getId())) {
+            //已取消
+            tv_status.setText(CourseGroupStatusType.CANCEL.getValue());
+            tv_status.setTextColor(getContext().getResources().getColor(com.cooleshow.base.R.color.color_999999));
+        }
+    }
+}

+ 21 - 0
teacher/src/main/java/com/cooleshow/teacher/contract/PianoCourseGroupContract.java

@@ -0,0 +1,21 @@
+package com.cooleshow.teacher.contract;
+
+import com.cooleshow.base.presenter.view.BaseView;
+import com.cooleshow.teacher.bean.VIPCourseGroupListBean;
+
+/**
+ * Author by pq, Date on 2022/4/20.
+ */
+public interface PianoCourseGroupContract {
+
+    interface View extends BaseView {
+        void onGetCourseGroupSuccess(int page, VIPCourseGroupListBean data);
+
+        void onGetCourseGroupError(int page);
+
+
+    }
+
+    interface Presenter {
+    }
+}

+ 59 - 0
teacher/src/main/java/com/cooleshow/teacher/presenter/course/PianoCourseGroupPresenter.java

@@ -0,0 +1,59 @@
+package com.cooleshow.teacher.presenter.course;
+
+import android.text.TextUtils;
+
+import com.cooleshow.base.constanst.Constants;
+import com.cooleshow.base.presenter.BasePresenter;
+import com.cooleshow.base.rx.BaseObserver;
+import com.cooleshow.base.utils.RequestBodyUtil;
+import com.cooleshow.teacher.api.APIService;
+import com.cooleshow.teacher.bean.VIPCourseGroupListBean;
+import com.cooleshow.teacher.contract.InterestCourseGroupContract;
+import com.cooleshow.teacher.contract.PianoCourseGroupContract;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+/**
+ * 陪练课presenter
+ * Author by pq, Date on 2022/4/20.
+ */
+public class PianoCourseGroupPresenter extends BasePresenter<PianoCourseGroupContract.View> implements PianoCourseGroupContract.Presenter {
+
+    public void queryInterestCourseGroup(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("status", status);
+            }
+            if (!TextUtils.isEmpty(subjectId)) {
+                jsonObject.putOpt("subjectId", subjectId);
+            }
+            jsonObject.putOpt("search", search);
+            jsonObject.putOpt("courseType", Constants.PIANO_COURSE_TAG);
+            jsonObject.putOpt("page", page);
+            jsonObject.putOpt("rows", Constants.DEFAULT_DATA_SIZE);
+        } catch (JSONException e) {
+            e.printStackTrace();
+        }
+        addSubscribe(create(APIService.class).getCourseGroup(RequestBodyUtil.convertToRequestBodyJson(jsonObject.toString())), new BaseObserver<VIPCourseGroupListBean>(getView()) {
+            @Override
+            protected void onSuccess(VIPCourseGroupListBean data) {
+                if (getView() != null) {
+                    getView().onGetCourseGroupSuccess(page, data);
+                }
+            }
+
+            @Override
+            public void onError(Throwable e) {
+                super.onError(e);
+                if (getView() != null) {
+                    getView().onGetCourseGroupError(page);
+                }
+            }
+        });
+    }
+}

+ 5 - 5
teacher/src/main/java/com/cooleshow/teacher/ui/course/MineCourseActivity.java

@@ -40,7 +40,7 @@ public class MineCourseActivity extends BaseMVPActivity<ActivityMineCourseLayout
     private ArrayList<Fragment> mFragments = new ArrayList<>();
     private LiveCourseGroupFragment mLiveCourseFragment;
     private VideoCourseGroupFragment mVideoCourseFragment;
-    private PianoRoomCourseFragment mPianoRoomCourseFragment;
+    private PianoCourseGroupFragment mPianoRoomCourseGroupFragment;
     private VIPCourseGroupFragment mVipCourseFragment;
     private InterestCourseGroupFragment mInterestCourseGroupFragment;
 
@@ -78,13 +78,13 @@ public class MineCourseActivity extends BaseMVPActivity<ActivityMineCourseLayout
         mInterestCourseGroupFragment = new InterestCourseGroupFragment();
         mLiveCourseFragment = new LiveCourseGroupFragment();
         mVideoCourseFragment = new VideoCourseGroupFragment();
-        mPianoRoomCourseFragment = new PianoRoomCourseFragment();
+        mPianoRoomCourseGroupFragment = new PianoCourseGroupFragment();
         mVipCourseFragment = new VIPCourseGroupFragment();
         mFragments.add(mVipCourseFragment);
         mFragments.add(mInterestCourseGroupFragment);
         mFragments.add(mLiveCourseFragment);
         mFragments.add(mVideoCourseFragment);
-        mFragments.add(mPianoRoomCourseFragment);
+        mFragments.add(mPianoRoomCourseGroupFragment);
         MineCoursePageAdapter mineCoursePageAdapter = new MineCoursePageAdapter(this);
         mineCoursePageAdapter.setFragments(mFragments);
         viewBinding.viewPager.setAdapter(mineCoursePageAdapter);
@@ -167,8 +167,8 @@ public class MineCourseActivity extends BaseMVPActivity<ActivityMineCourseLayout
         if (mVideoCourseFragment != null) {
             mVideoCourseFragment.querySubjectItemSuccess(data);
         }
-        if (mPianoRoomCourseFragment != null) {
-            mPianoRoomCourseFragment.querySubjectItemSuccess(data);
+        if (mPianoRoomCourseGroupFragment != null) {
+            mPianoRoomCourseGroupFragment.querySubjectItemSuccess(data);
         }
     }
 

+ 253 - 0
teacher/src/main/java/com/cooleshow/teacher/ui/course/PianoCourseGroupFragment.java

@@ -0,0 +1,253 @@
+package com.cooleshow.teacher.ui.course;
+
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.PopupWindow;
+
+import com.chad.library.adapter.base.BaseQuickAdapter;
+import com.chad.library.adapter.base.listener.OnItemClickListener;
+import com.cooleshow.base.constanst.Constants;
+import com.cooleshow.base.constanst.CourseGroupStatusType;
+import com.cooleshow.base.interfaces.IFilterViewData;
+import com.cooleshow.base.ui.fragment.BaseMVPFragment;
+import com.cooleshow.base.utils.LOG;
+import com.cooleshow.base.utils.PopupUtil;
+import com.cooleshow.base.utils.UiUtils;
+import com.cooleshow.base.widgets.CourseGroupFilterView;
+import com.cooleshow.base.widgets.EmptyViewLayout;
+import com.cooleshow.teacher.R;
+import com.cooleshow.teacher.adapter.PianoCourseGroupAdapter;
+import com.cooleshow.teacher.adapter.VIPCourseAdapter;
+import com.cooleshow.teacher.bean.QuerySubjectBean;
+import com.cooleshow.teacher.bean.VIPCourseGroupListBean;
+import com.cooleshow.teacher.contract.InterestCourseGroupContract;
+import com.cooleshow.teacher.contract.PianoCourseGroupContract;
+import com.cooleshow.teacher.databinding.FgInterestCourseLayoutBinding;
+import com.cooleshow.teacher.databinding.FgPianoCourseGroupLayoutBinding;
+import com.cooleshow.teacher.presenter.course.InterestCourseGroupPresenter;
+import com.cooleshow.teacher.presenter.course.PianoCourseGroupPresenter;
+import com.scwang.smart.refresh.footer.ClassicsFooter;
+import com.scwang.smart.refresh.layout.api.RefreshLayout;
+import com.scwang.smart.refresh.layout.listener.OnLoadMoreListener;
+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.LinearLayoutManager;
+
+/**
+ * Author by pq, Date on 2022/5/9.
+ * 我的课程-趣纠课课程组
+ */
+public class PianoCourseGroupFragment extends BaseMVPFragment<FgPianoCourseGroupLayoutBinding, PianoCourseGroupPresenter> implements PianoCourseGroupContract.View, View.OnClickListener {
+    private List<IFilterViewData> subjectBeanList = new ArrayList<>();//声部筛选
+    private PianoCourseGroupAdapter mAdapter;
+    private int currentPage = 1;
+    private boolean hasNext = true;
+    private String status = "";
+    private String currentSubjectId;
+    private String searchCondition;
+    private CourseGroupFilterView mCourseGroupFilterView;
+    private PopupWindow mPopupWindow;
+    private List<IFilterViewData> statusList;//状态筛选
+
+    @Override
+    protected void initView(View rootView) {
+        mViewBinding.refreshLayout.setRefreshFooter(new ClassicsFooter(getContext()));
+        LinearLayoutManager manager = new LinearLayoutManager(getContext());
+        mViewBinding.recyclerViewList.setLayoutManager(manager);
+        mAdapter = new PianoCourseGroupAdapter();
+        EmptyViewLayout mEmptyView = new EmptyViewLayout(getContext());
+        mEmptyView.setContent(com.cooleshow.base.R.drawable.icon_empty_course, "暂无课程");
+        mAdapter.setEmptyView(mEmptyView);
+        mViewBinding.recyclerViewList.setAdapter(mAdapter);
+    }
+
+
+    @Override
+    protected void initData() {
+        CourseGroupStatusType[] values = CourseGroupStatusType.values();
+        List<CourseGroupStatusType> courseGroupStatusTypes = Arrays.asList(values);
+        statusList = new ArrayList<IFilterViewData>(courseGroupStatusTypes);
+
+
+        initListener();
+        getData(true);
+    }
+
+    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(false);
+            }
+        });
+        mViewBinding.refreshLayout.setOnLoadMoreListener(new OnLoadMoreListener() {
+            @Override
+            public void onLoadMore(@NonNull RefreshLayout refreshLayout) {
+                //上拉加载
+                if (hasNext) {
+                    currentPage++;
+                    getData(false);
+                } else {
+                    mViewBinding.refreshLayout.finishLoadMoreWithNoMoreData();
+                }
+            }
+        });
+
+        mAdapter.setOnItemClickListener(new OnItemClickListener() {
+            @Override
+            public void onItemClick(@NonNull BaseQuickAdapter<?, ?> adapter, @NonNull View view, int position) {
+                //课程详情页
+            }
+        });
+    }
+
+    private void getData(boolean isLoading) {
+        if (currentPage == 1) {
+            mViewBinding.refreshLayout.resetNoMoreData();
+        }
+        presenter.queryInterestCourseGroup(isLoading, status, currentSubjectId, searchCondition, currentPage);
+    }
+
+    @Override
+    protected FgPianoCourseGroupLayoutBinding getLayoutView() {
+        return FgPianoCourseGroupLayoutBinding.inflate(getLayoutInflater());
+    }
+
+    @Override
+    protected PianoCourseGroupPresenter createPresenter() {
+        return new PianoCourseGroupPresenter();
+    }
+
+    @Override
+    public void onClick(View view) {
+        int id = view.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;
+                    PianoCourseGroupFragment.this.status = obj;
+                    PianoCourseGroupFragment.this.currentSubjectId = obj2;
+                    getData(true);
+                }
+            });
+        }
+        mCourseGroupFilterView.setData(statusList, 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);
+            }
+        });
+    }
+
+
+    @Override
+    public void onResume() {
+        super.onResume();
+    }
+
+
+    private void checkHasNext(int dataSize) {
+        hasNext = dataSize >= Constants.DEFAULT_DATA_SIZE;
+        mViewBinding.refreshLayout.setNoMoreData(!hasNext);
+    }
+
+    @Override
+    public void onGetCourseGroupSuccess(int page, VIPCourseGroupListBean dataList) {
+        if (isDetached()) {
+            return;
+        }
+        LOG.i("pq", "onGetCourseGroupSuccess:" + 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 onGetCourseGroupError(int page) {
+        if (isDetached()) {
+            return;
+        }
+        if (page == 1) {
+            mViewBinding.refreshLayout.finishRefresh();
+        } else {
+            if (mAdapter != null) {
+                currentPage--;
+                mViewBinding.refreshLayout.finishLoadMore(false);
+            }
+        }
+    }
+
+    public void querySubjectItemSuccess(List<QuerySubjectBean> data) {
+        subjectBeanList.clear();
+        subjectBeanList.add(new QuerySubjectBean("全部", 0));
+        subjectBeanList.addAll(data);
+    }
+}

二进制
teacher/src/main/res/drawable-xhdpi/icon_piano_room_course.png


二进制
teacher/src/main/res/drawable-xxhdpi/icon_piano_room_course.png


+ 1 - 1
teacher/src/main/res/layout/activity_piano_room_detail_layout.xml

@@ -83,7 +83,7 @@
                     android:layout_marginTop="20dp"
                     android:background="@drawable/shape_piano_room_course_icon"
                     android:gravity="center"
-                    android:text="小课"
+                    android:text="琴房"
                     android:textColor="@color/white"
                     android:textSize="@dimen/sp_14"
                     app:layout_constraintBottom_toBottomOf="parent"

+ 112 - 0
teacher/src/main/res/layout/fg_piano_course_group_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="请输入搜索关键词"
+        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>

+ 155 - 0
teacher/src/main/res/layout/item_piano_course_group_layout.xml

@@ -0,0 +1,155 @@
+<?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:padding="12dp">
+
+    <TextView
+        android:id="@+id/tv_title"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:layout_marginEnd="5dp"
+        android:ellipsize="end"
+        android:includeFontPadding="false"
+        android:maxLines="1"
+        android:textColor="@color/color_131415"
+        android:textSize="@dimen/sp_16"
+        android:textStyle="bold"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintRight_toLeftOf="@+id/tv_status"
+        app:layout_constraintTop_toTopOf="parent"
+        tools:text="VIP定制课-张涵宇" />
+
+    <TextView
+        android:id="@+id/tv_status"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:includeFontPadding="false"
+        android:textColor="@color/color_999999"
+        android:textSize="@dimen/sp_14"
+        app:layout_constraintBottom_toBottomOf="@+id/tv_title"
+        app:layout_constraintRight_toRightOf="parent"
+        app:layout_constraintTop_toTopOf="@+id/tv_title"
+        tools:text="已结课" />
+
+    <ImageView
+        android:src="@drawable/icon_piano_room_course"
+        android:id="@+id/iv_avatar"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="8dp"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/tv_title"
+        app:qmui_corner_radius="5dp" />
+
+    <TextView
+        android:id="@+id/tv_name"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="10dp"
+        android:layout_marginEnd="5dp"
+        android:ellipsize="end"
+        android:includeFontPadding="false"
+        android:maxLines="1"
+        android:textColor="@color/color_333333"
+        android:textSize="@dimen/sp_13"
+        app:layout_constraintBottom_toTopOf="@+id/tv_course_completed_title"
+        app:layout_constraintHorizontal_bias="0"
+        app:layout_constraintHorizontal_chainStyle="packed"
+        app:layout_constraintLeft_toRightOf="@+id/iv_avatar"
+        app:layout_constraintRight_toLeftOf="@+id/tv_course_name"
+        app:layout_constraintTop_toTopOf="@+id/iv_avatar"
+        app:layout_constraintVertical_chainStyle="packed"
+        app:layout_constraintWidth_default="wrap"
+        tools:text="张涵宇" />
+
+
+    <TextView
+        android:id="@+id/tv_course_name"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="5dp"
+        android:background="@drawable/shape_couse_type_text_bg"
+        android:gravity="center"
+        android:includeFontPadding="false"
+        android:paddingStart="4dp"
+        android:paddingTop="2dp"
+        android:paddingEnd="4dp"
+        android:paddingBottom="2dp"
+        android:textColor="@color/color_ff8c00"
+        android:textSize="@dimen/sp_10"
+        app:layout_constraintBottom_toBottomOf="@+id/tv_name"
+        app:layout_constraintLeft_toRightOf="@+id/tv_name"
+        app:layout_constraintRight_toRightOf="parent"
+        app:layout_constraintTop_toTopOf="@+id/tv_name"
+        tools:text="单簧管" />
+
+    <ImageView
+        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_constraintBottom_toBottomOf="@+id/tv_course_completed_title"
+        app:layout_constraintLeft_toLeftOf="@+id/tv_name"
+        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:layout_marginStart="4dp"
+        android:layout_marginTop="5dp"
+        android:includeFontPadding="false"
+        android:text="已上课时"
+        android:textColor="@color/color_999999"
+        android:textSize="@dimen/sp_12"
+        app:layout_constraintBottom_toBottomOf="@+id/iv_avatar"
+        app:layout_constraintLeft_toRightOf="@+id/iv_course_tag"
+        app:layout_constraintTop_toBottomOf="@+id/tv_name" />
+
+
+    <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_completed_title"
+        app:layout_constraintLeft_toRightOf="@+id/tv_course_completed_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_completed_value"
+        app:layout_constraintLeft_toRightOf="@+id/tv_course_completed_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_constraintBaseline_toBaselineOf="@+id/tv_course_total_title"
+        app:layout_constraintLeft_toRightOf="@+id/tv_course_total_title" />
+
+</androidx.constraintlayout.widget.ConstraintLayout>