Browse Source

修改学生端约课页面

Pq 3 months ago
parent
commit
2fe507a984
38 changed files with 1156 additions and 95 deletions
  1. 68 0
      BaseLibrary/src/main/java/com/cooleshow/base/adapter/CommonSortAdapter.java
  2. 85 0
      BaseLibrary/src/main/java/com/cooleshow/base/bean/DataSortBean.java
  3. 45 0
      BaseLibrary/src/main/java/com/cooleshow/base/constanst/DataSortType.java
  4. 8 0
      BaseLibrary/src/main/java/com/cooleshow/base/iml/IDataSortBasis.java
  5. 106 0
      BaseLibrary/src/main/java/com/cooleshow/base/widgets/CommonSortView.java
  6. 56 0
      BaseLibrary/src/main/java/com/cooleshow/base/widgets/RecyclerViewAtViewPager2.java
  7. BIN
      BaseLibrary/src/main/res/drawable-xhdpi/icon_search.png
  8. BIN
      BaseLibrary/src/main/res/drawable-xhdpi/icon_sort_status1.png
  9. BIN
      BaseLibrary/src/main/res/drawable-xhdpi/icon_sort_status2.png
  10. BIN
      BaseLibrary/src/main/res/drawable-xhdpi/icon_sort_status3.png
  11. BIN
      BaseLibrary/src/main/res/drawable-xxhdpi/icon_search.png
  12. BIN
      BaseLibrary/src/main/res/drawable-xxhdpi/icon_sort_status1.png
  13. BIN
      BaseLibrary/src/main/res/drawable-xxhdpi/icon_sort_status2.png
  14. BIN
      BaseLibrary/src/main/res/drawable-xxhdpi/icon_sort_status3.png
  15. 6 0
      BaseLibrary/src/main/res/drawable/shape_e8fffb_14dp_border_2dc7aa_1dp.xml
  16. 38 0
      BaseLibrary/src/main/res/layout/item_common_sort_view_layout.xml
  17. 12 0
      BaseLibrary/src/main/res/layout/view_common_sort_layout.xml
  18. 2 0
      BaseLibrary/src/main/res/values/colors.xml
  19. 1 0
      student/src/main/AndroidManifest.xml
  20. 45 0
      student/src/main/java/com/cooleshow/student/adapter/VIPCourseCourseListAdapter.java
  21. 9 0
      student/src/main/java/com/cooleshow/student/api/APIService.java
  22. 235 0
      student/src/main/java/com/cooleshow/student/bean/AppointCourseTeacherListBean.java
  23. 5 1
      student/src/main/java/com/cooleshow/student/contract/VIPCustomCourseListContract.java
  24. 24 9
      student/src/main/java/com/cooleshow/student/presenter/course/VIPCustomCourseListPresenter.java
  25. 43 11
      student/src/main/java/com/cooleshow/student/ui/course/AppointmentCourseActivity.java
  26. 138 8
      student/src/main/java/com/cooleshow/student/ui/course/VIPCustomCourseListFragment.java
  27. BIN
      student/src/main/res/drawable-xhdpi/bg_appointment_top.png
  28. BIN
      student/src/main/res/drawable-xhdpi/icon_course_completed_tag.png
  29. BIN
      student/src/main/res/drawable-xxhdpi/bg_appointment_top.png
  30. BIN
      student/src/main/res/drawable-xxhdpi/icon_course_completed_tag.png
  31. 20 0
      student/src/main/res/drawable/appoint_course_tab_indicator.xml
  32. 27 11
      student/src/main/res/layout/activity_appointment_course.xml
  33. 17 47
      student/src/main/res/layout/fg_vip_custom_course_list_layout.xml
  34. 138 0
      student/src/main/res/layout/item_vip_course_list_layout.xml
  35. 19 0
      student/src/main/res/layout/view_appoint_course_tab_layout.xml
  36. 3 3
      teacher/src/main/java/com/cooleshow/teacher/bean/VideoCourseListBean.java
  37. 1 1
      teacher/src/main/res/layout/ac_vip_course_setting_layout.xml
  38. 5 4
      teacher/src/main/res/layout/item_hp_vip_course_list_layout.xml

+ 68 - 0
BaseLibrary/src/main/java/com/cooleshow/base/adapter/CommonSortAdapter.java

@@ -0,0 +1,68 @@
+package com.cooleshow.base.adapter;
+
+import android.text.TextUtils;
+import android.view.View;
+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.R;
+import com.cooleshow.base.bean.DataSortBean;
+
+import androidx.annotation.NonNull;
+import androidx.constraintlayout.widget.ConstraintLayout;
+
+/**
+ * Author by pq, Date on 2024/11/18.
+ */
+public class CommonSortAdapter extends BaseQuickAdapter<DataSortBean, BaseViewHolder> {
+    public CommonSortAdapter() {
+        super(R.layout.item_common_sort_view_layout);
+    }
+
+    @Override
+    protected void convert(@NonNull BaseViewHolder holder, DataSortBean dataSortBean) {
+        boolean multiSelect = dataSortBean.isMultiSelect();
+
+        ImageView iv_status=holder.getView(R.id.iv_status);
+        boolean isSelect = dataSortBean.isSelect();
+        if (multiSelect){
+            iv_status.setVisibility(View.VISIBLE);
+            if(isSelect){
+                iv_status.setImageResource(dataSortBean.isTop() ? R.drawable.icon_sort_status2:R.drawable.icon_sort_status3);
+            }else{
+                iv_status.setImageResource(R.drawable.icon_sort_status1);
+            }
+        }else{
+            iv_status.setVisibility(View.GONE);
+        }
+        setCommonStyle(holder,isSelect, dataSortBean.getText());
+    }
+
+    private void setCommonStyle(BaseViewHolder holder,boolean isSelect,String text){
+        ConstraintLayout cs_root=holder.getView(R.id.cs_root);
+        TextView tv_text=holder.getView(R.id.tv_text);
+        tv_text.setText(text);
+        cs_root.setBackgroundResource(isSelect ? R.drawable.shape_e8fffb_14dp_border_2dc7aa_1dp:R.drawable.bg_white_14dp);
+        tv_text.setTextColor(getContext().getResources().getColor(isSelect ? R.color.color_18b99a:R.color.color_333333));
+    }
+
+    /**
+     * 多选状态的item仅支持选中一个
+     * @param id
+     * @return
+     */
+    public void cancelLastSelectIfNeed(String id){
+        for (int i = 0; i < getData().size(); i++) {
+            DataSortBean dataSortBean = getData().get(i);
+            if(dataSortBean.isMultiSelect()){
+                if(!TextUtils.equals(dataSortBean.getId(),id)){
+                    if(dataSortBean.isSelect()){
+                        dataSortBean.reset();
+                    }
+                }
+            }
+        }
+    }
+}

+ 85 - 0
BaseLibrary/src/main/java/com/cooleshow/base/bean/DataSortBean.java

@@ -0,0 +1,85 @@
+package com.cooleshow.base.bean;
+
+import com.cooleshow.base.constanst.DataSortType;
+import com.cooleshow.base.iml.IDataSortBasis;
+
+/**
+ * Author by pq, Date on 2024/11/18.
+ */
+public class DataSortBean implements IDataSortBasis {
+    public static final int MULTISELECT_STATUS_NUM = 3;
+    public static final int DEFAULT_STATUS_NUM = 2;
+    public static final int DEFAULT_STEP = 1;
+    private String id;
+    private String text;
+    private boolean isSelect;
+    private boolean isTop;//是否是升序
+    private int statusStep = DEFAULT_STEP;
+    private int maxStatusNum;
+
+    public DataSortBean(String id, String text, boolean isCanMultiSelect) {
+        this.id = id;
+        this.text = text;
+        this.maxStatusNum = isCanMultiSelect ? MULTISELECT_STATUS_NUM : DEFAULT_STATUS_NUM;
+    }
+
+    public DataSortBean(DataSortType dataSortType){
+        this.id = dataSortType.getId();
+        this.text = dataSortType.getText();
+        this.maxStatusNum = dataSortType.isMultiSelect() ? MULTISELECT_STATUS_NUM : DEFAULT_STATUS_NUM;
+    }
+
+    public boolean isTop() {
+        return isTop;
+    }
+
+    public void updateSelectStatus() {
+        statusStep++;
+        if (statusStep > maxStatusNum) {
+            statusStep = DEFAULT_STEP;
+        }
+        int result = statusStep % maxStatusNum;
+        if (isMultiSelect()) {
+            isSelect = result != 1;
+            isTop = result == 2;
+        } else {
+            isSelect = result == 0;
+        }
+    }
+
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public String getText() {
+        return text;
+    }
+
+    public void setText(String text) {
+        this.text = text;
+    }
+
+    public boolean isSelect() {
+        return isSelect;
+    }
+
+    public void setSelect(boolean select) {
+        isSelect = select;
+    }
+
+    @Override
+    public boolean isMultiSelect() {
+        return this.maxStatusNum == MULTISELECT_STATUS_NUM;
+    }
+
+    public void reset(){
+        statusStep =DEFAULT_STEP;
+        isSelect =false;
+        isTop =false;
+    }
+}

+ 45 - 0
BaseLibrary/src/main/java/com/cooleshow/base/constanst/DataSortType.java

@@ -0,0 +1,45 @@
+package com.cooleshow.base.constanst;
+
+/**
+ * Author by pq, Date on 2024/6/24.
+ */
+public enum DataSortType {
+    RECENT_FREE_TIME("recentFreeTime", "仅看30天内有空",false),
+    HAS_COURSE("expTime", "已上课时",true),
+    COURSE_PRICE("subjectPrice", "课时单价",true),
+    COURSE_MARK("starGrade", "评分",true);
+
+    DataSortType(String id, String value,boolean isMultiSelect) {
+        this.id = id;
+        this.value = value;
+        this.isMultiSelect = isMultiSelect;
+    }
+
+    private String id;
+    private String value;
+    private boolean isMultiSelect;
+
+    public boolean isMultiSelect() {
+        return isMultiSelect;
+    }
+
+    public void setMultiSelect(boolean multiSelect) {
+        isMultiSelect = multiSelect;
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public String getText() {
+        return value;
+    }
+
+    public void setValue(String value) {
+        this.value = value;
+    }
+}

+ 8 - 0
BaseLibrary/src/main/java/com/cooleshow/base/iml/IDataSortBasis.java

@@ -0,0 +1,8 @@
+package com.cooleshow.base.iml;
+
+/**
+ * Author by pq, Date on 2024/11/18.
+ */
+public interface IDataSortBasis {
+    boolean isMultiSelect();//是否多选 多选有3种状态 单选就2种
+}

+ 106 - 0
BaseLibrary/src/main/java/com/cooleshow/base/widgets/CommonSortView.java

@@ -0,0 +1,106 @@
+package com.cooleshow.base.widgets;
+
+import android.content.Context;
+import android.text.TextUtils;
+import android.util.AttributeSet;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.FrameLayout;
+
+import com.chad.library.adapter.base.BaseQuickAdapter;
+import com.chad.library.adapter.base.listener.OnItemClickListener;
+import com.cooleshow.base.R;
+import com.cooleshow.base.adapter.CommonSortAdapter;
+import com.cooleshow.base.bean.DataSortBean;
+import com.cooleshow.base.constanst.DataSortType;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+
+/**
+ * Author by pq, Date on 2024/11/18.
+ */
+public class CommonSortView extends FrameLayout {
+    public static final String ASC = "ASC";
+    public static final String DESC = "DESC";
+    private CommonSortAdapter mSortAdapter;
+    private OnEventListener mEventListener;
+
+    public CommonSortView(@NonNull Context context) {
+        this(context, null);
+    }
+
+    public CommonSortView(@NonNull Context context, @Nullable AttributeSet attrs) {
+        this(context, attrs, -1);
+    }
+
+    public CommonSortView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+        init();
+    }
+
+    private void init() {
+        LayoutInflater.from(getContext()).inflate(R.layout.view_common_sort_layout, this);
+        RecyclerView recyclerView = findViewById(R.id.recyclerView_item);
+        LinearLayoutManager layoutManager = new LinearLayoutManager(getContext(), RecyclerView.HORIZONTAL, false);
+        recyclerView.setLayoutManager(layoutManager);
+        mSortAdapter = new CommonSortAdapter();
+        recyclerView.setAdapter(mSortAdapter);
+
+        mSortAdapter.setOnItemClickListener(new OnItemClickListener() {
+            @Override
+            public void onItemClick(@NonNull BaseQuickAdapter<?, ?> adapter, @NonNull View view, int position) {
+                if (position < mSortAdapter.getData().size()) {
+                    DataSortBean dataSortBean = mSortAdapter.getData().get(position);
+                    if (dataSortBean.isMultiSelect()) {
+                        mSortAdapter.cancelLastSelectIfNeed(dataSortBean.getId());
+                    }
+                    dataSortBean.updateSelectStatus();
+                    mSortAdapter.notifyDataSetChanged();
+                    returnData();
+                }
+            }
+        });
+    }
+
+    private void returnData() {
+        List<DataSortBean> data = mSortAdapter.getData();
+        boolean isRecentFreeTime = false;
+        String sortField = "";
+        String sortRule = "";
+
+        for (int i = 0; i < data.size(); i++) {
+            DataSortBean dataSortBean = data.get(i);
+            if (TextUtils.equals(dataSortBean.getId(), DataSortType.RECENT_FREE_TIME.getId())) {
+                isRecentFreeTime = dataSortBean.isSelect();
+                continue;
+            }
+            if (dataSortBean.isSelect()) {
+                sortField = dataSortBean.getId();
+                sortRule = dataSortBean.isTop() ? ASC : DESC;
+            }
+        }
+        if (mEventListener != null) {
+            mEventListener.onFilterResult(isRecentFreeTime, sortField, sortRule);
+        }
+    }
+
+    public void setData(ArrayList<DataSortBean> data) {
+        if (mSortAdapter != null) {
+            mSortAdapter.setNewInstance(data);
+        }
+    }
+
+    public void setEventListener(OnEventListener eventListener) {
+        mEventListener = eventListener;
+    }
+
+    public interface OnEventListener {
+        void onFilterResult(boolean isRecentFreeTime, String sortField, String sortRule);
+    }
+}

+ 56 - 0
BaseLibrary/src/main/java/com/cooleshow/base/widgets/RecyclerViewAtViewPager2.java

@@ -0,0 +1,56 @@
+package com.cooleshow.base.widgets;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.recyclerview.widget.RecyclerView;
+
+/**
+ * Author by pq, Date on 2023/4/11.
+ */
+
+public class RecyclerViewAtViewPager2 extends RecyclerView {
+    public RecyclerViewAtViewPager2(@NonNull Context context) {
+        super(context);
+    }
+
+    public RecyclerViewAtViewPager2(@NonNull Context context, @Nullable AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    public RecyclerViewAtViewPager2(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+    }
+
+
+    private int startX, startY;
+    @Override
+    public boolean dispatchTouchEvent(MotionEvent ev) {
+        switch (ev.getAction()) {
+            case MotionEvent.ACTION_DOWN:
+                startX = (int) ev.getX();
+                startY = (int) ev.getY();
+                getParent().requestDisallowInterceptTouchEvent(true);
+                break;
+            case MotionEvent.ACTION_MOVE:
+                int endX = (int) ev.getX();
+                int endY = (int) ev.getY();
+                int disX = Math.abs(endX - startX);
+                int disY = Math.abs(endY - startY);
+                if(disX > disY){
+                    getParent().requestDisallowInterceptTouchEvent(canScrollHorizontally(startX -endX));
+                }else {
+                    getParent().requestDisallowInterceptTouchEvent(canScrollVertically(startY -endY));
+                }
+                break;
+            case MotionEvent.ACTION_UP:
+            case MotionEvent.ACTION_CANCEL:
+                getParent().requestDisallowInterceptTouchEvent(false);
+                break;
+        }
+        return super.dispatchTouchEvent(ev);
+    }
+}

BIN
BaseLibrary/src/main/res/drawable-xhdpi/icon_search.png


BIN
BaseLibrary/src/main/res/drawable-xhdpi/icon_sort_status1.png


BIN
BaseLibrary/src/main/res/drawable-xhdpi/icon_sort_status2.png


BIN
BaseLibrary/src/main/res/drawable-xhdpi/icon_sort_status3.png


BIN
BaseLibrary/src/main/res/drawable-xxhdpi/icon_search.png


BIN
BaseLibrary/src/main/res/drawable-xxhdpi/icon_sort_status1.png


BIN
BaseLibrary/src/main/res/drawable-xxhdpi/icon_sort_status2.png


BIN
BaseLibrary/src/main/res/drawable-xxhdpi/icon_sort_status3.png


+ 6 - 0
BaseLibrary/src/main/res/drawable/shape_e8fffb_14dp_border_2dc7aa_1dp.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <solid android:color="#E8FFFB"/>
+    <corners android:radius="14dp"/>
+    <stroke android:color="@color/color_2dc7aa" android:width="1dp"/>
+</shape>

+ 38 - 0
BaseLibrary/src/main/res/layout/item_common_sort_view_layout.xml

@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:id="@+id/cs_root"
+    android:paddingStart="8dp"
+    android:paddingEnd="8dp"
+    android:layout_marginEnd="10dp"
+    android:paddingTop="6dp"
+    android:paddingBottom="6dp"
+    android:background="@drawable/bg_white_14dp"
+    xmlns:tools="http://schemas.android.com/tools"
+    xmlns:app="http://schemas.android.com/apk/res-auto">
+    <TextView
+        app:layout_constraintRight_toLeftOf="@+id/iv_status"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintTop_toTopOf="parent"
+        android:id="@+id/tv_text"
+        android:textColor="@color/color_333333"
+        tools:text="已上课时"
+        android:includeFontPadding="false"
+        android:textSize="@dimen/sp_12"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"/>
+
+
+    <ImageView
+        app:layout_constraintRight_toRightOf="parent"
+        android:id="@+id/iv_status"
+        android:layout_marginStart="4dp"
+        app:layout_constraintBottom_toBottomOf="@+id/tv_text"
+        app:layout_constraintTop_toTopOf="@+id/tv_text"
+        app:layout_constraintLeft_toRightOf="@+id/tv_text"
+        android:src="@drawable/icon_sort_status1"
+        android:layout_width="6dp"
+        android:layout_height="10dp"/>
+
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 12 - 0
BaseLibrary/src/main/res/layout/view_common_sort_layout.xml

@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<FrameLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content">
+    <com.cooleshow.base.widgets.RecyclerViewAtViewPager2
+        android:layout_width="match_parent"
+        android:scrollbars="none"
+        android:overScrollMode="never"
+        android:id="@+id/recyclerView_item"
+        android:layout_height="wrap_content"/>
+</FrameLayout>

+ 2 - 0
BaseLibrary/src/main/res/values/colors.xml

@@ -224,4 +224,6 @@
     <color name="color_1affffff">#1affffff</color>
     <color name="color_51e1d0">#51e1d0</color>
     <color name="color_ff6827">#FF6827</color>
+    <color name="color_18b99a">#18B99A</color>
+    <color name="color_80000000">#80000000</color>
 </resources>

+ 1 - 0
student/src/main/AndroidManifest.xml

@@ -253,6 +253,7 @@
         <activity
             android:name=".ui.course.AppointmentCourseActivity"
             android:configChanges="orientation|screenSize|keyboardHidden|fontScale|smallestScreenSize|screenLayout|uiMode"
+            android:windowSoftInputMode="adjustPan"
             android:screenOrientation="portrait" />
         <!--        分享开始-->
         <activity

+ 45 - 0
student/src/main/java/com/cooleshow/student/adapter/VIPCourseCourseListAdapter.java

@@ -0,0 +1,45 @@
+package com.cooleshow.student.adapter;
+
+import android.widget.ImageView;
+import android.widget.RatingBar;
+
+import com.chad.library.adapter.base.BaseQuickAdapter;
+import com.chad.library.adapter.base.viewholder.BaseViewHolder;
+import com.cooleshow.base.utils.GlideImageLoaderUtils;
+import com.cooleshow.student.R;
+import com.cooleshow.student.bean.AppointCourseTeacherListBean;
+
+import androidx.annotation.NonNull;
+
+/**
+ * Author by pq, Date on 2024/11/19.
+ */
+public class VIPCourseCourseListAdapter extends BaseQuickAdapter<AppointCourseTeacherListBean.RowsBean, BaseViewHolder> {
+    public VIPCourseCourseListAdapter() {
+        super(R.layout.item_vip_course_list_layout);
+    }
+
+    @Override
+    protected void convert(@NonNull BaseViewHolder holder, AppointCourseTeacherListBean.RowsBean bean) {
+        ImageView iv_avatar = holder.getView(R.id.iv_avatar);
+        GlideImageLoaderUtils.getInstance().loadImage(getContext(), bean.getAvatar(), iv_avatar, R.drawable.icon_teacher_default_head);
+
+        holder.setText(R.id.tv_nickname, bean.getRealName());
+        holder.setText(R.id.tv_des, bean.getSchool() + "·" + bean.getSchoolSubject());
+        holder.setText(R.id.tv_course_num, String.format("已上课时%s节", bean.getExpTime()));
+
+        holder.setText(R.id.tv_price, bean.getSubjectPrice());
+        holder.setText(R.id.tv_time, String.format("/%s分钟", bean.getCourseMinutes()));
+
+        RatingBar rating_bar = holder.getView(R.id.rating_bar);
+        try {
+            String starGrade = bean.getStarGrade();
+            int i = Integer.parseInt(starGrade);
+            rating_bar.setRating(i);
+        } catch (Exception e) {
+            e.printStackTrace();
+            rating_bar.setRating(0);
+        }
+
+    }
+}

+ 9 - 0
student/src/main/java/com/cooleshow/student/api/APIService.java

@@ -12,6 +12,7 @@ import com.cooleshow.base.bean.TeachableInstrumentBean;
 import com.cooleshow.base.data.net.BaseResponse;
 import com.cooleshow.student.bean.AddressBean;
 import com.cooleshow.student.bean.AppHomeBean;
+import com.cooleshow.student.bean.AppointCourseTeacherListBean;
 import com.cooleshow.student.bean.AwardStatusBean;
 import com.cooleshow.student.bean.CountOfUnreadBean;
 import com.cooleshow.student.bean.CourseTableDataBean;
@@ -537,4 +538,12 @@ public interface APIService {
      */
     @GET(STUDENT_GROUP + "student/updateUserCustomerService")
     Observable<BaseResponse<String>> updateUserCustomerService();
+
+    /**
+     *
+     *
+     * @return
+     */
+    @POST(STUDENT_GROUP + "courseSchedule/queryTeacherList")
+    Observable<BaseResponse<AppointCourseTeacherListBean>> getAppointCourseTeachers(@Body RequestBody body);
 }

+ 235 - 0
student/src/main/java/com/cooleshow/student/bean/AppointCourseTeacherListBean.java

@@ -0,0 +1,235 @@
+package com.cooleshow.student.bean;
+
+import java.util.List;
+
+/**
+ * Author by pq, Date on 2024/11/19.
+ */
+public class AppointCourseTeacherListBean {
+
+
+    /**
+     * footer : [{"avatar":"","configSubject":"","courseMinutes":"","expTime":"","realName":"","school":"","schoolSubject":"","starGrade":"","subjectId":0,"subjectName":"","subjectPrice":"","teacherId":0,"userName":""}]
+     * limit : 0
+     * nextPage : 0
+     * offset : 0
+     * pageNo : 0
+     * prePage : 0
+     * rows : [{"avatar":"","configSubject":"","courseMinutes":"","expTime":"","realName":"","school":"","schoolSubject":"","starGrade":"","subjectId":0,"subjectName":"","subjectPrice":"","teacherId":0,"userName":""}]
+     * statInfo : {}
+     * total : 0
+     * totalPage : 0
+     */
+
+    private int limit;
+    private int nextPage;
+    private int offset;
+    private int pageNo;
+    private int prePage;
+    private int total;
+    private int totalPage;
+    private List<RowsBean> rows;
+
+    public int getLimit() {
+        return limit;
+    }
+
+    public void setLimit(int limit) {
+        this.limit = limit;
+    }
+
+    public int getNextPage() {
+        return nextPage;
+    }
+
+    public void setNextPage(int nextPage) {
+        this.nextPage = nextPage;
+    }
+
+    public int getOffset() {
+        return offset;
+    }
+
+    public void setOffset(int offset) {
+        this.offset = offset;
+    }
+
+    public int getPageNo() {
+        return pageNo;
+    }
+
+    public void setPageNo(int pageNo) {
+        this.pageNo = pageNo;
+    }
+
+    public int getPrePage() {
+        return prePage;
+    }
+
+    public void setPrePage(int prePage) {
+        this.prePage = prePage;
+    }
+
+
+    public int getTotal() {
+        return total;
+    }
+
+    public void setTotal(int total) {
+        this.total = total;
+    }
+
+    public int getTotalPage() {
+        return totalPage;
+    }
+
+    public void setTotalPage(int totalPage) {
+        this.totalPage = totalPage;
+    }
+
+
+    public List<RowsBean> getRows() {
+        return rows;
+    }
+
+    public void setRows(List<RowsBean> rows) {
+        this.rows = rows;
+    }
+
+
+    public static class RowsBean {
+        /**
+         * avatar :
+         * configSubject :
+         * courseMinutes :
+         * expTime :
+         * realName :
+         * school :
+         * schoolSubject :
+         * starGrade :
+         * subjectId : 0
+         * subjectName :
+         * subjectPrice :
+         * teacherId : 0
+         * userName :
+         */
+
+        private String avatar;
+        private String configSubject;
+        private String courseMinutes;
+        private String expTime;
+        private String realName;
+        private String school;
+        private String schoolSubject;
+        private String starGrade;
+        private String subjectId;
+        private String subjectName;
+        private String subjectPrice;
+        private String teacherId;
+        private String userName;
+
+        public String getAvatar() {
+            return avatar;
+        }
+
+        public void setAvatar(String avatar) {
+            this.avatar = avatar;
+        }
+
+        public String getConfigSubject() {
+            return configSubject;
+        }
+
+        public void setConfigSubject(String configSubject) {
+            this.configSubject = configSubject;
+        }
+
+        public String getCourseMinutes() {
+            return courseMinutes;
+        }
+
+        public void setCourseMinutes(String courseMinutes) {
+            this.courseMinutes = courseMinutes;
+        }
+
+        public String getExpTime() {
+            return expTime;
+        }
+
+        public void setExpTime(String expTime) {
+            this.expTime = expTime;
+        }
+
+        public String getRealName() {
+            return realName;
+        }
+
+        public void setRealName(String realName) {
+            this.realName = realName;
+        }
+
+        public String getSchool() {
+            return school;
+        }
+
+        public void setSchool(String school) {
+            this.school = school;
+        }
+
+        public String getSchoolSubject() {
+            return schoolSubject;
+        }
+
+        public void setSchoolSubject(String schoolSubject) {
+            this.schoolSubject = schoolSubject;
+        }
+
+        public String getStarGrade() {
+            return starGrade;
+        }
+
+        public void setStarGrade(String starGrade) {
+            this.starGrade = starGrade;
+        }
+
+        public String getSubjectId() {
+            return subjectId;
+        }
+
+        public void setSubjectId(String subjectId) {
+            this.subjectId = subjectId;
+        }
+
+        public String getSubjectName() {
+            return subjectName;
+        }
+
+        public void setSubjectName(String subjectName) {
+            this.subjectName = subjectName;
+        }
+
+        public String getSubjectPrice() {
+            return subjectPrice;
+        }
+
+        public void setSubjectPrice(String subjectPrice) {
+            this.subjectPrice = subjectPrice;
+        }
+
+        public String getTeacherId() {
+            return teacherId;
+        }
+
+        public void setTeacherId(String teacherId) {
+            this.teacherId = teacherId;
+        }
+
+        public String getUserName() {
+            return userName;
+        }
+
+        public void setUserName(String userName) {
+            this.userName = userName;
+        }
+    }
+}

+ 5 - 1
student/src/main/java/com/cooleshow/student/contract/VIPCustomCourseListContract.java

@@ -1,6 +1,7 @@
 package com.cooleshow.student.contract;
 
 import com.cooleshow.base.presenter.view.BaseView;
+import com.cooleshow.student.bean.AppointCourseTeacherListBean;
 import com.cooleshow.student.bean.SelectMyGroupBean;
 
 /**
@@ -10,9 +11,12 @@ public interface VIPCustomCourseListContract {
 
     interface VIPCustomCourseView extends BaseView {
 
+        void onGetTeacherListSuccess(int page, AppointCourseTeacherListBean data);
+
+        void onGetTeacherListError(int page);
+
     }
 
     interface Presenter {
-        void queryVideoCourse(boolean isShowLoading, String studentId,int subjectId, int page);
     }
 }

+ 24 - 9
student/src/main/java/com/cooleshow/student/presenter/course/VIPCustomCourseListPresenter.java

@@ -1,10 +1,13 @@
 package com.cooleshow.student.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.student.api.APIService;
+import com.cooleshow.student.bean.AppointCourseTeacherListBean;
 import com.cooleshow.student.bean.SelectMyGroupBean;
 import com.cooleshow.student.contract.VIPCustomCourseListContract;
 import com.cooleshow.student.contract.VideoCourseContract;
@@ -18,28 +21,40 @@ import org.json.JSONObject;
  */
 public class VIPCustomCourseListPresenter extends BasePresenter<VIPCustomCourseListContract.VIPCustomCourseView> implements VIPCustomCourseListContract.Presenter {
 
-    @Override
-    public void queryVideoCourse(boolean isShowLoading, String studentId,int subjectId, int page) {
+    public void queryCourseTeachers(boolean isShowLoading, String subjectId, String sortField, String sortRule, String search, boolean isRecentFreeTime, int page) {
         if (isShowLoading && getView() != null) {
             getView().showLoading();
         }
         JSONObject jsonObject = new JSONObject();
         try {
-            if (subjectId != 0) {
+            //类型
+            jsonObject.putOpt("courseType", "VIP");
+            if (!TextUtils.isEmpty(subjectId)) {
+                //声部id
                 jsonObject.putOpt("subjectId", subjectId);
             }
-            jsonObject.putOpt("platform", "android");
-            jsonObject.putOpt("version", "1");
+            if (isRecentFreeTime) {
+                //最近三十天有空
+                jsonObject.putOpt("recentFreeTime", isRecentFreeTime);
+            }
+            if (!TextUtils.isEmpty(sortField)) {
+                //排序key
+                jsonObject.putOpt("sortField", sortField);
+                //排序值 ASC DESC
+                jsonObject.putOpt("sortRule", sortRule);
+            }
+            //搜索条件
+            jsonObject.putOpt("search", search);
             jsonObject.putOpt("page", page);
             jsonObject.putOpt("rows", Constants.DEFAULT_DATA_SIZE);
         } catch (JSONException e) {
             e.printStackTrace();
         }
-        addSubscribe(create(APIService.class).selectMyGroup(RequestBodyUtil.convertToRequestBodyJson(jsonObject.toString())), new BaseObserver<SelectMyGroupBean>(getView()) {
+        addSubscribe(create(APIService.class).getAppointCourseTeachers(RequestBodyUtil.convertToRequestBodyJson(jsonObject.toString())), new BaseObserver<AppointCourseTeacherListBean>(getView()) {
             @Override
-            protected void onSuccess(SelectMyGroupBean data) {
+            protected void onSuccess(AppointCourseTeacherListBean data) {
                 if (getView() != null) {
-//                    getView().onGetVideoCourseSuccess(page, data);
+                    getView().onGetTeacherListSuccess(page, data);
                 }
             }
 
@@ -47,7 +62,7 @@ public class VIPCustomCourseListPresenter extends BasePresenter<VIPCustomCourseL
             public void onError(Throwable e) {
                 super.onError(e);
                 if (getView() != null) {
-//                    getView().onGetCourseError(page);
+                    getView().onGetTeacherListError(page);
                 }
             }
         });

+ 43 - 11
student/src/main/java/com/cooleshow/student/ui/course/AppointmentCourseActivity.java

@@ -1,15 +1,22 @@
 package com.cooleshow.student.ui.course;
 
+import android.graphics.Color;
+import android.graphics.Typeface;
 import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.TextView;
 
 import com.alibaba.android.arouter.facade.annotation.Route;
 import com.cooleshow.base.router.RouterPath;
 import com.cooleshow.base.ui.activity.BaseMVPActivity;
 import com.cooleshow.base.ui.fragment.BaseMVPFragment;
 import com.cooleshow.base.utils.helper.QMUIStatusBarHelper;
+import com.cooleshow.student.R;
 import com.cooleshow.student.adapter.MineCoursePagerAdapter;
 import com.cooleshow.student.bean.QuerySubjectBean;
 import com.cooleshow.student.contract.MineCourseContract;
+import com.cooleshow.student.databinding.ActivityAppointmentCourseBinding;
 import com.cooleshow.student.databinding.ActivityMineCourseBinding;
 import com.cooleshow.student.presenter.course.MineCoursePresenter;
 import com.google.android.material.tabs.TabLayout;
@@ -25,12 +32,13 @@ import androidx.viewpager2.widget.ViewPager2;
 
 /**
  * 创建日期:2022/5/30 9:21
- *  约课
+ * 约课
+ *
  * @author Ryan
  * 类说明:
  */
 @Route(path = RouterPath.CourseCenter.APPOINTMENT_COURSE)
-public class AppointmentCourseActivity extends BaseMVPActivity<ActivityMineCourseBinding, MineCoursePresenter> implements MineCourseContract.MineCourseView {
+public class AppointmentCourseActivity extends BaseMVPActivity<ActivityAppointmentCourseBinding, MineCoursePresenter> implements MineCourseContract.MineCourseView {
     public static final String SELECT_POSITION = "selectPosition";
     private TabLayout tabLayout;
     private ViewPager2 viewPager;
@@ -44,6 +52,7 @@ public class AppointmentCourseActivity extends BaseMVPActivity<ActivityMineCours
     @Override
     protected void initView() {
         initMidTitleToolBar(viewBinding.toolbarInclude.toolbar, "约课");
+        viewBinding.toolbarInclude.toolbar.setBackgroundColor(Color.TRANSPARENT);
         tabLayout = viewBinding.tablayout;
         viewPager = viewBinding.viewpager;
         viewPager.setCurrentItem(0);
@@ -57,8 +66,8 @@ public class AppointmentCourseActivity extends BaseMVPActivity<ActivityMineCours
     }
 
     @Override
-    protected ActivityMineCourseBinding getLayoutView() {
-        return ActivityMineCourseBinding.inflate(getLayoutInflater());
+    protected ActivityAppointmentCourseBinding getLayoutView() {
+        return ActivityAppointmentCourseBinding.inflate(getLayoutInflater());
     }
 
     @Override
@@ -70,7 +79,7 @@ public class AppointmentCourseActivity extends BaseMVPActivity<ActivityMineCours
     public void initData() {
         super.initData();
         int selectPosition = getIntent().getIntExtra(SELECT_POSITION, -1);
-        titles = new ArrayList<String>(Arrays.asList("VIP定制课","越纠课", "直播课", "视频课"));
+        titles = new ArrayList<String>(Arrays.asList("VIP定制课", "趣纠课", "直播课", "视频课"));
         initTabLayoutAndViewPager();
         presenter.querySubjectItem();
         if (selectPosition != -1 && selectPosition < fragments.size()) {
@@ -95,22 +104,37 @@ public class AppointmentCourseActivity extends BaseMVPActivity<ActivityMineCours
         MineCoursePagerAdapter mineCoursePageAdapter = new MineCoursePagerAdapter(this);
         mineCoursePageAdapter.setFragments(fragments);
         viewPager.setAdapter(mineCoursePageAdapter);
-        new TabLayoutMediator(tabLayout, viewPager, (tab, position) -> {
+        TabLayoutMediator tabLayoutMediator = new TabLayoutMediator(tabLayout, viewPager, (tab, position) -> {
             //这里需要根据position修改tab的样式和文字等
-            tab.setText(titles.get(position));
-            tab.select();
-        }).attach();
+            createTab(tab, titles.get(position));
+        });
         viewPager.setOffscreenPageLimit(fragments.size());
+        initListener();
+        tabLayoutMediator.attach();
+    }
 
+    private void initListener() {
         tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
             @Override
             public void onTabSelected(TabLayout.Tab tab) {
-                viewPager.setCurrentItem(tab.getPosition());
+                if (tab != null && tab.getCustomView() != null) {
+                    View customView = tab.getCustomView();
+                    TextView tv_text = customView.findViewById(com.cooleshow.chatmodule.R.id.tv_text);
+                    tv_text.setTextSize(16);
+                    tv_text.setTextColor(getResources().getColor(com.cooleshow.base.R.color.color_131415));
+                    tv_text.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD));
+                }
             }
 
             @Override
             public void onTabUnselected(TabLayout.Tab tab) {
-
+                if (tab != null && tab.getCustomView() != null) {
+                    View customView = tab.getCustomView();
+                    TextView tv_text = customView.findViewById(com.cooleshow.chatmodule.R.id.tv_text);
+                    tv_text.setTextSize(16);
+                    tv_text.setTextColor(getResources().getColor(com.cooleshow.base.R.color.color_80000000));
+                    tv_text.setTypeface(Typeface.defaultFromStyle(Typeface.NORMAL));
+                }
             }
 
             @Override
@@ -144,4 +168,12 @@ public class AppointmentCourseActivity extends BaseMVPActivity<ActivityMineCours
             mVideoCourseAppointListFragment.querySubjectItemSuccess(data);
         }
     }
+
+    private TabLayout.Tab createTab(TabLayout.Tab tab, String text) {
+        View view = LayoutInflater.from(this).inflate(R.layout.view_appoint_course_tab_layout, null);
+        TextView tv_text = view.findViewById(R.id.tv_text);
+        tv_text.setText(text);
+        tab.setCustomView(view);
+        return tab;
+    }
 }

+ 138 - 8
student/src/main/java/com/cooleshow/student/ui/course/VIPCustomCourseListFragment.java

@@ -7,26 +7,47 @@ import android.widget.TextView;
 import com.bigkoo.pickerview.builder.OptionsPickerBuilder;
 import com.bigkoo.pickerview.listener.OnDismissListener;
 import com.bigkoo.pickerview.view.OptionsPickerView;
+import com.cooleshow.base.bean.DataSortBean;
+import com.cooleshow.base.constanst.Constants;
+import com.cooleshow.base.constanst.DataSortType;
 import com.cooleshow.base.ui.fragment.BaseMVPFragment;
+import com.cooleshow.base.utils.LOG;
 import com.cooleshow.base.utils.UiUtils;
+import com.cooleshow.base.widgets.CommonSortView;
+import com.cooleshow.base.widgets.EmptyViewLayout;
 import com.cooleshow.student.R;
+import com.cooleshow.student.adapter.VIPCourseCourseListAdapter;
+import com.cooleshow.student.bean.AppointCourseTeacherListBean;
 import com.cooleshow.student.bean.QuerySubjectBean;
+import com.cooleshow.student.contract.VIPCustomCourseListContract;
 import com.cooleshow.student.databinding.FgVipCustomCourseListLayoutBinding;
 import com.cooleshow.student.presenter.course.VIPCustomCourseListPresenter;
+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.List;
 
+import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.LinearLayoutManager;
+
 /**
  * Author by pq, Date on 2024/11/13.
  * VIP定制课约课
  */
-public class VIPCustomCourseListFragment extends BaseMVPFragment<FgVipCustomCourseListLayoutBinding, VIPCustomCourseListPresenter> implements View.OnClickListener {
+public class VIPCustomCourseListFragment extends BaseMVPFragment<FgVipCustomCourseListLayoutBinding, VIPCustomCourseListPresenter> implements View.OnClickListener, VIPCustomCourseListContract.VIPCustomCourseView {
     private List<QuerySubjectBean> subjectList = new ArrayList<>();
     private OptionsPickerView pvOptions;
     private int currentSelectSubjectPosition = -1;
     private String currentSubjectId;
-    private int currentPage =1;
+    private String sortField;
+    private String sortRule;
+    private boolean isRecentFreeTime;
+    private String searchCondition;
+    private int currentPage = 1;
+    private VIPCourseCourseListAdapter mAdapter;
+    private boolean hasNext = true;
 
     public static VIPCustomCourseListFragment newInstance() {
         VIPCustomCourseListFragment fragment = new VIPCustomCourseListFragment();
@@ -40,16 +61,67 @@ public class VIPCustomCourseListFragment extends BaseMVPFragment<FgVipCustomCour
 
     @Override
     protected void initView(View rootView) {
-
     }
 
     @Override
     protected void initData() {
         initListener();
+        DataSortBean dataSortBean = new DataSortBean(DataSortType.RECENT_FREE_TIME);
+        DataSortBean dataSortBean2 = new DataSortBean(DataSortType.HAS_COURSE);
+        DataSortBean dataSortBean3 = new DataSortBean(DataSortType.COURSE_PRICE);
+        DataSortBean dataSortBean4 = new DataSortBean(DataSortType.COURSE_MARK);
+        ArrayList<DataSortBean> list = new ArrayList();
+        list.add(dataSortBean);
+        list.add(dataSortBean2);
+        list.add(dataSortBean3);
+        list.add(dataSortBean4);
+        mViewBinding.sortView.setData(list);
+
+        mAdapter = new VIPCourseCourseListAdapter();
+        EmptyViewLayout emptyViewLayout = new EmptyViewLayout(getContext());
+        emptyViewLayout.setContent(com.cooleshow.base.R.drawable.icon_empty_course, "暂无课程");
+        mViewBinding.recyclerViewList.setLayoutManager(new LinearLayoutManager(getContext()));
+        mViewBinding.recyclerViewList.setAdapter(mAdapter);
+        mAdapter.setEmptyView(emptyViewLayout);
+
+        getData(true);
     }
 
-    private void initListener(){
+    private void initListener() {
         mViewBinding.tvFilter.setOnClickListener(this);
+        mViewBinding.tvSearch.setOnClickListener(this);
+        mViewBinding.refreshLayout.setRefreshFooter(new ClassicsFooter(getContext()).setDrawableSize(20));
+        mViewBinding.refreshLayout.setOnRefreshListener(new OnRefreshListener() {
+            @Override
+            public void onRefresh(@NonNull RefreshLayout refreshLayout) {
+                currentPage = 1;
+                getData(false);
+            }
+        });
+        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();
+                }
+            }
+        });
+
+        mViewBinding.sortView.setEventListener(new CommonSortView.OnEventListener() {
+            @Override
+            public void onFilterResult(boolean isRecentFreeTime, String sortField, String sortRule) {
+                VIPCustomCourseListFragment.this.isRecentFreeTime = isRecentFreeTime;
+                VIPCustomCourseListFragment.this.sortField = sortField;
+                VIPCustomCourseListFragment.this.sortRule = sortRule;
+                currentPage = 1;
+                getData(false);
+            }
+        });
+
     }
 
     @Override
@@ -66,24 +138,29 @@ public class VIPCustomCourseListFragment extends BaseMVPFragment<FgVipCustomCour
     @Override
     public void onClick(View v) {
         int id = v.getId();
-        if(id == R.id.tv_filter){
+        if (id == R.id.tv_filter) {
             selectSubjectType();
             return;
         }
+        if (id == R.id.tv_search) {
+            searchCondition = mViewBinding.etTargetName.getText().toString().trim();
+            getData(false);
+            return;
+        }
     }
 
     private void selectSubjectType() {
-        if (subjectList.size() <= 0) {
+        if (subjectList.size() == 0) {
             return;
         }
-        if(pvOptions == null){
+        if (pvOptions == null) {
             pvOptions = new OptionsPickerBuilder(getContext(), (options1, options2, options3, v) -> {
                 this.currentSelectSubjectPosition = options1;
                 QuerySubjectBean subjectBean = subjectList.get(options1);
                 this.currentSubjectId = subjectBean.getId();
                 mViewBinding.tvFilter.setText(subjectBean.getPickerViewText());
                 currentPage = 1;
-                getData(true);
+                getData(false);
             }).setLayoutRes(com.cooleshow.base.R.layout.pickerview_select_options_layout, v -> {
                         //自定义布局中的控件初始化及事件处理
                         final TextView tvSubmit = (TextView) v.findViewById(com.cooleshow.base.R.id.tv_finish);
@@ -118,6 +195,59 @@ public class VIPCustomCourseListFragment extends BaseMVPFragment<FgVipCustomCour
     }
 
     private void getData(boolean isShowLoading) {
+        presenter.queryCourseTeachers(isShowLoading, currentSubjectId, sortField, sortRule, searchCondition, isRecentFreeTime, currentPage);
+    }
+
+    @Override
+    public void onGetTeacherListSuccess(int page, AppointCourseTeacherListBean dataList) {
+        if (isDetached()) {
+            return;
+        }
+        LOG.i("pq", "queryGroupNoticeSuccess:" + 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();
+                    }
+                }
+            }
+        }
+
+    }
 
+    private void checkHasNext(int dataSize) {
+        hasNext = dataSize >= Constants.DEFAULT_DATA_SIZE;
+    }
+
+    @Override
+    public void onGetTeacherListError(int page) {
+        if (isDetached()) {
+            return;
+        }
+        if (page == 1) {
+            mViewBinding.refreshLayout.finishRefresh();
+        } else {
+            if (mAdapter != null) {
+                currentPage--;
+                mViewBinding.refreshLayout.finishLoadMore(false);
+            }
+        }
     }
 }

BIN
student/src/main/res/drawable-xhdpi/bg_appointment_top.png


BIN
student/src/main/res/drawable-xhdpi/icon_course_completed_tag.png


BIN
student/src/main/res/drawable-xxhdpi/bg_appointment_top.png


BIN
student/src/main/res/drawable-xxhdpi/icon_course_completed_tag.png


+ 20 - 0
student/src/main/res/drawable/appoint_course_tab_indicator.xml

@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="rectangle">
+
+    <item
+        android:gravity="center">
+        <shape>
+
+            <size
+                android:width="16dp"
+                android:height="4dp" />
+
+            <corners android:radius="2dp" />
+
+            <solid android:color="@color/color_2dc7aa" />
+
+        </shape>
+    </item>
+
+</layer-list>

+ 27 - 11
student/src/main/res/layout/activity_appointment_course.xml

@@ -1,38 +1,54 @@
 <?xml version="1.0" encoding="utf-8"?>
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<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:layout_height="match_parent"
+    android:background="@color/color_f6f8f9"
     android:orientation="vertical">
 
+    <ImageView
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:adjustViewBounds="true"
+        android:src="@drawable/bg_appointment_top"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
+
     <include
         android:id="@+id/toolbar_include"
         layout="@layout/common_toolbar_layout" />
 
     <com.google.android.material.tabs.TabLayout
         android:id="@+id/tablayout"
-        android:background="@color/white"
-        android:layout_width="match_parent"
+        android:layout_width="wrap_content"
         android:layout_height="@dimen/dp_44"
         android:scrollbars="none"
+        app:layout_constraintRight_toRightOf="parent"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/toolbar_include"
         app:tabBackground="@null"
         app:tabGravity="fill"
-        app:tabIndicator="@drawable/tab_indicator"
+        app:tabPaddingStart="0dp"
+        app:tabPaddingEnd="0dp"
+        app:tabIndicator="@drawable/appoint_course_tab_indicator"
         app:tabIndicatorColor="@color/color_2dc7aa"
         app:tabIndicatorFullWidth="false"
         app:tabIndicatorHeight="4dp"
-        app:tabMode="fixed"
+        app:tabMode="scrollable"
         app:tabRippleColor="@null"
-        app:tabSelectedTextColor="@color/black_333"
+        app:tabSelectedTextColor="@color/color_131415"
         app:tabTextAppearance="@style/tab_layout_style"
-        app:tabTextColor="@color/color_666666" />
-
+        app:tabTextColor="@color/color_80000000" />
 
 
     <androidx.viewpager2.widget.ViewPager2
+        app:layout_constraintBottom_toBottomOf="parent"
         android:id="@+id/viewpager"
         android:layout_width="match_parent"
-        android:overScrollMode="never"
         android:layout_height="0dp"
-        android:layout_weight="1" />
-</LinearLayout>
+        android:layout_weight="1"
+        android:overScrollMode="never"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintRight_toRightOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/tablayout" />
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 17 - 47
student/src/main/res/layout/fg_vip_custom_course_list_layout.xml

@@ -2,6 +2,7 @@
 <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="12dp"
     android:layout_height="match_parent">
 
     <TextView
@@ -55,7 +56,8 @@
         android:includeFontPadding="false"
         android:maxLines="1"
         android:paddingStart="8dp"
-        android:textColor="@color/color_999999"
+        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"
@@ -79,68 +81,36 @@
         app:layout_constraintRight_toRightOf="@+id/view_search_bg"
         app:layout_constraintTop_toTopOf="@+id/view_search_bg" />
 
-    <RadioGroup
-        android:id="@+id/rg_filter"
+    <com.cooleshow.base.widgets.CommonSortView
         android:layout_width="match_parent"
-        android:layout_height="40dp"
-        android:orientation="horizontal"
+        android:id="@+id/sort_view"
+        android:layout_marginTop="12dp"
+        android:layout_marginStart="14dp"
         app:layout_constraintLeft_toLeftOf="parent"
         app:layout_constraintRight_toRightOf="parent"
-        app:layout_constraintTop_toBottomOf="@+id/view_search_bg">
+        app:layout_constraintTop_toBottomOf="@+id/view_search_bg"
+        android:layout_height="wrap_content"/>
 
-        <RadioButton
-            android:layout_width="wrap_content"
-            android:layout_height="match_parent"
-            android:button="@null"
-            android:paddingStart="5dp"
-            android:paddingEnd="5dp"
-            android:text="仅看未来30天有空" />
-
-        <RadioButton
-            android:layout_width="wrap_content"
-            android:layout_height="match_parent"
-            android:button="@null"
-            android:paddingStart="5dp"
-            android:paddingEnd="5dp"
-            android:text="已上课时" />
-
-        <RadioButton
-            android:layout_width="wrap_content"
-            android:layout_height="match_parent"
-            android:button="@null"
-            android:paddingStart="5dp"
-            android:paddingEnd="5dp"
-            android:text="课时单价" />
-
-        <RadioButton
-            android:layout_width="wrap_content"
-            android:layout_height="match_parent"
-            android:button="@null"
-            android:paddingStart="5dp"
-            android:paddingEnd="5dp"
-            android:text="评分" />
-    </RadioGroup>
 
     <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/rg_filter"
-        app:srlEnableLoadMore="false">
+        app:layout_constraintTop_toBottomOf="@+id/sort_view"
+        app:srlEnableLoadMore="true">
 
         <androidx.recyclerview.widget.RecyclerView
-            android:id="@+id/recyclerView"
+            android:id="@+id/recyclerView_list"
+            android:layout_marginEnd="14dp"
+            android:layout_marginTop="12dp"
+            android:layout_marginStart="14dp"
             android:layout_width="match_parent"
             android:layout_height="match_parent"
             android:overScrollMode="never"
-            android:scrollbars="none"
-            app:layout_constraintBottom_toBottomOf="parent"
-            app:layout_constraintEnd_toStartOf="@id/liv_letters"
-            app:layout_constraintStart_toStartOf="parent"
-            app:layout_constraintTop_toBottomOf="@id/view_search_bg"
-            app:layout_constraintVertical_bias="0.0" />
+            android:scrollbars="none" />
     </com.scwang.smart.refresh.layout.SmartRefreshLayout>
 
 </androidx.constraintlayout.widget.ConstraintLayout>

+ 138 - 0
student/src/main/res/layout/item_vip_course_list_layout.xml

@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_marginBottom="12dp"
+    android:padding="12dp"
+    android:background="@drawable/bg_white_10dp"
+    android:layout_height="wrap_content">
+    <com.cooleshow.base.widgets.QMUIRadiusImageView
+        android:layout_width="70dp"
+        android:id="@+id/iv_avatar"
+        app:qmui_corner_radius="6dp"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintTop_toTopOf="parent"
+        android:layout_height="70dp"/>
+
+    <TextView
+        app:layout_constraintRight_toLeftOf="@+id/rating_bar"
+        android:id="@+id/tv_nickname"
+        app:layout_constraintTop_toTopOf="@+id/iv_avatar"
+        app:layout_constraintLeft_toRightOf="@+id/iv_avatar"
+        android:includeFontPadding="false"
+        tools:text="名称"
+        android:textStyle="bold"
+        android:layout_marginStart="12dp"
+        android:textColor="@color/color_131415"
+        android:textSize="@dimen/sp_16"
+        android:layout_width="0dp"
+        android:maxLines="1"
+        android:ellipsize="end"
+        app:layout_constraintVertical_chainStyle="packed"
+        app:layout_constraintBottom_toTopOf="@+id/tv_des"
+        android:layout_height="wrap_content"/>
+
+    <RatingBar
+        android:layout_marginStart="8dp"
+        android:id="@+id/rating_bar"
+        style="@style/HomeRatingBar"
+        android:layout_width="wrap_content"
+        android:layout_height="19dp"
+        android:isIndicator="true"
+        android:numStars="5"
+        android:rating="0"
+        android:stepSize="1"
+        android:visibility="visible"
+        app:layout_constraintRight_toRightOf="parent"
+        app:layout_constraintBottom_toBottomOf="@+id/tv_nickname"
+        app:layout_constraintLeft_toRightOf="@+id/tv_nickname"
+        app:layout_constraintTop_toTopOf="@+id/tv_nickname" />
+
+    <TextView
+        app:layout_constraintRight_toRightOf="parent"
+        android:layout_marginTop="6dp"
+        app:layout_constraintBottom_toTopOf="@+id/tv_course_num"
+        android:id="@+id/tv_des"
+        app:layout_constraintLeft_toLeftOf="@+id/tv_nickname"
+        app:layout_constraintTop_toBottomOf="@+id/tv_nickname"
+        android:includeFontPadding="false"
+        tools:text="中国音乐学院"
+        android:textColor="@color/color_333333"
+        android:textSize="@dimen/sp_13"
+        android:layout_width="0dp"
+        android:maxLines="1"
+        android:ellipsize="end"
+        android:layout_height="wrap_content"/>
+
+
+    <ImageView
+        app:layout_constraintBottom_toBottomOf="@+id/tv_course_num"
+        app:layout_constraintTop_toTopOf="@+id/tv_course_num"
+        android:id="@+id/iv_course_tag"
+        app:layout_constraintLeft_toLeftOf="@+id/tv_nickname"
+        android:src="@drawable/icon_course_completed_tag"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"/>
+
+    <TextView
+        android:layout_marginTop="8dp"
+        android:paddingStart="4dp"
+        app:layout_constraintLeft_toRightOf="@+id/iv_course_tag"
+        android:id="@+id/tv_course_num"
+        app:layout_constraintTop_toBottomOf="@+id/tv_des"
+        android:includeFontPadding="false"
+        tools:text="已上课时34节"
+        android:gravity="center"
+        app:layout_constraintBottom_toBottomOf="@+id/iv_avatar"
+        android:textColor="@color/color_999999"
+        android:textSize="@dimen/sp_12"
+        android:layout_width="0dp"
+        android:maxLines="1"
+        android:ellipsize="end"
+        android:layout_height="wrap_content"/>
+
+    <TextView
+        android:id="@+id/tv_price_unit"
+        app:layout_constraintRight_toLeftOf="@+id/tv_price"
+        app:layout_constraintBaseline_toBaselineOf="@+id/tv_price"
+        tools:text="¥"
+        android:text="¥"
+        android:textColor="@color/color_f44541"
+        android:textSize="@dimen/sp_14"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        tools:ignore="MissingConstraints" />
+
+    <TextView
+        android:paddingStart="3dp"
+        android:layout_marginTop="2dp"
+        android:id="@+id/tv_price"
+        app:layout_constraintRight_toLeftOf="@+id/tv_time"
+        app:layout_constraintBaseline_toBaselineOf="@+id/tv_time"
+        tools:text="280"
+        android:textColor="@color/color_f44541"
+        android:textSize="@dimen/sp_18"
+        android:textStyle="bold"
+        android:includeFontPadding="false"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        tools:ignore="MissingConstraints" />
+
+
+    <TextView
+        android:paddingStart="2dp"
+        android:layout_marginTop="6dp"
+        android:id="@+id/tv_time"
+        app:layout_constraintBottom_toBottomOf="@+id/tv_course_num"
+        app:layout_constraintTop_toTopOf="@+id/tv_course_num"
+        app:layout_constraintRight_toRightOf="parent"
+        tools:text="/25分钟"
+        android:includeFontPadding="false"
+        android:textColor="@color/color_999999"
+        android:textSize="@dimen/sp_12"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        tools:ignore="MissingConstraints" />
+
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 19 - 0
student/src/main/res/layout/view_appoint_course_tab_layout.xml

@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_gravity="center"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content">
+    <TextView
+        android:paddingStart="15dp"
+        android:paddingEnd="15dp"
+        tools:text="哈哈"
+        android:gravity="center"
+        android:layout_gravity="center"
+        android:includeFontPadding="false"
+        android:textSize="@dimen/sp_16"
+        android:textColor="@color/color_666666"
+        android:id="@+id/tv_text"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"/>
+</FrameLayout>

+ 3 - 3
teacher/src/main/java/com/cooleshow/teacher/bean/VideoCourseListBean.java

@@ -129,14 +129,14 @@ public class VideoCourseListBean {
         public String updateTime;
         public String username;
         public String payType;
-        public String musicScoreNum;
+        public String musicNum;
 
         public String getMusicScoreNum() {
-            return musicScoreNum;
+            return musicNum;
         }
 
         public void setMusicScoreNum(String musicScoreNum) {
-            this.musicScoreNum = musicScoreNum;
+            this.musicNum = musicScoreNum;
         }
     }
 }

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

@@ -61,7 +61,7 @@
             android:drawableStart="@drawable/icon_vip_course_setting_time_tag"
             android:textSize="@dimen/sp_16"
             android:textColor="@color/color_333333"
-            android:text="课程时长"
+            android:text="单课时时长"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"/>
 

+ 5 - 4
teacher/src/main/res/layout/item_hp_vip_course_list_layout.xml

@@ -43,7 +43,7 @@
         app:layout_constraintLeft_toLeftOf="@+id/tv_title"
         tools:text="¥"
         android:text="¥"
-        android:textColor="@color/color_ff6827"
+        android:textColor="@color/color_f44541"
         android:textSize="@dimen/sp_14"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
@@ -57,8 +57,9 @@
         app:layout_constraintTop_toBottomOf="@+id/tv_title"
         app:layout_constraintLeft_toRightOf="@+id/tv_price_unit"
         tools:text="280"
-        android:textColor="@color/color_ff6827"
-        android:textSize="@dimen/sp_20"
+        android:textStyle="bold"
+        android:textColor="@color/color_f44541"
+        android:textSize="@dimen/sp_18"
         android:includeFontPadding="false"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
@@ -74,7 +75,7 @@
         tools:text="/25分钟"
         android:includeFontPadding="false"
         android:textColor="@color/color_999999"
-        android:textSize="@dimen/sp_14"
+        android:textSize="@dimen/sp_12"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         tools:ignore="MissingConstraints" />