Commit 94f80724 by 严久程

课程模块

parent 878ea97f
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'
android {
compileSdkVersion rootProject.ext.android["compileSdkVersion"]
buildToolsVersion rootProject.ext.android["buildToolsVersion"]
defaultConfig {
minSdkVersion rootProject.ext.android["minSdkVersion"]
targetSdkVersion rootProject.ext.android["targetSdkVersion"]
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
javaCompileOptions {
annotationProcessorOptions {
arguments = [AROUTER_MODULE_NAME: "course"]
}
}
flavorDimensions "versionCode"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
publishNonDefault true
productFlavors {
ydl {}
xlzx {}
}
sourceSets {
main {
manifest.srcFile 'src/main/AndroidManifest.xml'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:28.0.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
kapt 'com.alibaba:arouter-compiler:1.2.2'
implementation 'com.jakewharton:butterknife:8.8.1'
api rootProject.ext.dependencies["ydl-user-router"]
if (rootProject.ext.dev_mode){
//开发时使用
implementation modularPublication('com.ydl:m-user-api')
api project(":ydl-webview")
api project(":ydl-platform")
} else {
//发布时使用
compileOnly rootProject.ext.dependencies["ydl-m-user-api"]
api rootProject.ext.dependencies["ydl-webview"]
api(rootProject.ext.dependencies["ydl-platform"]) {
transitive = true
}
}
}
modular {
//模块包名
packageName "com.yidianling.course"
// 模块发布需要的参数
publish {
modules {
xlzx {
groupId = "com.ydl"
artifactId = "m-course-module-xlzx"
// 上报的 心理咨询 业务模块 aar 包的版本号
version = "0.0.11"
}
ydl{
groupId = "com.ydl"
artifactId = "m-course-module-ydl"
// 上报的 壹点灵 业务模块 aar 包的版本号
version = "0.0.11"
}
}
api {
// 壹点灵/心理咨询 业务模块 API层 jar包的发布信息
groupId = "com.ydl"
artifactId = "m-course-api"
//开发时注释掉版本号,发布api时打开
//version = "0.0.1"
// API 层打包时需要引入的依赖
apiDependencies {
implementation "com.google.code.gson:gson:2.8.2"
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'com.alibaba:arouter-api:1.4.1'
}
}
}
}
\ No newline at end of file
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.yidianling.course"/>
package com.yidianling.course;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
import butterknife.BindView;
import butterknife.ButterKnife;
import com.alibaba.android.arouter.facade.annotation.Route;
import com.ydl.ydlcommon.base.BaseActivity;
import com.yidianling.course.courseNew.home.CourseHomeFragment;
import com.yidianling.course.courseNew.mine.MyCourseActivity;
import com.yidianling.course.router.CourseIn;
import com.yidianling.course.widget.SearchBarView;
/**
* 课程首页Activity(心理课程)
*/
@Route(path = "/course/home")
public class CourseActivity extends BaseActivity {
@BindView(R2.id.content)
FrameLayout content;
@BindView(R2.id.img_music)
ImageView imgMusic;
@BindView(R2.id.iv_back)
ImageView ivBack;
@BindView(R2.id.tv_left_menu)
TextView leftMenu;
@BindView(R2.id.activity_course_search_bar)
SearchBarView activityCourseSearchBar;
private boolean isSplash;//是否从启动页进入
private final static String TAB = "tab";
public final static int TAB0 = 0;
private static final String IS_SPLASH = "isSplash";
public static void start(Context context, int tab) {
Intent intent = new Intent(context, CourseActivity.class);
Bundle bundle = new Bundle();
bundle.putInt(TAB, tab);
intent.putExtra("bundle", bundle);
context.startActivity(intent);
}
@Override
protected int layoutResId() {
return R.layout.activity_course;
}
@Override
protected void initDataAndEvent() {
ButterKnife.bind(this);
Bundle bundle = getIntent().getBundleExtra("bundle");
if (bundle != null) {
isSplash = bundle.getBoolean("isSplash", false);
}
activityCourseSearchBar.initBarType(SearchBarView.JUMP_TO_SEARCH_COURSE, null);
init();
}
private void init() {
initTags();
ivBack.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
imgMusic.setOnClickListener(v -> {
if (YDLMusicHelper.INSTANCE.isCoursePlaying()) {
//课程播放页
YDLMusicHelper.INSTANCE.startCoursePlayActivity(getMContext(), 1, 0, "", false);
} else {
imgMusic.setVisibility(View.GONE);
}
});
leftMenu.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (CourseIn.INSTANCE.isLogin()) {
MyCourseActivity.start(CourseActivity.this);
} else {
startActivity(CourseIn.INSTANCE.loginWayIntent(CourseActivity.this));
}
}
});
}
/**
* 初始化tab
*/
private void initTags() {
Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.content);
if (fragment == null) {
fragment = new CourseHomeFragment();
getSupportFragmentManager().beginTransaction()
.add(R.id.content, fragment)
.commit();
}
}
@Override
protected void onResume() {
super.onResume();
if (YDLMusicHelper.INSTANCE.isCoursePlaying()) {
imgMusic.setVisibility(View.VISIBLE);
} else {
imgMusic.setVisibility(View.GONE);
}
}
public void disPro() {
dismissProgressDialog();
}
@Override
public void onBackPressed() {
super.onBackPressed();
if (isSplash) {
startActivity(CourseIn.INSTANCE.mainIntent(this));
finish();
}
}
}
package com.yidianling.course
import com.yidianling.ydlcommon.http.YdlRetrofitUtils
import com.yidianling.ydlcommon.router.YdlCommonOut
class CourseConstants {
companion object {
var EXPERT_HOME = YdlCommonOut.API_HOST_H5 + "experts/"
const val ALL_COURSE = YdlCommonOut.API_HOST + "course/list"
const val COURSE_PAGE_SIZE = 20
//课程详情H5地址
var COURSE_DETAIL_H5 = YdlRetrofitUtils.MH5_URL + "course/Detail/v2/"
//课程评价页面
var COURSE_COMMENT_H5 = YdlRetrofitUtils.MH5_URL + "course/all-comments/"
}
}
\ No newline at end of file
package com.yidianling.course;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import com.yidianling.course.coursePlay.moudle.Course;
import com.yidianling.ydlcommon.adapter.CommonAdapter;
/**
* Created by zqk on 6/22/17.
*/
public class CourseListAdapter extends CommonAdapter<Course> {
private Context context;
public CourseListAdapter(Context context) {
this.context = context;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = new CourseListItemView(context);
}
((CourseListItemView) convertView).setData(mDataList.get(position));
return convertView;
}
}
package com.yidianling.course;
import android.graphics.Color;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.text.TextUtils;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import com.google.gson.Gson;
import com.yidianling.common.tools.LogUtil;
import com.yidianling.course.courseNew.LoadMoreView;
import com.yidianling.course.courseNew.courseList.BaseLazyFragment;
import com.yidianling.course.coursePlay.common.net.RetrofitUtils;
import com.yidianling.course.coursePlay.http.CourseListDataManager;
import com.yidianling.course.coursePlay.moudle.Course;
import com.yidianling.course.coursePlay.moudle.CourseListDataBean;
import com.yidianling.course.router.CourseIn;
import com.yidianling.ydlcommon.data.ShareData;
import com.yidianling.ydlcommon.h5.H5Params;
import com.yidianling.ydlcommon.h5.NewH5Activity;
import com.yidianling.ydlcommon.http.RxUtils;
import com.yidianling.ydlcommon.http.YdlRetrofitUtils;
import com.yidianling.ydlcommon.tool.BuryPointUtils;
import com.yidianling.ydlcommon.utils.UMEventUtils;
import com.yidianling.ydlcommon.utils.YDLCacheUtils;
import java.net.ConnectException;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeoutException;
import butterknife.BindView;
import butterknife.OnClick;
import butterknife.OnItemClick;
import in.srain.cube.views.loadmore.LoadMoreContainer;
import in.srain.cube.views.loadmore.LoadMoreHandler;
import in.srain.cube.views.loadmore.LoadMoreListViewContainer;
import in.srain.cube.views.ptr.PtrDefaultHandler;
import in.srain.cube.views.ptr.PtrFrameLayout;
import in.srain.cube.views.ptr.PtrHandler;
import in.srain.cube.views.ptr.header.MaterialHeader;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
/**
* A simple {@link Fragment} subclass.
* 咨询师课程列表页
*/
public class CourseListFragment extends BaseLazyFragment implements PtrHandler, LoadMoreHandler {
@BindView(R2.id.lv_content)
ListView lvContent;
@BindView(R2.id.load_more_list_view_container)
LoadMoreListViewContainer loadMoreListViewContainer;
@BindView(R2.id.store_house_ptr_frame)
PtrFrameLayout storeHousePtrFrame;
@BindView(R2.id.tv_course_list_empty_prompt)
TextView emptyTv;
@BindView(R2.id.iv_course_list_empty_view)
ImageView ivEmptyView;
@BindView(R2.id.ll_pay_type)
LinearLayout llPayType;
@BindView(R2.id.tv_pay_type_free)
TextView payTypeFree;
@BindView(R2.id.tv_paied_type)
TextView paiedCourse;
private int page = 0;
private boolean hasMore = true;
private int tagId;
private CourseListAdapter adapter;
/**
* 是否免费(默认付费)
*/
private int childType = TYPE_PAY;
/**
* 1.免费 2.付费
*/
private static final int TYPE_PAY = 2;
private static final int TYPE_FREE = 1;
private boolean isPrepared;
public CourseListFragment() {
// Required empty public constructor
}
public static CourseListFragment newInstance(int tagId) {
Bundle args = new Bundle();
args.putInt("tagId", tagId);
CourseListFragment fragment = new CourseListFragment();
fragment.setArguments(args);
return fragment;
}
public static CourseListFragment newInstance(int tagId, int childType) {
Bundle args = new Bundle();
args.putInt("tagId", tagId);
args.putInt("childType", childType);
CourseListFragment fragment = new CourseListFragment();
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
tagId = getArguments().getInt("tagId");
childType = getArguments().getInt("childType");
}
}
@Override
public void afterViewCreated(View view, Bundle savedInstanceState) {
isPrepared = true; //View创建完成
LogUtil.i("afterViewCreated id: " + tagId);
if (!isUseLazyMode) {
isVisible = true;
}
lazyLoad();
}
@Override
public int getLayoutId() {
return R.layout.fragment_course_list;
}
@Override
public void lazyLoad() {
if (!isPrepared || !isVisible) {
return;
}
LogUtil.i("lazy load tagid: " + tagId);
if (childType == TYPE_PAY) { //付费
llPayType.setVisibility(View.VISIBLE);
payTypeFree.setSelected(false);
payTypeFree.setTextColor(Color.parseColor("#909599"));
paiedCourse.setSelected(true);
paiedCourse.setTextColor(Color.parseColor("#ffffff"));
} else if (childType == TYPE_FREE) { //免费
llPayType.setVisibility(View.VISIBLE);
payTypeFree.setSelected(true);
payTypeFree.setTextColor(Color.parseColor("#ffffff"));
paiedCourse.setSelected(false);
paiedCourse.setTextColor(Color.parseColor("#909599"));
}
init();
isPrepared = false;
}
@Override
public void onResume() {
super.onResume();
}
private void init() {
// header
final MaterialHeader header = new MaterialHeader(getActivity());
int[] colors = getResources().getIntArray(R.array.ydl_colors);
header.setColorSchemeColors(colors);
header.setLayoutParams(new PtrFrameLayout.LayoutParams(-1, -2));
int padding = (int) getActivity().getResources().getDimension(R.dimen.default_dis_size);
header.setPadding(0, padding, 0, padding);
header.setPtrFrameLayout(storeHousePtrFrame);
storeHousePtrFrame.setHeaderView(header);
storeHousePtrFrame.setPtrHandler(this);
storeHousePtrFrame.addPtrUIHandler(header);
// 使用默认样式
// loadMoreListViewContainer.useDefaultHeader();
LoadMoreView footerView = new LoadMoreView(getContext());
loadMoreListViewContainer.setLoadMoreView(footerView);
loadMoreListViewContainer.setLoadMoreUIHandler(footerView);
footerView.onLoading(loadMoreListViewContainer);
loadMoreListViewContainer.setLoadMoreHandler(this);
adapter = new CourseListAdapter(getActivity());
lvContent.setAdapter(adapter);
localData();
getData(false);
}
/**
* 加载本地缓存数据
*/
private void localData() {
}
/**
* 更新缓存
* @param dataBean
*/
private void updateCache(CourseListDataBean dataBean){
String json = new Gson().toJson(dataBean);
if (!TextUtils.isEmpty(json)){
YDLCacheUtils.Companion.saveCourseListData(json);
}
}
private void getData(boolean loadMore) {
switch (tagId) {
case 1:
case 2:
if (!CourseIn.INSTANCE.isLogin()) {
return;
}
break;
default:
break;
}
if (loadMore && !hasMore) {
loadMoreListViewContainer.loadMoreFinish(false, false);
return;
}
if (loadMore) {
page++;
} else {
page = 1;
hasMore = true;
}
getCourses(loadMore);
}
private void getCourses(final boolean loadMore) {
StringBuffer sb = new StringBuffer();
if (tagId >= 10) {
sb.append("&page=").append(page).append("&listType=").append(tagId);
if (childType != -1){
sb.append("&isFree=").append(childType);
}
} else {
sb.append("&page=").append(page)
.append("&listType=").append(tagId+1);
}
String urlParams = YdlRetrofitUtils.getCommonParam() + sb.toString();
CourseListDataManager.INSTANCE.getHttp().getCourseList(urlParams).compose(RxUtils.resultJavaData()).subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(resp -> {
lvContent.setVisibility(View.VISIBLE);
emptyTv.setVisibility(View.GONE);
ivEmptyView.setVisibility(View.GONE);
if (getActivity() instanceof CourseActivity)
((CourseActivity) getActivity()).disPro();
if (loadMoreListViewContainer != null) {
loadMoreListViewContainer.loadMoreFinish(false, true);
}
try {
List<Course> courses = new ArrayList<>();
courses.addAll(resp.getList());
if (courses == null || courses.size() < CourseConstants.COURSE_PAGE_SIZE) {
hasMore = false;
}
if (!loadMore) {
if (courses != null) {
//更新缓存
updateCache(resp);
adapter.setDataList(courses);
adapter.notifyDataSetChanged();
}
} else if (courses != null) {
adapter.addDataList(courses);
adapter.notifyDataSetChanged();
}
isShowEmptyView();
} catch (Exception e) {
LogUtil.e(e.toString());
}
}, throwable -> {
if (throwable instanceof TimeoutException || throwable instanceof ConnectException || throwable instanceof UnknownHostException) {
if (adapter.mDataList == null || adapter.mDataList.size() <= 0) {
if (parentView == null) {
return;
}
emptyTv.setVisibility(View.VISIBLE);
ivEmptyView.setVisibility(View.VISIBLE);
lvContent.setVisibility(View.GONE);
emptyTv.setText("网络不给力哦,下拉刷新重试");
ivEmptyView.setImageResource(R.drawable.no_net);
} else {
RetrofitUtils.handleError(getActivity(), throwable);
}
} else {
RetrofitUtils.handleError(getActivity(), throwable);
isShowEmptyView();
}
});
}
private void isShowEmptyView() {
if (getParentView() == null) {
return;
}
if (adapter.mDataList == null || adapter.mDataList.size() <= 0) {
emptyTv.setVisibility(View.VISIBLE);
ivEmptyView.setVisibility(View.VISIBLE);
lvContent.setVisibility(View.GONE);
ivEmptyView.setImageResource(R.drawable.blank);
emptyTv.setText("还没有相应的课程哦~");
} else {
lvContent.setVisibility(View.VISIBLE);
emptyTv.setVisibility(View.GONE);
ivEmptyView.setVisibility(View.GONE);
}
}
@Override
public boolean checkCanDoRefresh(PtrFrameLayout frame, View content, View header) {
return PtrDefaultHandler.checkContentCanBePulledDown(frame, lvContent, header);
}
@Override
public void onRefreshBegin(PtrFrameLayout frame) {
frame.postDelayed(new Runnable() {
@Override
public void run() {
if (storeHousePtrFrame != null) {
storeHousePtrFrame.refreshComplete();
}
}
}, 1800);
getData(false);
}
@OnClick({R2.id.tv_pay_type_free, R2.id.tv_paied_type})
void doClick(View view) {
if (view.getId() == R.id.tv_paied_type) {
if (paiedCourse.isSelected()) {
return;
}
childType = TYPE_PAY; //付费
payTypeFree.setSelected(false);
payTypeFree.setTextColor(Color.parseColor("#909599"));
paiedCourse.setSelected(true);
paiedCourse.setTextColor(Color.parseColor("#ffffff"));
getCourses(false);
} else if (view.getId() == R.id.tv_pay_type_free) {
if (payTypeFree.isSelected()) {
return;
}
childType = TYPE_FREE; //免费
payTypeFree.setSelected(true);
payTypeFree.setTextColor(Color.parseColor("#ffffff"));
paiedCourse.setSelected(false);
paiedCourse.setTextColor(Color.parseColor("#909599"));
getCourses(false);
}
}
@Override
public void onLoadMore(LoadMoreContainer loadMoreContainer) {
getData(true);
}
@OnItemClick(R2.id.lv_content)
void onItemClick(View v, int position) {
Course course = adapter.getDataList().get(position);
if (course != null) {
H5Params h5Params = new H5Params(CourseConstants.Companion.getCOURSE_DETAIL_H5() + course.id, getActivity().getString(R.string.course_detail));
if (null != course.share && !TextUtils.isEmpty(course.share.getShare_url())) {
ShareData shareData = new ShareData(course.share.getShare_url(), course.share.getTitle(), course.share.getCover(), course.share.getDesc());
h5Params.setShareData(shareData);
}
UMEventUtils.umEvent("列表页分类点击", "分类id", course.id + "");
UMEventUtils.umEvent("列表页分类点击", "分类名称", course.title);
NewH5Activity.start(getActivity(), h5Params);
BuryPointUtils.getInstance().createMap()
.put("curriculum_name", course.title == null ? "" : course.title)
.put("curriculum_ID", course.id)
.burryPoint("Curriculum_click");
}
}
@Override
public void onDestroyView() {
super.onDestroyView();
LogUtil.i("destroy view id: " + tagId);
parentView = null;
}
}
package com.yidianling.course;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.support.constraint.ConstraintLayout;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.ydl.ydl_router.manager.YDLRouterManager;
import com.yidianling.course.coursePlay.CourseCommentActivity;
import com.yidianling.course.coursePlay.moudle.Course;
import com.yidianling.course.widget.CourseItemNewView;
import com.yidianling.ydlcommon.utils.UMEventUtils;
import butterknife.BindView;
import butterknife.ButterKnife;
/**
* Created by zqk on 6/22/17.
*/
public class CourseListItemView extends ConstraintLayout implements View.OnClickListener {
@BindView(R2.id.view_content)
CourseItemNewView courseItemNewView;
@BindView(R2.id.iv_export_btn_layout)
LinearLayout ivExportBtnLayout;
@BindView(R2.id.tv_line_bottom)
View tvLineBottom;
@BindView(R2.id.tv_course_item_first)
TextView tvCourseItemFirst;
@BindView(R2.id.tv_course_item_comment)
TextView tvCourseItemComment;
private Course mCourse;
private Context context;
public CourseListItemView(Context context) {
super(context);
this.context = context;
View view = inflate(context, R.layout.item_course_list, this);
ButterKnife.bind(this, view);
}
@SuppressLint("SetTextI18n")
public void setData(Course course) {
mCourse = course;
courseItemNewView.setData(course);
courseItemNewView.hideListenerButton();
//显示item下面的私聊,倾诉,咨询入口
if (course.isShowHostButton == 1) {
ivExportBtnLayout.setVisibility(View.VISIBLE);
tvLineBottom.setVisibility(View.VISIBLE);
if (course.userCommentNum == 0) {
tvCourseItemComment.setVisibility(VISIBLE);
} else {
tvCourseItemComment.setVisibility(GONE);
}
if (course.isOpenChat == 1) {
tvCourseItemFirst.setVisibility(VISIBLE);
} else {
tvCourseItemFirst.setVisibility(GONE);
}
if (course.userCommentNum != 0 && course.isOpenChat != 1) {
ivExportBtnLayout.setVisibility(View.GONE);
courseItemNewView.setBottomLineGone();
} else {
ivExportBtnLayout.setVisibility(View.VISIBLE);
courseItemNewView.setBottomLineVisible();
}
} else {
ivExportBtnLayout.setVisibility(View.GONE);
courseItemNewView.setBottomLineGone();
}
tvCourseItemComment.setOnClickListener(v -> CourseCommentActivity.Companion.startActivity((Activity) context, mCourse.id + ""));
tvCourseItemFirst.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
YDLRouterManager.Companion.router(mCourse.chatLinkUri);
}
});
}
@Override
public void onClick(View v) {
}
}
package com.yidianling.course;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import com.yidianling.course.coursePlay.moudle.Course;
import com.yidianling.course.widget.CourseItemNewView;
import com.yidianling.ydlcommon.adapter.CommonAdapter;
public class CourseNewListAdapter extends CommonAdapter<Course> {
private Context context;
public CourseNewListAdapter(Context context) {
this.context = context;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = new CourseItemNewView(context);
}
((CourseItemNewView) convertView).setData(mDataList.get(position));
return convertView;
}
}
package com.yidianling.course
import android.app.Activity
import android.content.Intent
import android.graphics.Bitmap
import android.graphics.Canvas
import android.support.v4.view.PagerAdapter
import android.support.v4.view.ViewPager
import android.text.TextUtils
import android.view.View
import android.view.ViewGroup
import android.view.WindowManager
import com.alibaba.android.arouter.facade.annotation.Route
import com.ydl.ydlcommon.base.BaseActivity
import com.ydl.ydlcommon.utils.StatusBarUtils
import com.yidianling.common.tools.ToastUtil
import com.yidianling.course.bean.PostersShareBean
import com.yidianling.course.coursePlay.common.net.RetrofitUtils
import com.yidianling.course.widget.CoursePosterTemplate
import com.yidianling.course.widget.CustomPagerTransformer
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
/**
* @author jiucheng
* @描述:课程生成海报
* @Copyright Copyright (c) 2018
* @Company 壹点灵
* @date 2019/8/6
*/
@Route(path = "/course/poster")
class CoursePosterActivity : BaseActivity() {
private val posterLayoutList = ArrayList<View>()
private var courseId: String? = null
private var bean: PostersShareBean? = null
private lateinit var posterView: CoursePosterTemplate
private lateinit var posterView2: CoursePosterTemplate
companion object {
private const val COURSE_ID = "course_id"
fun startActivity(activity: Activity, courseId: String) {
var intent = Intent(activity, CoursePosterActivity::class.java)
intent.putExtra(COURSE_ID, courseId)
activity.startActivity(intent)
}
}
override fun layoutResId(): Int {
window.addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND)
return R.layout.activity_course_poster
}
override fun initDataAndEvent() {
courseId = intent.getStringExtra(COURSE_ID)
StatusBarUtils.setWindowStatusBarColor(mContext, R.color.color_66000000)
if (TextUtils.isEmpty(courseId)) {
ToastUtil.toastShort("参数错误")
return
}
iv_back.setOnClickListener {
finish()
}
getData()
posterView = CoursePosterTemplate(this)
posterLayoutList.add(posterView)
posterView2 = CoursePosterTemplate(this)
posterLayoutList.add(posterView2)
viewpager.setPageTransformer(false, CustomPagerTransformer(this))
viewpager.adapter = PosterPagerAdapter()
viewpager.addOnPageChangeListener(object : ViewPager.OnPageChangeListener {
override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {}
override fun onPageSelected(position: Int) {
if (position == 0) {
radio_group.check(R.id.rb_one)
} else {
radio_group.check(R.id.rb_two)
}
}
override fun onPageScrollStateChanged(state: Int) {
}
})
radio_group.setOnCheckedChangeListener { _, checkedId ->
if (checkedId == R.id.rb_two) {
viewpager.currentItem = 1
} else {
viewpager.currentItem = 0
}
}
tv_share.setOnClickListener {
showShareDialog()
}
}
private fun getData() {
RetrofitUtils.getPosterData(courseId)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ resp ->
dismissProgressDialog()
if (resp.code == 200) {
bean = resp.data
initViewData()
} else {
ToastUtil.toastShort(resp.msg)
}
}, { t ->
dismissProgressDialog()
ToastUtil.toastShort(t.localizedMessage)
})
}
private fun initViewData() {
if (bean == null) {
ToastUtil.toastShort("数据错误")
return
}
posterView.setData(bean!!, true)
posterView2.setData(bean!!, false)
}
private fun showShareDialog() {
if (bean!!.shareData == null) {
ToastUtil.toastShort("分享参数错误")
return
}
val dialog = YDLShareDialog.style6(
this,
bean!!.shareData!!.title,
bean!!.shareData!!.share_url,
bean!!.shareData!!.desc,
bean!!.shareData!!.cover
)
dialog.setCallBack(object : YDLShareDialog.ICallBack {
override fun callBack(type: Int) {
if (type == 6) {
ImageUtil.savePicture(
this@CoursePosterActivity,
createViewBitmap(if (viewpager.currentItem == 0) posterView else posterView2)
)
}
if (type == 7) {
ShareUtils.sharePicToWeiXin(
this@CoursePosterActivity,
createViewBitmap(if (viewpager.currentItem == 0) posterView else posterView2)
)
dialog.dismiss()
}
}
})
dialog.show(fragmentManager, "lose")
}
private fun createViewBitmap(v: View): Bitmap? {
if (this.isFinishing) {
return null
}
var bitmap = Bitmap.createBitmap(v.width, v.height, Bitmap.Config.ARGB_8888)
var canvas = Canvas(bitmap)
v.draw(canvas)
return bitmap
}
internal inner class PosterPagerAdapter : PagerAdapter() {
override fun getCount(): Int {
return posterLayoutList.size
}
override fun isViewFromObject(view: View, `object`: Any): Boolean {
return view === `object`
}
override fun instantiateItem(container: ViewGroup, position: Int): Any {
val view = posterLayoutList[position]
container.addView(view)
return view
}
override fun destroyItem(container: ViewGroup, position: Int, `object`: Any) {
container.removeView(`object` as View)
}
}
}
\ No newline at end of file
package com.yidianling.course
import CoursePlugin
import android.annotation.SuppressLint
import android.os.Handler
import android.text.TextUtils
import com.alibaba.android.arouter.launcher.ARouter
import com.google.gson.Gson
import com.ydl.ydl_router.manager.YDLRouterManager
import com.yidianling.common.tools.ToastUtil
import com.yidianling.course.bean.CourseCouponBean
import com.yidianling.course.coursePlay.common.net.RetrofitUtils
import com.yidianling.course.flutterPlugin.CourseSendPlugin
import com.yidianling.course.widget.CourseCouponDialog
import com.yidianling.router.RouterManager
import com.yidianling.ydlcommon.flutter.base.BaseFlutterFragment
import com.yidianling.ydlcommon.http.BaseResponse
import com.yidianling.ydlcommon.http.RxUtils
import com.yidianling.ydlcommon.http.ThrowableConsumer
import com.yidianling.ydlcommon.remind.ToastHelper
import com.yidianling.ydlcommon.router.YdlCommonRouterManager
import com.yidianling.ydlcommon.utils.YDLCacheUtils
import com.yidianling.ydlcommon.utils.actionutil.ActionCountUtils
import com.yidianling.ydlcommon.utils.actionutil.BIConstants
import io.flutter.view.FlutterView
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.functions.Consumer
import io.reactivex.schedulers.Schedulers
import java.text.SimpleDateFormat
import java.util.*
/**
* @author jiucheng
* @描述:课程频道页(flutter)
* @Copyright Copyright (c) 2018
* @Company 壹点灵
* @date 2019/10/22
*/
class FlutterCourseHomeFragment : BaseFlutterFragment() {
private var hasRequestCoupon = false
private var dialog: CourseCouponDialog? = null
override fun initChannelPlugin(flutterView: FlutterView) {
CoursePlugin.rigister(this, flutterView)
CourseSendPlugin.initContext(this, flutterView)
}
override fun initialRoute(): String {
return "native/course/home"
}
override fun setUserVisibleHint(isVisibleToUser: Boolean) {
super.setUserVisibleHint(isVisibleToUser)
if (isVisibleToUser) {
prepareCoupon()
ActionCountUtils.count(BIConstants.CourseHomeEvent.POSITION_COURSE_HOME_PAGE_VISIT)
}
}
/**
* 获取优惠券信息
*/
private fun prepareCoupon() {
//判断是否登录 以及本次app启动后是否已经请求过
if (RouterManager.getUserRouter()?.isLogin() == true && !hasRequestCoupon) {
Handler().postDelayed({
//优惠券逻辑
if (compareCouponTime()) {
getCouponData()
}
}, 2000)
}
}
/**
* 获取可以领取的课程优惠券
*
* @param uid uid
* @param services 适用服务 1预约咨询 2电话倾诉 3课程(用户课程 专家课程) 5测评
* @param receiveType 领取条件方式 1前台领取 2链接领取
* @param applyEnds 适用终端 1PC官网 2wap站点 3用户app 4好杮app 5专家app
* @return
*/
@SuppressLint("SimpleDateFormat", "CheckResult")
private fun getCouponData() {
val (userId) = YdlCommonRouterManager.getYdlCommonRoute().getUserInfo() ?: return
RetrofitUtils.getCourseCoupons(userId, "3", "1", "3")
.compose(RxUtils.netCheck())
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(Consumer {
hasRequestCoupon = true
val simpleFormat = SimpleDateFormat("yyyy-MM-dd HH:mm:ss")//如2016-08-10
val time = System.currentTimeMillis()
val date = Date()
date.time = time
val nowTime = simpleFormat.format(date)
if (it?.data != null && it.data.isNotEmpty()) {
YDLCacheUtils.saveCouponTime(userId, nowTime)
couponDataResponse(it.data)
}
}, object : ThrowableConsumer() {
override fun accept(msg: String) {
}
})
}
/**
* 可领取的优惠券列表
*/
private fun couponDataResponse(data: List<CourseCouponBean>) {
if (dialog == null) {
dialog = CourseCouponDialog(activity, data, object : CourseCouponDialog.OnClickEnsureListener {
override fun clickUse(toLink: String) {
YDLRouterManager.router(toLink)
dialog!!.dismiss()
}
override fun clickEnsure(status: Int) {
if (status == CourseCouponDialog.STATUS_RECEIVER) {
receiveCoupon(data)
} else {
dialog!!.dismiss()
//查看我的卡券
ARouter.getInstance().build("/mine/redpacket")
.withString("is_from_main", "1")
.navigation()
}
}
})
}
dialog!!.show()
}
/**
* 领取优惠券
*/
@SuppressLint("CheckResult")
fun receiveCoupon(list: List<CourseCouponBean>) {
val (userId) = YdlCommonRouterManager.getYdlCommonRoute().getUserInfo() ?: return
val couponIds = ArrayList<String>()
for (bean in list) {
couponIds.add(bean.id)
}
val bean = CouponReceiveBean()
bean.couponIds = couponIds
bean.uid = userId
val couponIdsStr = Gson().toJson(bean)
RetrofitUtils.receiveCoupon(couponIdsStr)
.compose(RxUtils.netCheck())
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(Consumer {
receiveCouponResponse(it)
}, object : ThrowableConsumer() {
override fun accept(msg: String) {
ToastUtil.toastShort(msg)
}
})
}
/**
* 优惠券领取成功
*/
private fun receiveCouponResponse(data: BaseResponse<List<String>>) {
if (data.code == 200) {
dialog?.updateStatus(CourseCouponDialog.STATUS_GET, data.data)
} else {
ToastHelper.show(data.msg)
}
}
/**
* 对比上次获取优惠券时间,若时间差超过一天,则再次请求,否则不获请求
*/
@SuppressLint("SimpleDateFormat")
private fun compareCouponTime(): Boolean {
val uid = YdlCommonRouterManager.getYdlCommonRoute().getUserInfo()?.userId
val simpleFormat = SimpleDateFormat("yyyy-MM-dd HH:mm:ss")//如2016-08-10
val last = YDLCacheUtils.getCouponTime(uid)
return if (TextUtils.isEmpty(last)) {
//还没有获取过优惠券,直接请求数据
true
} else {
val time = System.currentTimeMillis()
val date = Date()
date.time = time
val nowTime = simpleFormat.format(date)
!TextUtils.equals(last.substring(0, 10), nowTime.substring(0, 10))
}
}
inner class CouponReceiveBean {
var couponIds: List<String>? = null
var uid: String? = null
}
}
\ No newline at end of file
package com.yidianling.course;
import android.graphics.Color;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.text.TextUtils;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import com.yidianling.common.tools.LogUtil;
import com.yidianling.common.tools.ToastUtil;
import com.yidianling.course.courseNew.LoadMoreView;
import com.yidianling.course.courseNew.courseList.BaseLazyFragment;
import com.yidianling.course.coursePlay.common.net.Command;
import com.yidianling.course.coursePlay.common.net.RetrofitUtils;
import com.yidianling.course.coursePlay.moudle.Course;
import com.yidianling.course.router.CourseIn;
import com.yidianling.ydlcommon.data.ShareData;
import com.yidianling.ydlcommon.h5.H5Params;
import com.yidianling.ydlcommon.h5.NewH5Activity;
import com.yidianling.ydlcommon.tool.BuryPointUtils;
import com.yidianling.ydlcommon.utils.UMEventUtils;
import java.net.ConnectException;
import java.net.UnknownHostException;
import java.util.List;
import java.util.concurrent.TimeoutException;
import butterknife.BindView;
import butterknife.OnClick;
import butterknife.OnItemClick;
import in.srain.cube.views.loadmore.LoadMoreContainer;
import in.srain.cube.views.loadmore.LoadMoreHandler;
import in.srain.cube.views.loadmore.LoadMoreListViewContainer;
import in.srain.cube.views.ptr.PtrDefaultHandler;
import in.srain.cube.views.ptr.PtrFrameLayout;
import in.srain.cube.views.ptr.PtrHandler;
import in.srain.cube.views.ptr.header.MaterialHeader;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
/**
* A simple {@link Fragment} subclass.
* 咨询师课程列表页
*/
public class MyCourseListFragment extends BaseLazyFragment implements PtrHandler, LoadMoreHandler {
@BindView(R2.id.lv_content)
ListView lvContent;
@BindView(R2.id.load_more_list_view_container)
LoadMoreListViewContainer loadMoreListViewContainer;
@BindView(R2.id.store_house_ptr_frame)
PtrFrameLayout storeHousePtrFrame;
@BindView(R2.id.tv_course_list_empty_prompt)
TextView emptyTv;
@BindView(R2.id.iv_course_list_empty_view)
ImageView ivEmptyView;
@BindView(R2.id.ll_pay_type)
LinearLayout llPayType;
@BindView(R2.id.tv_pay_type_free)
TextView payTypeFree;
@BindView(R2.id.tv_paied_type)
TextView paiedCourse;
private int page = 0;
private boolean hasMore = true;
private int tagId;
private CourseListAdapter adapter;
private int childType = -1;
private boolean isPrepared;
public MyCourseListFragment() {
// Required empty public constructor
}
public static MyCourseListFragment newInstance(int tagId) {
Bundle args = new Bundle();
args.putInt("tagId", tagId);
MyCourseListFragment fragment = new MyCourseListFragment();
fragment.setArguments(args);
return fragment;
}
public static MyCourseListFragment newInstance(int tagId, int childType) {
Bundle args = new Bundle();
args.putInt("tagId", tagId);
args.putInt("childType", childType);
MyCourseListFragment fragment = new MyCourseListFragment();
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
tagId = getArguments().getInt("tagId");
childType = getArguments().getInt("childType");
}
}
@Override
public void afterViewCreated(View view, Bundle savedInstanceState) {
isPrepared = true; //View创建完成
LogUtil.i("afterViewCreated id: " + tagId);
if (!isUseLazyMode) {
isVisible = true;
}
lazyLoad();
}
@Override
public int getLayoutId() {
return R.layout.fragment_course_list;
}
@Override
public void lazyLoad() {
if (!isPrepared || !isVisible) {
return;
}
LogUtil.i("lazy load tagid: " + tagId);
if (childType == 2) { //付费
llPayType.setVisibility(View.VISIBLE);
payTypeFree.setSelected(false);
payTypeFree.setTextColor(Color.parseColor("#909599"));
paiedCourse.setSelected(true);
paiedCourse.setTextColor(Color.parseColor("#ffffff"));
} else if (childType == 1) { //免费
llPayType.setVisibility(View.VISIBLE);
payTypeFree.setSelected(true);
payTypeFree.setTextColor(Color.parseColor("#ffffff"));
paiedCourse.setSelected(false);
paiedCourse.setTextColor(Color.parseColor("#909599"));
}
init();
isPrepared = false;
}
private void init() {
// header
final MaterialHeader header = new MaterialHeader(getActivity());
int[] colors = getResources().getIntArray(R.array.ydl_colors);
header.setColorSchemeColors(colors);
header.setLayoutParams(new PtrFrameLayout.LayoutParams(-1, -2));
int padding = (int) getActivity().getResources().getDimension(R.dimen.default_dis_size);
header.setPadding(0, padding, 0, padding);
header.setPtrFrameLayout(storeHousePtrFrame);
storeHousePtrFrame.setHeaderView(header);
storeHousePtrFrame.setPtrHandler(this);
storeHousePtrFrame.addPtrUIHandler(header);
// 使用默认样式
// loadMoreListViewContainer.useDefaultHeader();
LoadMoreView footerView = new LoadMoreView(getContext());
loadMoreListViewContainer.setLoadMoreView(footerView);
loadMoreListViewContainer.setLoadMoreUIHandler(footerView);
footerView.onLoading(loadMoreListViewContainer);
loadMoreListViewContainer.setLoadMoreHandler(this);
adapter = new CourseListAdapter(getActivity());
lvContent.setAdapter(adapter);
getData(false);
}
private void getData(boolean loadMore) {
switch (tagId) {
case 1:
case 2:
if (!CourseIn.INSTANCE.isLogin()) {
return;
}
break;
default:
break;
}
if (loadMore && !hasMore) {
loadMoreListViewContainer.loadMoreFinish(false, false);
return;
}
if (loadMore) {
page++;
} else {
page = 1;
hasMore = true;
}
getCourses(loadMore);
}
private void getCourses(final boolean loadMore) {
Command.GetCourse command;
if (tagId >= 10) {
command = new Command.GetCourse(page, tagId, childType);
} else {
command = new Command.GetCourse(page, tagId + 1);
}
//todo heti 待修改
RetrofitUtils.getCourseList(command)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(resp -> {
if (resp.code != 0) {
ToastUtil.toastShort(resp.msg);
hasMore = false;
isShowEmptyView();
return;
}
lvContent.setVisibility(View.VISIBLE);
emptyTv.setVisibility(View.GONE);
ivEmptyView.setVisibility(View.GONE);
if (getActivity() instanceof CourseActivity)
((CourseActivity) getActivity()).disPro();
if (loadMoreListViewContainer != null) {
loadMoreListViewContainer.loadMoreFinish(false, true);
}
try {
List<Course> courses = resp.data;
if (courses == null || courses.size() < CourseConstants.COURSE_PAGE_SIZE) {
hasMore = false;
}
if (!loadMore) {
if (courses != null) {
adapter.setDataList(courses);
adapter.notifyDataSetChanged();
}
} else if (courses != null) {
adapter.addDataList(courses);
}
isShowEmptyView();
} catch (Exception e) {
LogUtil.e(e.toString());
}
}, throwable -> {
// hasMore=false;
if (throwable instanceof TimeoutException || throwable instanceof ConnectException || throwable instanceof UnknownHostException) {
if (adapter.mDataList == null || adapter.mDataList.size() <= 0) {
if (parentView == null) {
return;
}
emptyTv.setVisibility(View.VISIBLE);
ivEmptyView.setVisibility(View.VISIBLE);
lvContent.setVisibility(View.GONE);
emptyTv.setText("网络不给力哦,下拉刷新重试");
ivEmptyView.setImageResource(R.drawable.no_net);
} else {
RetrofitUtils.handleError(getActivity(), throwable);
}
} else {
RetrofitUtils.handleError(getActivity(), throwable);
isShowEmptyView();
}
});
}
private void isShowEmptyView() {
if (getParentView() == null) {
return;
}
if (adapter.mDataList == null || adapter.mDataList.size() <= 0) {
emptyTv.setVisibility(View.VISIBLE);
ivEmptyView.setVisibility(View.VISIBLE);
lvContent.setVisibility(View.GONE);
ivEmptyView.setImageResource(R.drawable.blank);
emptyTv.setText("还没有相应的课程哦~");
} else {
lvContent.setVisibility(View.VISIBLE);
emptyTv.setVisibility(View.GONE);
ivEmptyView.setVisibility(View.GONE);
}
}
@Override
public boolean checkCanDoRefresh(PtrFrameLayout frame, View content, View header) {
return PtrDefaultHandler.checkContentCanBePulledDown(frame, lvContent, header);
}
@Override
public void onRefreshBegin(PtrFrameLayout frame) {
frame.postDelayed(new Runnable() {
@Override
public void run() {
if (storeHousePtrFrame != null) {
storeHousePtrFrame.refreshComplete();
}
}
}, 1800);
getData(false);
}
@OnClick({R2.id.tv_pay_type_free, R2.id.tv_paied_type})
void doClick(View view) {
if (view.getId() == R.id.tv_paied_type) {
if (paiedCourse.isSelected()) {
return;
}
childType = 2; //付费
payTypeFree.setSelected(false);
payTypeFree.setTextColor(Color.parseColor("#909599"));
paiedCourse.setSelected(true);
paiedCourse.setTextColor(Color.parseColor("#ffffff"));
getCourses(false);
} else if (view.getId() == R.id.tv_pay_type_free) {
if (payTypeFree.isSelected()) {
return;
}
childType = 1; //付费
payTypeFree.setSelected(true);
payTypeFree.setTextColor(Color.parseColor("#ffffff"));
paiedCourse.setSelected(false);
paiedCourse.setTextColor(Color.parseColor("#909599"));
getCourses(false);
}
}
@Override
public void onLoadMore(LoadMoreContainer loadMoreContainer) {
getData(true);
}
@OnItemClick(R2.id.lv_content)
void onItemClick(View v, int position) {
Course course = adapter.getDataList().get(position);
if (course != null) {
H5Params h5Params = new H5Params(CourseConstants.Companion.getCOURSE_DETAIL_H5() + course.id, getActivity().getString(R.string.course_detail));
if (!TextUtils.isEmpty(course.share.getShare_url())) {
ShareData shareData = new ShareData(course.share.getShare_url(), course.share.getTitle(), course.share.getCover(), course.share.getDesc());
h5Params.setShareData(shareData);
}
UMEventUtils.umEvent("列表页分类点击", "分类id", course.id + "");
UMEventUtils.umEvent("列表页分类点击", "分类名称", course.title);
NewH5Activity.start(getActivity(), h5Params);
BuryPointUtils.getInstance().createMap()
.put("curriculum_name", course.title == null ? "" : course.title)
.put("curriculum_ID", course.id)
.burryPoint("Curriculum_click");
}
}
@Override
public void onDestroyView() {
super.onDestroyView();
LogUtil.i("destroy view id: " + tagId);
parentView = null;
}
}
package com.yidianling.course.bean;
/**
* @author jiucheng
* @描述:优惠券信息
* @Copyright Copyright (c) 2018
* @Company 壹点灵
* @date 2018/8/8
*/
public class CourseCouponBean {
/**
* amount (integer, optional): 优惠金额 ,
* discount (number, optional): 折扣 ,
* discountCont (string, optional): 优惠的文案 ,
* effective (string, optional): 有效期的文案 ,
* id (integer, optional),
* rangeCont (string, optional): 使用范围的文案 ,
* receiveStatus (string, optional): 领取状态 1已结束 2已领取 3可领取 ,
* residueCont (string, optional): 状态的文案 ,
* specifiedGoodsList (Array[integer], optional): 指定商品列表 ,
* title (string, optional): 优惠券名称 ,
* toLink (string, optional): 跳转链接 ,
* type (string, optional): 优惠券形式:1立减,2折扣 ,
* useCondition (string, optional): 使用条件 1无限制 2满金额 ,
* useConditionValue (integer, optional): 使用条件的值(金额或次数)
*/
public String title;
public String id;
public String effective;
public String rangeCont;
public String discountCont;
public String residueCont;
public String type;//优惠券形式:1立减,2折扣 ,
public String amount;
public String discount;
public String useCondition;
public String useConditionValue;
public String toLink;
public String specifiedGoodsList;
public String receiveStatus;
}
package com.yidianling.course.bean;
/**
* @author jiucheng
* @描述:
* @Copyright Copyright (c) 2018
* @Company 壹点灵
* @date 2019/8/20
*/
public class CourseHomeBodyBean {
public String title;
public String image;
public String pic;
public String linkUrl;
//1 付费课程 2 体验课程 3 线下或站位课程 4 其他课程
public String type;
public String id;
public String hostListPic;
public String hostInfo;
public int subCourseNum;
public int joinNum;
public CourseHostInfoBean courseHostInfo;
public String leftBottom;
public String rightBottom;
public String isPromotion;
public String promotionApplyFee;
public String isVirtual;
public String courseType;
public String doctorName;
public int isInvite;
public String applyFee;
public int newCourse;
public int recommend;
public int demoType;
public String originalApplyFee;
public boolean isBuy;
public String demoFile;
}
package com.yidianling.course.bean;
import com.yidianling.ydlcommon.data.ShareData;
/**
* @author jiucheng
* @描述:
* @Copyright Copyright (c) 2018
* @Company 壹点灵
* @date 2019/8/21
*/
public class CourseHostInfoBean {
public String doctorId;
public String doctorUid;
public String doctorHead;
public String doctorName;
public String goodAt;
public String thsNum;
public String zixunOrderNum;
public String listenOrderNum;
public String serviceNum;
public String fansNum;
public String title;
public String feedbackRate;
public String tag1;
public String tag2;
public String askTotalTime;
public String helpLong;
public ShareData shareData;
}
package com.yidianling.course.bean
import com.yidianling.ydlcommon.data.ShareData
/**
* @author jiucheng
* @描述:
* @Copyright Copyright (c) 2018
* @Company 壹点灵
* @date 2019/8/7
*/
data class PostersShareBean(
/**
* 课程价格
*/
var applyFee: String,
/**
* 简述
*/
var desc: String,
/**
* 课程id ,
*/
var id: String,
/**
* isPromotion ,是否促销 1活动中 2结束or没开始 3倒计时 ,
*/
var isPromotion: String,
/**
* originalApplyFee 课程原价 ,
*/
var originalApplyFee: String,
/**
* pic 课程图 ,
*/
var pic: String,
/**
* promotionApplyFee 课程促销价 , ,
*/
var promotionApplyFee: String,
/**
* qrCodeByte 二维码
*/
var qrCodeByte: String,
/**
* readNums 课程浏览量 ,
*/
var readNums: String,
/**
* shareUser 分享的用户基本信息 ,
*/
var shareUser: ShareUser?,
/**
* subCourseNum 子课程数量
*/
var subCourseNum: String,
/**
* title 课程标题
*/
var title: String,
var shareData: ShareData?
)
\ No newline at end of file
package com.yidianling.course.bean
/**
* @author jiucheng
* @描述:
* @Copyright Copyright (c) 2018
* @Company 壹点灵
* @date 2019/8/7
*/
data class ShareUser(
var head:String,
var nickName :String,
var uid :String
)
\ No newline at end of file
package com.yidianling.course.courseNew;
/**
* Created by Jim on 2018/7/13 0013.
*/
public class BannerBean {
public String title;
public String image;
public String linkUrl;
}
package com.yidianling.course.courseNew
import android.content.Context
import android.view.LayoutInflater
import android.widget.FrameLayout
import android.widget.LinearLayout
import com.ydl.ydl_image.module.GlideApp
import com.yidianling.course.R
import kotlinx.android.synthetic.main.item_view_category.view.*
/**
* @author : Zhangwenchao
* @e-mail : zhangwch@yidianling.com
* @time : 2018/7/14
*/
class CategoryItemView(context: Context?) : FrameLayout(context) {
init {
LayoutInflater.from(context).inflate(R.layout.item_view_category, this, true)
}
fun setText(text: CharSequence?) {
tv_title.text = text
}
fun setImage(url: String?) {
url?.let { GlideApp.with(this).load(it).into(iv_icon) }
}
}
\ No newline at end of file
package com.yidianling.course.courseNew;
import android.content.Context;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import com.ydl.ydl_image.module.GlideApp;
import com.yidianling.common.tools.RxImageTool;
import com.yidianling.course.R;
import com.yidianling.ydlcommon.utils.ScreenUtil;
import com.yidianling.ydlcommon.utils.UMEventUtils;
import com.yidianling.ydlcommon.utils.actionutil.ActionCountUtils;
import com.yidianling.ydlcommon.utils.actionutil.BIConstants;
import java.util.List;
/**
* Created by softrice on 2015/11/13.
*/
public class CourseHeadPagerAdapter extends PagerAdapter {
/**
* 装ImageView数组
*/
private List<BannerBean> banners;
private ImageView[] mImageViews;
private Context mContext;
private int dp194, screenWidth;
public CourseHeadPagerAdapter(List<BannerBean> banners, Context context) {
this.banners = banners;
mContext = context;
dp194 = RxImageTool.dip2px(194f);
screenWidth = ScreenUtil.screenWidth;
initDatas();
}
public void setData(List<BannerBean> banners) {
this.banners = banners;
initDatas();
}
@Override
public int getCount() {
if (banners == null || banners.size() <= 0) {
return 1;
} else {
return banners.size();
}
}
private void initDatas() {
if (banners == null || banners.size() <= 0) {
mImageViews = new ImageView[1];
mImageViews[0] = new ImageView(mContext);
mImageViews[0].setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, dp194));
mImageViews[0].setScaleType(ImageView.ScaleType.CENTER_CROP);
GlideApp.with(mContext)
.load(R.drawable.default_banner)
.override(screenWidth, dp194)
.into(mImageViews[0]);
} else {
mImageViews = new ImageView[banners.size()];
for (int i = 0; i < mImageViews.length; i++) {
mImageViews[i] = new ImageView(mContext);
mImageViews[i].setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, dp194));
mImageViews[i].setScaleType(ImageView.ScaleType.CENTER_CROP);
GlideApp.with(mContext)
.load(banners.get(i).image)
.override(screenWidth, dp194)
.into(mImageViews[i]);
}
}
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
((ViewPager) container).removeView(mImageViews[position
% mImageViews.length]);
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
try {
((ViewPager) container).addView(mImageViews[position
% mImageViews.length], 0);
} catch (Exception e) {
// handler something
}
mImageViews[position % mImageViews.length].setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
UMEventUtils.umEvent("banner点击", "banner链接", banners.get(position).linkUrl);
ActionCountUtils.Companion.count(BIConstants.CourseHomeEvent.POSITION_COURSE_HOME_BANNER_CLICK, position + "");
LinkUrlRouterProtocol.jump(container.getContext(), banners.get(position).linkUrl);
}
});
return mImageViews[position % mImageViews.length];
}
}
package com.yidianling.course.courseNew
import android.content.Context
import android.content.Intent
import android.support.v4.widget.SwipeRefreshLayout
import android.support.v7.widget.LinearLayoutManager
import android.text.TextUtils
import android.view.LayoutInflater
import android.view.View
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.TextView
import com.alibaba.android.arouter.facade.annotation.Route
import com.ydl.ydl_image.module.GlideApp
import com.yidianling.common.tools.LogUtil
import com.yidianling.common.tools.RxNetTool
import com.yidianling.course.R
import com.yidianling.course.coursePlay.common.net.RetrofitUtils
import com.yidianling.course.coursePlay.moudle.Course
import com.yidianling.course.model.TopicCourseBean
import com.yidianling.ydlcommon.base.BaseActivity
import com.yidianling.ydlcommon.http.RxUtils
import com.yidianling.ydlcommon.share.ShareUtils
import com.yidianling.ydlcommon.utils.UMEventUtils
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import kotlinx.android.synthetic.main.activity_course_topic.*
import kotlinx.android.synthetic.main.layout_title_bar.*
/**
* 课程专题页面
*/
@Route(path = "/course/special")
class CourseTopicActivity : BaseActivity(), View.OnClickListener, SwipeRefreshLayout.OnRefreshListener {
private var opicCourseBean: TopicCourseBean? = null
private var adapter: CourseTopicAdapter? = null
private var datas: List<Course>? = null
private var specialId: Int? = 0
private var headView: ImageView? = null
private var footerView: View? = null
companion object {
fun start(context: Context, id: String) {
val i = Intent(context, CourseTopicActivity::class.java)
i.putExtra("special_id", id)
context.startActivity(i)
}
}
override fun layoutResId(): Int {
return R.layout.activity_course_topic
}
override fun initDataAndEvent() {
tv_title.text = "课程专题"
iv_back.setOnClickListener(this)
course_topic_rcv.layoutManager = LinearLayoutManager(this)
datas = ArrayList()
adapter = CourseTopicAdapter(this, datas!!)
course_topic_rcv.adapter = adapter
if (!TextUtils.isEmpty(intent.getStringExtra("special_id"))) {
specialId = intent.getStringExtra("special_id").toInt()
}
LogUtil.i("special id: $specialId")
swl.setColorSchemeResources(R.color.google_green)
swl.setOnRefreshListener(this)
tv_left_menu.setOnClickListener {
UMEventUtils.umEvent("专题详情", "分享", "分享")
//分享
share()
}
initHeadView()
initFooterView()
loadData()
}
override fun onRefresh() {
swl.isRefreshing = true
loadData()
}
override fun onClick(v: View?) {
when (v?.id) {
R.id.iv_back -> finish()
}
}
fun initHeadView() {
headView = LayoutInflater.from(this).inflate(R.layout.item_course_topic_image, course_topic_rcv, false) as ImageView
adapter?.addHeaderView(headView)
}
fun initFooterView() {
footerView = LayoutInflater.from(this).inflate(R.layout.item_text, course_topic_rcv, false)
adapter?.addFooterView(footerView)
}
private fun share() {
if (null != opicCourseBean && null != opicCourseBean!!.share) {
ShareUtils.share(CourseTopicActivity@ this, opicCourseBean!!.share!!.title, opicCourseBean!!.share!!.share_url, opicCourseBean!!.share!!.desc, opicCourseBean!!.share!!.cover)
}
}
private fun loadData() {
if (!RxNetTool.isConnected(CourseTopicActivity@ this)) {
swl.isRefreshing = false
course_topic_rcv.visibility = View.GONE
v_no_network.visibility = View.VISIBLE
return
}
course_topic_rcv.visibility = View.VISIBLE
v_no_network.visibility = View.GONE
RetrofitUtils.getCourseTopic(specialId.toString())
.subscribeOn(Schedulers.io())
.compose(RxUtils.resultJavaData())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ resp ->
LogUtil.i("resp: $resp")
opicCourseBean = resp
course_topic_rcv.visibility = View.VISIBLE
adapter?.setDatas(resp.courses)
GlideApp.with(CourseTopicActivity@ this).load(resp.pic).into(headView)
if (resp.explain.isNullOrEmpty()) {
footerView?.findViewById<LinearLayout>(R.id.ll_title)!!.visibility = View.GONE
} else {
footerView?.findViewById<LinearLayout>(R.id.ll_title)!!.visibility = View.VISIBLE
footerView?.findViewById<TextView>(R.id.tv_content)!!.text = resp.explain!!
}
adapter?.notifyDataSetChanged()
swl.isRefreshing = false
}, { throwable ->
LogUtil.e(throwable.toString())
course_topic_rcv.visibility = View.GONE
swl.isRefreshing = false
})
}
}
package com.yidianling.course.courseNew
import android.content.Context
import android.support.v4.util.SparseArrayCompat
import android.support.v7.widget.RecyclerView
import android.view.View
import android.view.ViewGroup
import com.yidianling.course.CourseConstants
import com.yidianling.course.coursePlay.moudle.Course
import com.yidianling.course.widget.CourseItemNewView
import com.yidianling.ydlcommon.h5.H5Params
import com.yidianling.ydlcommon.h5.NewH5Activity
import com.yidianling.ydlcommon.utils.UMEventUtils
import com.yidianling.ydlcommon.view.BaseViewHolder
/**
* Created by Jim on 2018/7/12 0012.
*/
class CourseTopicAdapter(val context: Context, var mDatas: List<Course>) : RecyclerView.Adapter<BaseViewHolder>() {
private val BASE_ITEM_TYPE_HEADER = 100000
private val BASE_ITEM_TYPE_FOOTER = 200000
private var mHeaderViews: SparseArrayCompat<View> = SparseArrayCompat()
private var mFootViews: SparseArrayCompat<View> = SparseArrayCompat()
fun addHeaderView(v: View?) {
mHeaderViews.put(mHeaderViews.size() + BASE_ITEM_TYPE_HEADER, v)
}
fun addFooterView(v: View?) {
mFootViews.put(mFootViews.size() + BASE_ITEM_TYPE_FOOTER, v)
}
fun getHeadersCount(): Int = mHeaderViews.size()
fun getFootersCount(): Int = mFootViews.size()
private fun isHeaderView(position: Int): Boolean {
return position < getHeadersCount()
}
private fun isFooterView(position: Int): Boolean {
return position >= getHeadersCount() + mDatas.size
}
fun setDatas(datas: List<Course>?) {
if (datas != null) {
mDatas = datas
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseViewHolder {
if (mHeaderViews.get(viewType) != null) {
return BaseViewHolder(mHeaderViews.get(viewType), context, viewType)
}
if (mFootViews.get(viewType) != null) {
return BaseViewHolder(mFootViews.get(viewType), context, viewType)
}
val view = CourseItemNewView(context)
return BaseViewHolder(view, context, viewType)
}
override fun onBindViewHolder(holder: BaseViewHolder, position: Int) {
if (isHeaderView(position)) {
return
}
if (isFooterView(position)) {
return
} else {
val course = mDatas[position - getHeadersCount()]
(holder.getItemView() as CourseItemNewView).setData(course)
if (position == itemCount - getFootersCount() - 1) {
(holder.getItemView() as CourseItemNewView).setBottomLineGone()
}
holder.itemView.setOnClickListener { view ->
UMEventUtils.umEvent("列表点击", "专题id", course.id.toString())
UMEventUtils.umEvent("列表点击", "专题名称", course.title)
NewH5Activity.start(context, H5Params(CourseConstants.COURSE_DETAIL_H5 + course.id, null))
}
}
}
override fun getItemViewType(position: Int): Int {
if (isHeaderView(position)) {
return mHeaderViews.keyAt(position)
} else if (isFooterView(position)) {
return mFootViews.keyAt(position - mDatas.size - getHeadersCount())
}
return super.getItemViewType(position)
}
override fun getItemCount(): Int {
if (mDatas != null && mDatas!!.size > 0) {
return mDatas!!.size + getHeadersCount() + getFootersCount()
}
return getFootersCount() + getHeadersCount()
}
}
\ No newline at end of file
package com.yidianling.course.courseNew;
import android.content.Context;
import android.text.TextUtils;
import com.ydl.ydl_router.manager.YDLRouterManager;
import com.ydl.ydl_router.manager.YDLRouterParams;
import com.yidianling.common.tools.LogUtil;
import com.yidianling.ydlcommon.router.IYDLRouterConstant;
/**
* Created by Jim on 2018/7/17 0017.
*/
public class LinkUrlRouterProtocol {
public static void jump(Context context, String url) {
if (TextUtils.isEmpty(url)) {
LogUtil.e("jump url is null");
}
if (url.startsWith("app://course/category")) {
int index = splitParam(url);
//跳转课程列表
YDLRouterManager.Companion.router(IYDLRouterConstant.ROUTER_COURSE_LIST,
new YDLRouterParams().putExtra(IYDLRouterConstant.EXTRA_LISTTYPE, String.valueOf(index)));
} else if (url.startsWith("http")) {
//跳转H5页面
YDLRouterManager.Companion.router(IYDLRouterConstant.ROUTER_H5_H5,
new YDLRouterParams().putExtra(IYDLRouterConstant.EXTRA_URL, url), "");
} else if (url.startsWith("app://course/special")) {
int id = splitParam(url);
//跳转课程专题页
YDLRouterManager.Companion.router(IYDLRouterConstant.ROUTER_COURSE_SPECIAL,
new YDLRouterParams().putExtra(IYDLRouterConstant.EXTRA_ID, String.valueOf(id)));
} else if (url.startsWith("app://course/fineCourse")) {
int childId = splitParam(url);
//跳转课程列表--精品课程
YDLRouterManager.Companion.router(IYDLRouterConstant.ROUTER_COURSE_LIST,
new YDLRouterParams().putExtra(IYDLRouterConstant.EXTRA_LISTTYPE, "18")
.putExtra(IYDLRouterConstant.EXTRA_ISFREE, String.valueOf(childId)));
} else {
YDLRouterManager.Companion.router(url);
}
}
private static int splitParam(String url) {
try {
return Integer.valueOf(url.split("\\?")[1].split("=")[1]);
} catch (Exception e) {
LogUtil.e(e.toString());
return 0;
}
}
}
package com.yidianling.course.courseNew;
import android.content.Context;
import android.graphics.Color;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.widget.RelativeLayout;
import android.widget.TextView;
import in.srain.cube.views.loadmore.LoadMoreContainer;
import in.srain.cube.views.loadmore.LoadMoreUIHandler;
/**
* Created by Jim on 2018/7/20 0020.
*/
public class LoadMoreView extends RelativeLayout implements LoadMoreUIHandler {
private TextView mTextView;
public LoadMoreView(Context context) {
this(context, null);
}
public LoadMoreView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public LoadMoreView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
setupViews();
}
private void setupViews() {
LayoutInflater.from(getContext()).inflate(in.srain.cube.R.layout.cube_views_load_more_default_footer, this);
mTextView = (TextView) findViewById(in.srain.cube.R.id.cube_views_load_more_default_footer_text_view);
mTextView.setTextColor(Color.parseColor("#909599"));
mTextView.setTextSize(11);
}
@Override
public void onLoading(LoadMoreContainer container) {
setVisibility(VISIBLE);
mTextView.setText(in.srain.cube.R.string.cube_views_load_more_loading);
}
@Override
public void onLoadFinish(LoadMoreContainer container, boolean empty, boolean hasMore) {
if (!hasMore) {
setVisibility(VISIBLE);
if (empty) {
mTextView.setText(in.srain.cube.R.string.cube_views_load_more_loaded_empty);
} else {
mTextView.setText("没有更多咯~");
}
} else {
setVisibility(INVISIBLE);
}
}
@Override
public void onWaitToLoadMore(LoadMoreContainer container) {
setVisibility(VISIBLE);
mTextView.setText(in.srain.cube.R.string.cube_views_load_more_click_to_load_more);
}
}
\ No newline at end of file
package com.yidianling.course.courseNew;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.TextUtils;
import android.text.style.AbsoluteSizeSpan;
import android.widget.TextView;
import com.yidianling.course.R;
import com.yidianling.ydlcommon.app.YdlCommonApp;
/**
* Created by Jim on 2018/7/17 0017.
*/
public class PriceUtil {
public static void formatPrice(String price, TextView textView) {
if (TextUtils.isEmpty(price) || "0.00".equals(price) || "null".equals(price)) {
textView.setTextSize(12);
textView.setTextColor(YdlCommonApp.INSTANCE.getApp().getResources().getColor(R.color.google_green));
String money = "0.00";
SpannableString sStr = new SpannableString("¥" + money);
int index = money.indexOf(".") + 1;
if (index != -1) {
sStr.setSpan(new AbsoluteSizeSpan(18, true), 1, index, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
textView.setText(sStr);
} else {
textView.setTextSize(12);
textView.setTextColor(YdlCommonApp.INSTANCE.getApp().getResources().getColor(R.color.cube_holo_orange_dark));
SpannableString sStr = new SpannableString("¥" + price);
int index = price.indexOf(".") + 1;
if (index != -1 && index > 1) {
sStr.setSpan(new AbsoluteSizeSpan(18, true), 1, index, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
textView.setText(sStr);
}
}
}
package com.yidianling.course.courseNew.courseList;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import butterknife.ButterKnife;
import butterknife.Unbinder;
public abstract class BaseLazyFragment extends Fragment {
protected boolean isVisible;
protected boolean isUseLazyMode=true;
private Unbinder mUnBinder;
protected View parentView;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
parentView = inflater.inflate(getLayoutId(), container, false);
return parentView;
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mUnBinder = ButterKnife.bind(this, view);
afterViewCreated(view,savedInstanceState);
}
public abstract void afterViewCreated(View view,Bundle savedInstanceState);
public abstract int getLayoutId();
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (!isUseLazyMode){
return;
}
if (getUserVisibleHint()) {
isVisible = true;
onVisible();
} else {
isVisible = false;
onInvisible();
}
}
public BaseLazyFragment setIsUseLazyMode(boolean isUseLazyMode){
this.isUseLazyMode=isUseLazyMode;
return this;
}
protected void onInvisible() {
}
protected void onVisible() {
lazyLoad();
};
public abstract void lazyLoad();
@Override
public void onDestroyView() {
super.onDestroyView();
mUnBinder.unbind();
}
public View getParentView(){
return parentView;
}
}
\ No newline at end of file
package com.yidianling.course.courseNew.courseList;
/**
* Created by Jim on 2018/7/16 0016.
*/
public class CouresListPresenter {
}
package com.yidianling.course.courseNew.courseList
import `in`.srain.cube.views.loadmore.LoadMoreContainer
import `in`.srain.cube.views.loadmore.LoadMoreHandler
import `in`.srain.cube.views.ptr.PtrDefaultHandler
import `in`.srain.cube.views.ptr.PtrFrameLayout
import `in`.srain.cube.views.ptr.PtrHandler
import `in`.srain.cube.views.ptr.header.MaterialHeader
import android.content.Context
import android.content.Intent
import android.graphics.Typeface
import android.support.v4.content.ContextCompat
import android.text.TextUtils
import android.view.View
import android.widget.AdapterView
import android.widget.LinearLayout
import android.widget.TextView
import com.alibaba.android.arouter.facade.annotation.Route
import com.ydl.base_module.ui.searchbarview.SearchBarView
import com.yidianling.common.tools.LogUtil
import com.yidianling.common.tools.RxImageTool
import com.yidianling.course.CourseConstants
import com.yidianling.course.CourseNewListAdapter
import com.yidianling.course.R
import com.yidianling.course.courseNew.LoadMoreView
import com.yidianling.course.courseNew.courseList.widget.CourseFilterPopupWindow
import com.yidianling.course.courseNew.courseList.widget.CourseGoodPopupWindow
import com.yidianling.course.courseNew.courseList.widget.CourseSortPopupWindow
import com.yidianling.course.coursePlay.common.net.RetrofitUtils
import com.yidianling.course.coursePlay.http.CourseListDataManager
import com.yidianling.course.coursePlay.moudle.Course
import com.yidianling.course.model.CourseCategoryBean
import com.yidianling.course.router.CourseIn
import com.yidianling.ydlcommon.base.BaseActivity
import com.yidianling.ydlcommon.data.ShareData
import com.yidianling.ydlcommon.h5.H5Params
import com.yidianling.ydlcommon.h5.NewH5Activity
import com.yidianling.ydlcommon.http.RxUtils
import com.yidianling.ydlcommon.http.YdlRetrofitUtils
import com.yidianling.ydlcommon.remind.ToastHelper
import com.yidianling.ydlcommon.ui.LogoLoadingView
import com.yidianling.ydlcommon.utils.UMEventUtils
import com.yidianling.ydlcommon.utils.actionutil.ActionCountUtils
import com.yidianling.ydlcommon.utils.actionutil.BIConstants
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import kotlinx.android.synthetic.main.activity_courses.*
import kotlinx.android.synthetic.main.item_hot_search_view.view.*
import org.json.JSONException
import org.json.JSONObject
/**
* 课程分类列表
*/
@Route(path = "/course/list")
class CourseListContainerActivity : BaseActivity(), PtrHandler, LoadMoreHandler {
private var currentType: Int = -1
private var childType: Int = 0
private var adapter: CourseNewListAdapter? = null
private var hasMore = true
private var page = 0
private var keyList = ArrayList<String>()
private var valueList = ArrayList<String>()
//免费1-是 2-否,其他则全部展示
private var isFree = 0
//是否返利 1是 2否,不传则全部
private var isInvite = 0
//是否促销 1是 2否,不传则全部
private var isPromotion = 0
//综合排序字段 默认综合排序
private var selectedSort = "synthesize"
//选定的课程分类
private var selectedCourseList = ArrayList<CourseCategoryBean>()
//所有课程分类
private var allCourseList = ArrayList<CourseCategoryBean>()
//所有的筛选数据
private var allCategoryBean: CourseCategoryBean? = null
//热门筛选数据
private var hotSearchList = ArrayList<CourseCategoryBean>()
companion object {
const val PARAMS_LISTTYPE = "listType"
const val PARAMS_ISFREE = "isFree"
fun start(context: Context, type: Int) {
var i = Intent(context, CourseListContainerActivity::class.java)
i.putExtra(PARAMS_LISTTYPE, type)
context.startActivity(i)
}
fun start(context: Context, type: Int, childType: Int) {
var i = Intent(context, CourseListContainerActivity::class.java)
i.putExtra(PARAMS_LISTTYPE, type)
i.putExtra(PARAMS_ISFREE, childType)
context.startActivity(i)
}
}
override fun layoutResId(): Int {
return R.layout.activity_courses
}
override fun initDataAndEvent() {
currentType = intent.getIntExtra(PARAMS_LISTTYPE, -1)
childType = intent.getIntExtra(PARAMS_ISFREE, 2)
if (!TextUtils.isEmpty(intent.getStringExtra("routerParam"))) {
try {
val jsonObject = JSONObject(intent.getStringExtra("routerParam"))
currentType = jsonObject.getInt(PARAMS_LISTTYPE)
childType = jsonObject.getInt(PARAMS_ISFREE)
} catch (e: JSONException) {
LogUtil.e("--json解析错误" + e.message)
}
}
search_view.initBarType(SearchBarView.JUMP_TO_SEARCH_COURSE, null)
iv_back.setOnClickListener {
ActionCountUtils.count(BIConstants.CourseListEvent.POSITION_COURSE_LIST_RETURN_CLICK)
finish()
}
search_view.setTextVisibility()
init()
loadData()
initCouponHintView()
setClick()
initNetLossView()
}
private fun init() {
// header
val header = MaterialHeader(this)
val colors = resources.getIntArray(R.array.ydl_colors)
header.setColorSchemeColors(colors)
header.layoutParams = PtrFrameLayout.LayoutParams(-1, -2)
val padding = resources.getDimension(R.dimen.default_dis_size).toInt()
header.setPadding(0, padding, 0, padding)
header.setPtrFrameLayout(store_house_ptr_frame)
store_house_ptr_frame.headerView = header
store_house_ptr_frame.setPtrHandler(this)
store_house_ptr_frame.addPtrUIHandler(header)
val footerView = LoadMoreView(this)
load_more_list_view_container.setLoadMoreView(footerView)
load_more_list_view_container.setLoadMoreUIHandler(footerView)
footerView.onLoading(load_more_list_view_container)
load_more_list_view_container.setLoadMoreHandler(this)
adapter = CourseNewListAdapter(this)
lv_content.adapter = adapter
lv_content.onItemClickListener = AdapterView.OnItemClickListener { parent, view, position, id ->
val course = adapter!!.dataList[position]
if (course != null) {
val h5Params = H5Params(CourseConstants.COURSE_DETAIL_H5 + course.id, this@CourseListContainerActivity.getString(R.string.course_detail))
if (null != course.share && !TextUtils.isEmpty(course.share.share_url)) {
val shareData = ShareData(course.share.share_url, course.share.title, course.share.cover, course.share.desc)
h5Params.shareData = shareData
}
UMEventUtils.umEvent("列表页分类点击", "分类id", course.id.toString() + "")
UMEventUtils.umEvent("列表页分类点击", "分类名称", course.title)
NewH5Activity.start(this@CourseListContainerActivity, h5Params)
}
}
getData(false)
}
/**
* 获取课程分类数据
*/
private fun loadData() {
RetrofitUtils.getCourseListCategory()
.subscribeOn(Schedulers.io())
.compose(RxUtils.resultJavaData())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ resp ->
if (resp?.childSample != null && resp.childSample.size > 0) {
allCategoryBean = resp
repeat(resp.childSample.size) {
if (resp.childSample[it].id == 2) {
allCourseList.addAll(resp.childSample[it].childSample)
return@repeat
}
}
if (currentType != -1) {
for (bean in allCourseList) {
if (bean.type == currentType.toString()) {
selectedCourseList.add(bean)
break
}
}
}
if (selectedCourseList.size > 0) {
classify_layout.typeface = Typeface.defaultFromStyle(Typeface.BOLD)
classify_layout.setTextColor(ContextCompat.getColor(this@CourseListContainerActivity, R.color.color_1DA1F2))
} else {
classify_layout.typeface = Typeface.defaultFromStyle(Typeface.NORMAL)
classify_layout.setTextColor(ContextCompat.getColor(this@CourseListContainerActivity, R.color.color_242424))
}
repeat(resp.childSample.size) {
if (resp.childSample[it].id == 4) {
addHotSearchView(resp.childSample[it].childSample)
return@repeat
}
}
}
}, { t: Throwable? ->
})
//
// RetrofitUtils.getCourseListCategory(BaseCommand())
// .subscribeOn(Schedulers.io())
// .compose(RxUtils.resultData())
// .observeOn(AndroidSchedulers.mainThread())
// .subscribe({ resp ->
// if (resp != null && resp.size >= 0) {
// allCourseList.addAll(resp)
// //如果上个页面有传递选中的课程分类,在这里需要添加的选中的list中,弹窗显示时才会有选中信息
// if (currentType != -1) {
// for (bean in allCourseList) {
// if (bean.type == currentType) {
// selectedCourseList.add(bean)
// break
// }
// }
// }
// if (selectedCourseList.size > 0) {
// classify_layout.typeface = Typeface.defaultFromStyle(Typeface.BOLD)
// classify_layout.setTextColor(ContextCompat.getColor(this@CourseListContainerActivity, R.color.color_1DA1F2))
// } else {
// classify_layout.typeface = Typeface.defaultFromStyle(Typeface.NORMAL)
// classify_layout.setTextColor(ContextCompat.getColor(this@CourseListContainerActivity, R.color.color_242424))
// }
//
// addHotSearchView()
// }
// }, { t: Throwable? ->
// })
}
private fun initCouponHintView() {
courseListContainerActivityCouponHintView.initData(View.VISIBLE)
courseListContainerActivityCouponHintView.setCouponList()
}
private fun setClick() {
//综合排序弹窗
sort_layout.setOnClickListener {
var popupWindow = CourseSortPopupWindow(this, selectedSort, object : CourseSortPopupWindow.OnSortItemSelectedListener {
override fun onSortItemSelected(sortItem: String) {
selectedSort = sortItem
getData(false)
ActionCountUtils.count(BIConstants.CourseListEvent.POSITION_COURSE_LIST_SORT_CLICK, selectedSort)
}
})
popupWindow.setOnDismissListener {
sort_layout.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_arrow_drop_down_grey_500_18dp, 0)
}
sort_layout.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_arrow_drop_down_green_18dp, 0)
popupWindow.showAsDropDown(view_line)
}
//分类排序弹窗--现在是只支持单选
classify_layout.setOnClickListener {
var popupWindow = CourseGoodPopupWindow(this, allCourseList, selectedCourseList, object : CourseGoodPopupWindow.OnGoodSelectedListener {
override fun onGoodSelected(selectedGoodsList: ArrayList<CourseCategoryBean>) {//现在是只支持单选:selectedGoodsList里面最多只有一个数据
selectedCourseList.clear()
selectedCourseList.addAll(selectedGoodsList)
if (selectedCourseList.size > 0) {
}
if (selectedGoodsList.size == 0) {
//重置所有选择条件:这时候默认选择全部类型
currentType = 10
}
getData(false)
var name = if (selectedGoodsList.size == 0) "全部类型" else selectedGoodsList[0].name
ActionCountUtils.count(BIConstants.CourseListEvent.POSITION_COURSE_LIST_CLASSIFICATION_CLICK, name)
}
})
popupWindow.setOnDismissListener {
if (selectedCourseList.size > 0) {
classify_layout.typeface = Typeface.defaultFromStyle(Typeface.BOLD)
classify_layout.setTextColor(ContextCompat.getColor(this@CourseListContainerActivity, R.color.color_1DA1F2))
} else {
classify_layout.typeface = Typeface.defaultFromStyle(Typeface.NORMAL)
classify_layout.setTextColor(ContextCompat.getColor(this@CourseListContainerActivity, R.color.color_242424))
}
classify_layout.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_arrow_drop_down_grey_500_18dp, 0)
}
classify_layout.setTextColor(ContextCompat.getColor(this@CourseListContainerActivity, R.color.color_1DA1F2))
classify_layout.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_arrow_drop_down_green_18dp, 0)
popupWindow.showAsDropDown(view_line)
}
//筛选
filter_layout.setOnClickListener {
var popupWindow = CourseFilterPopupWindow(this@CourseListContainerActivity, isFree, isInvite, isPromotion, object : CourseFilterPopupWindow.OnFilterSelectedListener {
override fun onFilterSelected(isFree: Int, isInvite: Int, isPromotion: Int) {
this@CourseListContainerActivity.isFree = isFree
this@CourseListContainerActivity.isInvite = isInvite
this@CourseListContainerActivity.isPromotion = isPromotion
getData(false)
var sign = if (isFree == 1) "免费" else "付费"
if (isInvite == 1) {
sign += "返利"
}
if (isPromotion == 1) {
sign += "促销"
}
ActionCountUtils.count(BIConstants.CourseListEvent.POSITION_COURSE_LIST_FILTER_CLICK, sign)
}
})
popupWindow.setOnDismissListener {
if (this@CourseListContainerActivity.isFree != 0 || this@CourseListContainerActivity.isInvite != 0 || this@CourseListContainerActivity.isPromotion != 0) {
filter_layout.typeface = Typeface.defaultFromStyle(Typeface.BOLD)
filter_layout.setTextColor(ContextCompat.getColor(this@CourseListContainerActivity, R.color.color_1DA1F2))
} else {
filter_layout.typeface = Typeface.defaultFromStyle(Typeface.NORMAL)
filter_layout.setTextColor(ContextCompat.getColor(this@CourseListContainerActivity, R.color.color_242424))
}
filter_layout.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_arrow_drop_down_grey_500_18dp, 0)
}
filter_layout.setTextColor(ContextCompat.getColor(this@CourseListContainerActivity, R.color.color_1DA1F2))
filter_layout.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_arrow_drop_down_green_18dp, 0)
popupWindow.showAsDropDown(view_line)
}
}
/**
* 初始化无网络视图
*/
private fun initNetLossView() {
v_loading.setListener(object : LogoLoadingView.LogoLoadingListener {
override fun onDataResetClick() {
v_loading.visibility = View.VISIBLE
v_loading.setViewType(LogoLoadingView.TYPE_LOADING, null)
getData(false)
}
override fun onBackClick() {
finish()
}
})
}
/**
* 获取课程具体数据
*/
private fun getData(loadMore: Boolean) {
when (currentType) {
1, 2 -> if (!CourseIn.isLogin()) {
return
}
else -> {
}
}
if (loadMore && !hasMore) {
load_more_list_view_container.loadMoreFinish(false, false)
return
}
if (loadMore) {
page++
} else {
page = 1
hasMore = true
}
getCourses(loadMore)
}
private fun getCourses(loadMore: Boolean) {
val sb = StringBuffer()
if (selectedCourseList.size > 0) {
currentType = selectedCourseList[0].type.toInt()
}
if (currentType >= 10) {
sb.append("&listType=").append(currentType)
} else {
sb.append("&listType=").append(currentType + 1)
}
sb.append("&page=").append(page)
.append("&isFree=").append(isFree)
.append("&reorder=").append(selectedSort)
.append("&isInvite=").append(isInvite)
.append("&isPromotion=").append(isPromotion)
if (keyList.size > 0) {
repeat(keyList.size) {
sb.append("&${keyList[it]}=").append(valueList[it])
}
}
val urlParams = YdlRetrofitUtils.getCommonParam() + sb.toString()
//不是上拉加载更多,是第一次加载或者下拉刷新,且当前页面还没有数据
if (!loadMore && adapter?.count!! <= 0) {
lv_content.visibility = View.GONE
v_loading.visibility = View.VISIBLE
v_loading.setViewType(LogoLoadingView.TYPE_LOADING, null)
}
CourseListDataManager.getHttp().getCourseList(urlParams).compose(RxUtils.resultJavaData()).subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ resp ->
if (resp.list.isNotEmpty()) {
if (load_more_list_view_container != null) {
load_more_list_view_container.loadMoreFinish(false, true)
}
try {
val courses = ArrayList<Course>()
courses.addAll(resp.list)
if (courses.size < CourseConstants.COURSE_PAGE_SIZE) {
hasMore = false
}
if (!loadMore) {
adapter!!.dataList = courses
adapter!!.notifyDataSetChanged()
lv_content.setSelection(0)
} else {
adapter!!.addDataList(courses)
adapter!!.notifyDataSetChanged()
}
} catch (e: Exception) {
LogUtil.e(e.toString())
}
lv_content.visibility = View.VISIBLE
tv_course_list_empty_prompt.visibility = View.GONE
iv_course_list_empty_view.visibility = View.GONE
v_loading.visibility = View.GONE
} else {
lv_content.visibility = View.GONE
tv_course_list_empty_prompt.visibility = View.VISIBLE
iv_course_list_empty_view.visibility = View.VISIBLE
iv_course_list_empty_view.setImageResource(R.drawable.blank)
tv_course_list_empty_prompt.text = "还没有相应的课程哦~"
v_loading.visibility = View.GONE
}
}, { throwable ->
v_loading.visibility = View.GONE
if (adapter!!.mDataList == null || adapter!!.mDataList.size <= 0) {
lv_content.visibility = View.GONE
tv_course_list_empty_prompt.visibility = View.GONE
iv_course_list_empty_view.visibility = View.GONE
v_loading.visibility = View.VISIBLE
v_loading.setViewType(LogoLoadingView.TYPE_NET_LOSS, "哎呦,网络开小差了")
} else {
ToastHelper.show("网络不给力")
RetrofitUtils.handleError(this@CourseListContainerActivity, throwable)
}
})
}
private fun addHotSearchView(list: List<CourseCategoryBean>) {
hotSearchList.clear()
hotSearchList.addAll(list)
repeat(list.size) {
var index = it
val textView = View.inflate(this, R.layout.item_hot_search_view, null)
val tv = textView.tv_hot_search
val params = LinearLayout.LayoutParams(0, RxImageTool.dp2px(22f))
params.weight = 1f
params.setMargins(0, 0, RxImageTool.dp2px(10f), 0)
tv.layoutParams = params
tv.text = list[it].name
tv.setOnClickListener {
if (tv.isSelected) {
dealHotSelect(list[index], false)
tv.isSelected = false
} else {
dealHotSelect(list[index], true)
tv.isSelected = true
}
}
ll_hot_search.addView(textView)
}
}
private fun dealHotSelect(bean: CourseCategoryBean, isAdd: Boolean) {
when (bean.parentId) {
1 -> {//排序
if (isAdd) {
selectedSort = bean.type
//处理view选中状态
repeat(hotSearchList.size) {
if (hotSearchList[it].parentId == 1 && !TextUtils.equals(hotSearchList[it].name, bean.name)) {
val textView = ll_hot_search.getChildAt(it) as TextView
textView.isSelected = false
}
}
} else {
selectedSort = "synthesize"
}
}
2 -> {//分类
selectedCourseList.clear()
if (isAdd) {
selectedCourseList.add(bean)
} else {
//重置所有分类条件:这时候默认选择全部类型
currentType = 10
}
repeat(hotSearchList.size) {
if (hotSearchList[it].parentId == 2 && !TextUtils.equals(hotSearchList[it].name, bean.name)) {
val textView = ll_hot_search.getChildAt(it) as TextView
textView.isSelected = false
}
}
if (selectedCourseList.size > 0) {
classify_layout.typeface = Typeface.defaultFromStyle(Typeface.BOLD)
classify_layout.setTextColor(ContextCompat.getColor(this@CourseListContainerActivity, R.color.color_1DA1F2))
} else {
classify_layout.typeface = Typeface.defaultFromStyle(Typeface.NORMAL)
classify_layout.setTextColor(ContextCompat.getColor(this@CourseListContainerActivity, R.color.color_242424))
}
classify_layout.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_arrow_drop_down_grey_500_18dp, 0)
}
3 -> {//筛选
if (isAdd) {
if (TextUtils.equals(bean.name, "免费") || TextUtils.equals(bean.name, "付费")) {
isFree += bean.type.toInt()
}
if (TextUtils.equals(bean.name, "限时促销")) {
isInvite = 1
}
if (TextUtils.equals(bean.name, "邀请返利")) {
isPromotion = 1
}
} else {
if (TextUtils.equals(bean.name, "免费") || TextUtils.equals(bean.name, "付费")) {
isFree -= bean.type.toInt()
}
if (TextUtils.equals(bean.name, "限时促销")) {
isInvite = 0
}
if (TextUtils.equals(bean.name, "邀请返利")) {
isPromotion = 0
}
}
if (this@CourseListContainerActivity.isFree != 0 || this@CourseListContainerActivity.isInvite != 0 || this@CourseListContainerActivity.isPromotion != 0) {
filter_layout.typeface = Typeface.defaultFromStyle(Typeface.BOLD)
filter_layout.setTextColor(ContextCompat.getColor(this@CourseListContainerActivity, R.color.color_1DA1F2))
} else {
filter_layout.typeface = Typeface.defaultFromStyle(Typeface.NORMAL)
filter_layout.setTextColor(ContextCompat.getColor(this@CourseListContainerActivity, R.color.color_242424))
}
}
else -> {//热门筛选
if (isAdd) {
keyList.add(bean.value)
valueList.add(bean.type)
} else {
keyList.remove(bean.value)
valueList.remove(bean.type)
}
}
}
getData(false)
}
override fun onRefreshBegin(frame: PtrFrameLayout?) {
frame!!.postDelayed({
if (store_house_ptr_frame != null) {
store_house_ptr_frame.refreshComplete()
}
}, 1800)
getData(false)
}
override fun onResume() {
super.onResume()
ActionCountUtils.count(BIConstants.CourseListEvent.POSITION_COURSE_LIST_PAGE_VISIT)
}
override fun checkCanDoRefresh(frame: PtrFrameLayout?, content: View?, header: View?): Boolean {
return PtrDefaultHandler.checkContentCanBePulledDown(frame, lv_content, header)
}
override fun onLoadMore(loadMoreContainer: LoadMoreContainer?) {
getData(true)
}
}
package com.yidianling.course.courseNew.courseList;//package com.yidianling.course.courseNew.courseList;
//
//import com.yidianling.common.tools.LogUtil;
//import com.yidianling.course.coursePlay.common.net.Command;
//import com.yidianling.course.coursePlay.common.net.RetrofitUtils;
//import com.yidianling.course.coursePlay.moudle.Course;
//import com.yidianling.ydlcommon.http.RxUtils;
//
//import java.util.List;
//
//import io.reactivex.android.schedulers.AndroidSchedulers;
//import io.reactivex.functions.Consumer;
//import io.reactivex.schedulers.Schedulers;
//
///**
// * Created by Jim on 2018/7/16 0016.
// */
//
//public class CourseListPresenter {
//
// private ICourseListView mView;
//
// public CourseListPresenter(ICourseListView view){
// mView=view;
// }
//
// public void fetchData(Command.GetCourse cmd) {
// RetrofitUtils.getCourseList(cmd)
// .subscribeOn(Schedulers.io())
// .compose(RxUtils.resultData())
// .observeOn(AndroidSchedulers.mainThread())
// .subscribe(resp-> {
//
// },throwable -> {
// mView.showLoadErrorView();
// LogUtil.e("load error: "+throwable.toString());
// });
// }
//
//}
package com.yidianling.course.courseNew.courseList;
/**
* Created by Jim on 2018/7/16 0016.
*/
public interface ICourseListView {
void hideRefreshView();
void showLoadErrorView();
}
package com.yidianling.course.courseNew.courseList.widget
import android.content.Context
import android.graphics.Typeface
import android.graphics.drawable.BitmapDrawable
import android.view.LayoutInflater
import android.view.ViewGroup
import android.widget.PopupWindow
import android.widget.TextView
import com.yidianling.course.R
import kotlinx.android.synthetic.main.course_filter_popup_window.view.*
/**
* @author yuanwai
* @描述:课程-筛选popWindow
* @Copyright Copyright (c) 2018
* @Company 壹点灵
* @date 2018/9/22
*
* @param isFree 免费1-是 2-否,其他则全部展示
* @param isInvite 是否返利 1是 2否,其他则全部
* @param isPromotion 是否促销 1是 2否,其他则全部
*/
class CourseFilterPopupWindow(var context: Context, var isFree: Int, var isInvite: Int, var isPromotion: Int,
var onFilterSelectedListener: OnFilterSelectedListener)
: PopupWindow(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT) {
//付费是否选中 1:选中 0:没选
private var hasSelectNoFree = 0
//免费是否选中 1:选中 0:没选
private var hasSelectFree = 0
init {
val view = LayoutInflater.from(context).inflate(R.layout.course_filter_popup_window, null)
this.contentView = view
this.isFocusable = true
@Suppress("DEPRECATION")
this.setBackgroundDrawable(BitmapDrawable())
this.isOutsideTouchable = true
inputMethodMode = PopupWindow.INPUT_METHOD_NEEDED
view.btn_confirm.setOnClickListener {
dismiss()
}
view.v_zhezhao.setOnClickListener {
dismiss()
}
when (isFree) {//是否免费这项:全选和全不选,意义是一样的
0 -> {//两项都没选
setSelect(view.tv_free, false)
setSelect(view.tv_no_free, false)
}
1 -> {//免费
setSelect(view.tv_free, true)
}
2 -> {//付费
setSelect(view.tv_no_free, true)
}
3 -> {//两项都选了
setSelect(view.tv_free, true)
setSelect(view.tv_no_free, true)
}
}
when (isPromotion) {//是否促销 1是 2否,其他则全部
1 -> {
setSelect(view.tv_promotion, true)
}
else -> {
setSelect(view.tv_promotion, false)
}
}
when (isInvite) {//是否返利 1是 2否,其他则全部
1 -> {
setSelect(view.tv_invite, true)
}
else -> {
setSelect(view.tv_invite, false)
}
}
hasSelectNoFree = if (isFree == 2 || isFree == 3) {
1
} else {
0
}
hasSelectFree = if (isFree == 1 || isFree == 3) {
1
} else {
0
}
view.tv_no_free.setOnClickListener {
if (hasSelectNoFree == 0) {
hasSelectNoFree = 1
setSelect(view.tv_no_free, true)
} else {
hasSelectNoFree = 0
setSelect(view.tv_no_free, false)
}
}
view.tv_free.setOnClickListener {
if (hasSelectFree == 0) {
hasSelectFree = 1
setSelect(view.tv_free, true)
} else {
hasSelectFree = 0
setSelect(view.tv_free, false)
}
}
view.tv_promotion.setOnClickListener {
if (isPromotion == 1) {
isPromotion = 0
setSelect(view.tv_promotion, false)
} else {
isPromotion = 1
setSelect(view.tv_promotion, true)
}
}
view.tv_invite.setOnClickListener {
if (isInvite == 1) {
isInvite = 0
setSelect(view.tv_invite, false)
} else {
isInvite = 1
setSelect(view.tv_invite, true)
}
}
//重置数据
view.btn_reset.setOnClickListener {
hasSelectNoFree = 0
hasSelectFree = 0
isInvite = 0
isPromotion = 0
setSelect(view.tv_invite, false)
setSelect(view.tv_promotion, false)
setSelect(view.tv_no_free, false)
setSelect(view.tv_free, false)
}
//确认
view.btn_confirm.setOnClickListener {
isFree = if (hasSelectNoFree == 0 && hasSelectFree == 0) {
0
} else if (hasSelectNoFree == 0 && hasSelectFree == 1) {
1
} else if (hasSelectNoFree == 1 && hasSelectFree == 0) {
2
} else {
3
}
onFilterSelectedListener.onFilterSelected(isFree, isInvite, isPromotion)
dismiss()
}
}
/**
* 设置选中样式
*/
private fun setSelect(textView: TextView, boolean: Boolean) {
if (boolean) {
textView.setBackgroundResource(R.drawable.course_filter_select_sel)
textView.typeface = Typeface.defaultFromStyle(Typeface.BOLD)
} else {
textView.setBackgroundResource(R.drawable.course_filter_select_nor)
textView.typeface = Typeface.defaultFromStyle(Typeface.NORMAL)
}
}
interface OnFilterSelectedListener {
/**
* @param isFree 免费1-是 2-否,不传则全部展示
* @param isInvite 是否返利 1是 2否,不传则全部
* @param isPromotion 是否促销 1是 2否,不传则全部
*/
fun onFilterSelected(isFree: Int, isInvite: Int, isPromotion: Int)
}
}
\ No newline at end of file
package com.yidianling.course.courseNew.courseList.widget
import android.content.Context
import android.graphics.Typeface
import android.graphics.drawable.BitmapDrawable
import android.support.v7.widget.GridLayoutManager
import android.support.v7.widget.LinearLayoutManager
import android.view.LayoutInflater
import android.view.ViewGroup
import android.widget.PopupWindow
import com.yidianling.common.tools.RxImageTool
import com.yidianling.course.R
import com.yidianling.course.courseNew.courseList.widget.adapter.CourseGoodAdapter
import com.yidianling.course.model.CourseCategoryBean
import com.yidianling.ydlcommon.view.SpaceItemDecorator
import kotlinx.android.synthetic.main.course_good_popup_window.view.*
/**
* @author yuanwai
* @描述:课程列表页-分类popWindow 目前逻辑只支持单选
* @Copyright Copyright (c) 2018
* @Company 壹点灵
* @date 2018/9/22
*/
class CourseGoodPopupWindow(context: Context, allCourseList: ArrayList<CourseCategoryBean>, selectedCourseList: ArrayList<CourseCategoryBean>,
var onGoodSelectedListener: OnGoodSelectedListener)
: PopupWindow(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT) {
//擅长方向列表数据
private var goodsList: ArrayList<CourseCategoryBean>? = null
//已选择的擅长方向数据
private var selectedGoodsList: ArrayList<CourseCategoryBean>? = null
init {
val view = LayoutInflater.from(context).inflate(R.layout.course_good_popup_window, null)
this.contentView = view
this.isFocusable = true
@Suppress("DEPRECATION")
this.setBackgroundDrawable(BitmapDrawable())
this.isOutsideTouchable = true
val rvGood = view.rvGood
val tvTitle = view.tv_title
tvTitle.text = "课程类型"
if (null == this.goodsList) {
this.goodsList = ArrayList()
} else {
(this.goodsList as ArrayList).clear()
}
this.goodsList!!.addAll(allCourseList)
if (null == this.selectedGoodsList) {
this.selectedGoodsList = ArrayList()
} else {
(this.selectedGoodsList as ArrayList).clear()
}
this.selectedGoodsList!!.addAll(selectedCourseList)
var goodAdapter: CourseGoodAdapter? = null
if (null == rvGood.adapter) {
goodAdapter = CourseGoodAdapter(context, this.goodsList!!, this.selectedGoodsList!!)
rvGood.adapter = goodAdapter
rvGood.layoutManager = GridLayoutManager(context, 3, LinearLayoutManager.VERTICAL, false)
rvGood.addItemDecoration(SpaceItemDecorator(RxImageTool.dp2px(8f), 3))
}
inputMethodMode = PopupWindow.INPUT_METHOD_NEEDED
view.btnConfirm.setOnClickListener {
onGoodSelectedListener?.onGoodSelected(this.selectedGoodsList!!)
dismiss()
}
view.btnReset.setOnClickListener {
goodAdapter?.cleanSelectedGoods()
}
view.v_zhezhao.setOnClickListener {
dismiss()
}
}
interface OnGoodSelectedListener {
fun onGoodSelected(selectedGoodsList: ArrayList<CourseCategoryBean>)
}
}
\ No newline at end of file
package com.yidianling.course.courseNew.courseList.widget
import android.content.Context
import android.graphics.Typeface
import android.graphics.drawable.BitmapDrawable
import android.support.v4.content.ContextCompat
import android.view.LayoutInflater
import android.view.ViewGroup
import android.widget.PopupWindow
import android.widget.TextView
import com.yidianling.course.R
import kotlinx.android.synthetic.main.course_sort_popup_window.view.*
/**
* @author yuanwai
* @描述:课程综合排序popupWindow(选项是本地写死的,选择后传给服务端的也是固定字段)
* 选项对应接口字段:synthesize综合 read人气 price价格 new最新
* @Copyright Copyright (c) 2018
* @Company 壹点灵
* @date 2018/9/22
*/
class CourseSortPopupWindow(val context: Context, var selectedSort: String, private val onSortItemSelectedListener: OnSortItemSelectedListener)
: PopupWindow(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT) {
init {
val view = LayoutInflater.from(context).inflate(R.layout.course_sort_popup_window, null)
this.contentView = view
this.isFocusable = true
@Suppress("DEPRECATION")
this.setBackgroundDrawable(BitmapDrawable())
this.isOutsideTouchable = true
view.v_zhezhao.setOnClickListener {
dismiss()
}
when (selectedSort) {//ynthesize综合 read人气 price价格 new最新
"synthesize" -> {
setSelect(view.tv_ynthesize)
}
"read" -> {
setSelect(view.tv_read)
}
"price" -> {
setSelect(view.tv_price)
}
"new" -> {
setSelect(view.tv_new)
}
}
view.tv_ynthesize.setOnClickListener {
onSortItemSelectedListener.onSortItemSelected("synthesize")
dismiss()
}
view.tv_read.setOnClickListener {
onSortItemSelectedListener.onSortItemSelected("read")
dismiss()
}
view.tv_price.setOnClickListener {
onSortItemSelectedListener.onSortItemSelected("price")
dismiss()
}
view.tv_new.setOnClickListener {
onSortItemSelectedListener.onSortItemSelected("new")
dismiss()
}
}
private fun setSelect(textView: TextView) {
textView.setTextColor(ContextCompat.getColor(context, R.color.color_1DA1F2))
textView.typeface = Typeface.defaultFromStyle(Typeface.BOLD)
}
interface OnSortItemSelectedListener {
fun onSortItemSelected(sortItem: String)
}
}
\ No newline at end of file
package com.yidianling.course.courseNew.courseList.widget.adapter
import android.content.Context
import android.graphics.Typeface
import android.support.v7.widget.RecyclerView
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import com.yidianling.course.R
import com.yidianling.course.model.CourseCategoryBean
import kotlinx.android.synthetic.main.item_course_good_item.view.*
/**
* @author yuanwai
* @描述:课程列表页--筛选模块--擅长方式popwindow适配器
* @Copyright Copyright (c) 2018
* @Company 壹点灵
* @date 2018/9/22
*/
class CourseGoodAdapter(private val context: Context, private val goods: ArrayList<CourseCategoryBean>, private val selectedGood: ArrayList<CourseCategoryBean>) : RecyclerView.Adapter<CourseGoodAdapter.ViewHolder>() {
override fun onBindViewHolder(holder: ViewHolder?, position: Int) {
if (holder != null) {
val category = goods[position]
holder.tvGoodName.text = goods[position].name
holder.tvGoodName.isSelected = selectedGood.contains(category)
if (holder.tvGoodName.isSelected) {
holder.tvGoodName.setBackgroundResource(R.drawable.course_filter_select_sel)
holder.tvGoodName.typeface = Typeface.defaultFromStyle(Typeface.BOLD)
} else {
holder.tvGoodName.setBackgroundResource(R.drawable.course_filter_select_nor)
holder.tvGoodName.typeface = Typeface.defaultFromStyle(Typeface.NORMAL)
}
}
}
fun cleanSelectedGoods() {
selectedGood?.clear()
notifyDataSetChanged()
}
override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): ViewHolder {
val itemView = LayoutInflater.from(context).inflate(R.layout.item_course_good_item, parent, false)
return ViewHolder(itemView)
}
override fun getItemCount(): Int = goods.size
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val tvGoodName: TextView = itemView.tvGoodName
init {
itemView.setOnClickListener {
if (adapterPosition != RecyclerView.NO_POSITION) {
val subject = goods[adapterPosition]
when {
//如果 点击已选中的 那就移除 然后更新
selectedGood.contains(subject) -> {
selectedGood.remove(subject)
notifyItemChanged(adapterPosition)
}
else -> {
//如果点击没选中的 则添加
selectedGood.clear()//目前只支持单选
selectedGood.add(subject)
notifyDataSetChanged()
}
}
}
}
}
}
}
package com.yidianling.course.courseNew.home
import android.support.v4.widget.SwipeRefreshLayout
import android.support.v7.widget.LinearLayoutManager
import android.text.TextUtils
import android.view.View
import com.alibaba.android.arouter.launcher.ARouter
import com.ydl.base_module.ui.searchbarview.SearchBarView
import com.ydl.ydl_image.module.GlideApp
import com.ydl.ydl_router.manager.YDLRouterManager
import com.yidianling.course.R
import com.yidianling.course.bean.CourseCouponBean
import com.yidianling.course.bean.CourseHomeBodyBean
import com.yidianling.course.courseNew.BannerBean
import com.yidianling.course.courseNew.mine.MyCourseActivity
import com.yidianling.course.courseNew.sections.*
import com.yidianling.course.coursePlay.common.net.RetrofitUtils
import com.yidianling.course.model.CatogoryBean
import com.yidianling.course.model.NormalCourseBean
import com.yidianling.course.model.QulityCourseBean
import com.yidianling.course.router.CourseIn
import com.yidianling.course.widget.CourseCouponDialog
import com.yidianling.ydlcommon.adapter.section.SectionAdapter
import com.yidianling.ydlcommon.base.BaseFragment
import com.yidianling.ydlcommon.event.SelectTabCallPhoneEvent
import com.yidianling.ydlcommon.http.BaseResponse
import com.yidianling.ydlcommon.player.YDLMusicHelper
import com.yidianling.ydlcommon.remind.ToastHelper
import com.yidianling.ydlcommon.ui.LogoLoadingView
import com.yidianling.ydlcommon.utils.UMEventUtils
import com.yidianling.ydlcommon.utils.actionutil.ActionCountUtils
import com.yidianling.ydlcommon.utils.actionutil.BIConstants
import de.greenrobot.event.EventBus
import kotlinx.android.synthetic.main.fragment_course_home.*
/**
* Created by Jim on 2018/6/21 0021.
* 课程首页Fragment
*/
class CourseHomeFragment : BaseFragment(), ICourseHomeView, SwipeRefreshLayout.OnRefreshListener {
private var presenter: CourseHomePresenter = CourseHomePresenter(this)
private var adapter = SectionAdapter()
private var dialog: CourseCouponDialog? = null
companion object {
private const val BANNER = 1
private const val CATEGORY = 2
private const val QULITY_COURSE = 3
private const val CLASSIFIED_COURSE = 4
private const val TOPIC = 5
private const val LIST_END = 7
}
override fun layoutResId(): Int {
return R.layout.fragment_course_home
}
override fun initDataAndEvent() {
}
override fun initDataAndEventLazy() {
initViews()
initNetLossView()
//加载本地缓存数据
presenter.localData(context)
presenter.fetchData()
initCouponHintView()
}
override fun isAddStatusView(): Boolean {
return true
}
override fun setUserVisibleHint(isVisibleToUser: Boolean) {
super.setUserVisibleHint(isVisibleToUser)
if (isVisibleToUser) {
presenter.prepareCoupon()
ActionCountUtils.count(BIConstants.CourseHomeEvent.POSITION_COURSE_HOME_PAGE_VISIT)
}
}
private fun initCouponHintView() {
couponHintView.initData(View.VISIBLE)
couponHintView.setCouponList()
}
private fun initViews() {
iv_back.setOnClickListener {
EventBus.getDefault().post(SelectTabCallPhoneEvent(0))
}
swl?.setOnRefreshListener(this)
swl?.setColorSchemeResources(R.color.google_green)
rcv?.layoutManager = LinearLayoutManager(activity)
rcv?.adapter = adapter
activity_course_search_bar.initBarType(SearchBarView.JUMP_TO_SEARCH_COURSE, null)
GlideApp.with(activity).load(R.drawable.music).into(img_music)
img_music.setOnClickListener {
if (YDLMusicHelper.isCoursePlaying()) {
//课程播放页
YDLMusicHelper.startCoursePlayActivity(activity, 1)
} else {
img_music.visibility = View.GONE
}
}
tv_left_menu.setOnClickListener {
ActionCountUtils.count(BIConstants.CourseHomeEvent.POSITION_COURSE_HOME_MY_COUSE_CLICK)
UMEventUtils.umEvent("我的课程点击", "我的课程", "我的课程")
if (CourseIn.isLogin()) {
MyCourseActivity.start(activity)
} else {
startActivity(CourseIn.loginWayIntent(activity))
}
}
}
private fun initNetLossView() {
v_loading.visibility = View.VISIBLE
v_loading.setViewType(LogoLoadingView.TYPE_LOADING, null)
v_loading.setListener(object : LogoLoadingView.LogoLoadingListener {
override fun onDataResetClick() {
v_loading.setViewType(LogoLoadingView.TYPE_LOADING, null)
presenter.fetchData()
}
override fun onBackClick() {
EventBus.getDefault().post(SelectTabCallPhoneEvent(0))
}
})
}
override fun showBody(resultBeans: List<ResultBean>) {
if (resultBeans.isEmpty()) {
return
}
v_loading.visibility = View.GONE
rcv?.visibility = View.VISIBLE
adapter.clearData()
for (resultBean in resultBeans) {
when (resultBean.type) {
BANNER -> {
val bannerMap = resultBean.body
val banners = ArrayList<BannerBean>()
for (map in bannerMap) {
val banner = BannerBean()
banner.image = map.image
banner.title = map.title
banner.linkUrl = map.linkUrl
banners.add(banner)
}
adapter.addSection(BannerSection(banners))
}
CATEGORY -> {
val categoryMap = resultBean.body
val categorys = ArrayList<CatogoryBean>()
for (map in categoryMap) {
val category = CatogoryBean()
category.image = map.image
category.title = map.title
category.linkUrl = map.linkUrl
categorys.add(category)
}
adapter.addSection(CategorySection(categorys))
}
QULITY_COURSE -> {
val totalCourse = ArrayList<ArrayList<CourseHomeBodyBean>>()
val coursesLeft = ArrayList<CourseHomeBodyBean>()
val coursesRight = ArrayList<CourseHomeBodyBean>()
for (result in resultBean.body) {
if (TextUtils.equals(result.type, "1")) {
coursesLeft.add(result)
}
if (TextUtils.equals(result.type, "2")) {
coursesRight.add(result)
}
}
totalCourse.add(coursesLeft)
totalCourse.add(coursesRight)
val course = QulityCourseBean().apply {
this.diviLine = resultBean.diviLine
this.head = resultBean.head
this.footer = resultBean.footer
this.body = totalCourse
}
adapter.addSection(QulityCourseSection(activity, course, adapter))
}
CLASSIFIED_COURSE -> {
val classifiedMap = resultBean.body
val normal = NormalCourseBean().apply {
this.head = resultBean.head
this.footer = resultBean.footer
this.diviLine = resultBean.diviLine
this.body = classifiedMap
}
adapter.addSection(ClassifiedCourseSection(activity, normal))
}
TOPIC -> {
val topicMap = resultBean.body
val normal = NormalCourseBean().apply {
this.head = resultBean.head
this.footer = resultBean.footer
this.diviLine = resultBean.diviLine
this.body = topicMap
}
adapter.addSection(TopicsCoursesSection(context, normal))
}
LIST_END -> {
val head = resultBean.head
adapter.addSection(ListEndSection(head.title))
}
}
}
adapter.notifyDataSetChanged()
}
/**
* 可领取的优惠券列表
*/
override fun couponDataResponse(data: List<CourseCouponBean>) {
if (dialog == null) {
dialog = CourseCouponDialog(activity, data, object : CourseCouponDialog.OnClickEnsureListener {
override fun clickUse(toLink: String) {
YDLRouterManager.router(toLink)
dialog!!.dismiss()
}
override fun clickEnsure(status: Int) {
if (status == CourseCouponDialog.STATUS_RECEIVER) {
presenter.receiveCoupon(data)
} else {
dialog!!.dismiss()
//查看我的卡券
ARouter.getInstance().build("/mine/redpacket")
.withString("is_from_main", "1")
.navigation()
}
}
})
}
dialog!!.show()
}
/**
* 优惠券领取成功
*/
override fun receiveCouponResponse(data: BaseResponse<List<String>>) {
if (data.code == 200) {
dialog?.updateStatus(CourseCouponDialog.STATUS_GET, data.data)
} else {
ToastHelper.show(data.msg)
}
}
override fun showLoadErrorView(throwable: Throwable?) {
RetrofitUtils.handleError(activity, throwable)
}
override fun hideRefreshView() {
swl?.isRefreshing = false
}
override fun showRefreshView() {
swl?.isRefreshing = true
v_loading.visibility = View.VISIBLE
v_loading.setViewType(LogoLoadingView.TYPE_LOADING, null)
}
override fun onRefresh() {
swl?.isRefreshing = true
presenter.fetchData()
}
override fun onDestroy() {
super.onDestroy()
presenter?.onDestroy()
}
}
package com.yidianling.course.courseNew.home
import android.annotation.SuppressLint
import android.content.Context
import android.os.Handler
import android.text.TextUtils
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import com.yidianling.common.tools.LogUtil
import com.yidianling.common.tools.ToastUtil
import com.yidianling.course.bean.CourseCouponBean
import com.yidianling.course.coursePlay.common.net.RetrofitUtils
import com.yidianling.router.RouterManager
import com.yidianling.ydlcommon.http.RxUtils
import com.yidianling.ydlcommon.http.ThrowableConsumer
import com.yidianling.ydlcommon.router.YdlCommonRouterManager
import com.yidianling.ydlcommon.utils.AssetsUtils
import com.yidianling.ydlcommon.utils.YDLAsyncUtils
import com.yidianling.ydlcommon.utils.YDLCacheUtils
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.functions.Consumer
import io.reactivex.schedulers.Schedulers
import java.text.SimpleDateFormat
import java.util.*
/**
* Created by Jim on 2018/7/11 0011.
*/
class CourseHomePresenter(var view: ICourseHomeView) {
private var hasRequestCoupon = false
private val compositeSubscription = CompositeDisposable()
/**
* 加载本地缓存
*/
fun localData(context: Context) {
YDLAsyncUtils.asyncAsResult(object : YDLAsyncUtils.AsyncObjecyerResult {
override fun doAsyncAction(): Any {
var cacheData = YDLCacheUtils.getCourseHomeData()
if (cacheData?.isEmpty()!!) {
cacheData = String(AssetsUtils.getAssertsFile(context, "course_home.json")!!)
}
return cacheData
}
override fun asyncResult(`object`: Any?) {
if (`object` is String) {
val gson = Gson()
if (!TextUtils.isEmpty(`object`)) {
val list = gson.fromJson<List<ResultBean>>(`object`, object : TypeToken<List<ResultBean>>() {}.type)
view.showBody(list)
}
}
}
})
}
/**
* 更新本地缓存
*/
private fun updateCache(list: List<ResultBean>) {
YDLAsyncUtils.async(object : YDLAsyncUtils.AsyncObjecyer {
override fun doAsyncAction() {
val gson = Gson()
val json = gson.toJson(list)
YDLCacheUtils.saveCourseHomeData(json)
}
})
}
fun fetchData() {
compositeSubscription.add(RetrofitUtils.getCoursesHomePage()
.subscribeOn(Schedulers.io())
.compose(RxUtils.resultJavaData())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ response ->
view.hideRefreshView()
view.showBody(response)
//更新本地缓存数据
updateCache(response)
}, { t: Throwable? ->
view.hideRefreshView()
view.showLoadErrorView(t)
LogUtil.e("CoursesHomePage data fetch error: " + t.toString())
}))
}
/**
* 获取优惠券信息
*/
fun prepareCoupon() {
//判断是否登录 以及本次app启动后是否已经请求过
if (RouterManager.getUserRouter()?.isLogin() == true && !hasRequestCoupon) {
Handler().postDelayed({
//优惠券逻辑
if (compareCouponTime()) {
getCouponData()
}
}, 2000)
}
}
/**
* 获取可以领取的课程优惠券
*
* @param uid uid
* @param services 适用服务 1预约咨询 2电话倾诉 3课程(用户课程 专家课程) 5测评
* @param receiveType 领取条件方式 1前台领取 2链接领取
* @param applyEnds 适用终端 1PC官网 2wap站点 3用户app 4好杮app 5专家app
* @return
*/
@SuppressLint("SimpleDateFormat")
private fun getCouponData() {
val (userId) = YdlCommonRouterManager.getYdlCommonRoute().getUserInfo() ?: return
val disposable = RetrofitUtils.getCourseCoupons(userId, "3", "1", "3")
.compose(RxUtils.netCheck())
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(Consumer {
hasRequestCoupon = true
val simpleFormat = SimpleDateFormat("yyyy-MM-dd HH:mm:ss")//如2016-08-10
val time = System.currentTimeMillis()
val date = Date()
date.time = time
val nowTime = simpleFormat.format(date)
if (it?.data != null && !it.data.isEmpty()) {
YDLCacheUtils.saveCouponTime(userId, nowTime)
view.couponDataResponse(it.data)
}
}, object : ThrowableConsumer() {
override fun accept(msg: String) {
}
})
compositeSubscription.add(disposable)
}
/**
* 领取优惠券
*/
fun receiveCoupon(list: List<CourseCouponBean>) {
val (userId) = YdlCommonRouterManager.getYdlCommonRoute().getUserInfo() ?: return
val couponIds = ArrayList<String>()
for (bean in list) {
couponIds.add(bean.id)
}
val bean = CouponReceiveBean()
bean.couponIds = couponIds
bean.uid = userId
val couponIdsStr = Gson().toJson(bean)
view.showRefreshView()
val disposable = RetrofitUtils.receiveCoupon(couponIdsStr)
.compose(RxUtils.netCheck())
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(Consumer {
view.hideRefreshView()
view.receiveCouponResponse(it)
}, object : ThrowableConsumer() {
override fun accept(msg: String) {
ToastUtil.toastShort(msg)
view.hideRefreshView()
}
})
compositeSubscription.add(disposable)
}
/**
* 对比上次获取优惠券时间,若时间差超过一天,则再次请求,否则不获请求
*/
@SuppressLint("SimpleDateFormat")
private fun compareCouponTime(): Boolean {
val uid = YdlCommonRouterManager.getYdlCommonRoute().getUserInfo()?.userId
val simpleFormat = SimpleDateFormat("yyyy-MM-dd HH:mm:ss")//如2016-08-10
val last = YDLCacheUtils.getCouponTime(uid)
return if (TextUtils.isEmpty(last)) {
//还没有获取过优惠券,直接请求数据
true
} else {
val time = System.currentTimeMillis()
val date = Date()
date.time = time
val nowTime = simpleFormat.format(date)
!TextUtils.equals(last.substring(0, 10), nowTime.substring(0, 10))
}
}
fun onDestroy() {
compositeSubscription.dispose()
}
inner class CouponReceiveBean {
var couponIds: List<String>? = null
var uid: String? = null
}
}
\ No newline at end of file
package com.yidianling.course.courseNew.home
import com.hannesdorfmann.mosby3.mvp.MvpView
import com.yidianling.course.bean.CourseCouponBean
import com.yidianling.ydlcommon.http.BaseResponse
/**
* Created by Jim on 2018/7/11 0011.
*/
interface ICourseHomeView : MvpView {
fun showBody(resultBeans: List<ResultBean>)
fun hideRefreshView()
fun showRefreshView()
fun showLoadErrorView(throwable: Throwable?)
fun couponDataResponse(data: List<CourseCouponBean>)
fun receiveCouponResponse(data: BaseResponse<List<String>>)
}
package com.yidianling.course.courseNew.home;
import com.google.gson.annotations.SerializedName;
import com.yidianling.course.bean.CourseHomeBodyBean;
import java.util.List;
/**
* Created by Jim on 2018/7/13 0013.
*/
public class ResultBean {
public Head head;
public List<CourseHomeBodyBean> body;
public Footer footer;
public int type;
public boolean diviLine;
public static class Head {
public String title;
public String subTitle;
public String subLinkUrl;
public String tab1Name;
public String tab2Name;
}
public static class Footer {
public String title;
@SerializedName(value = "linkUrl",alternate = "LinkUrl")
public String linkUrl;
}
}
package com.yidianling.course.courseNew.mine;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.util.TypedValue;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.ydl.base_module.ui.searchbarview.SearchBarView;
import com.yidianling.course.CourseListFragment;
import com.yidianling.course.R;
import com.yidianling.ydlcommon.base.BaseActivity;
import com.yidianling.ydlcommon.ui.confideredpacket.ConfideRedPacketView;
import com.yidianling.ydlcommon.utils.DisplayUtils;
import com.yidianling.ydlcommon.utils.UMEventUtils;
import java.lang.reflect.Field;
/**
* Created by Jim on 2018/7/16 0016.
* 心理课程
*/
public class MyCourseActivity extends BaseActivity {
public final static String TAB_KEY = "tab_index";
public final static int TAB_PAIED = 2;
public final static int TAB_COLLECT = 1;
private int tabIndex;
public static void start(Context context) {
Intent i = new Intent(context, MyCourseActivity.class);
i.putExtra(TAB_KEY, TAB_PAIED);
context.startActivity(i);
}
public static void start(Context context, int index) {
Intent i = new Intent(context, MyCourseActivity.class);
i.putExtra(TAB_KEY, index);
context.startActivity(i);
}
@Override
protected int layoutResId() {
return R.layout.activity_my_course;
}
@Override
protected void initDataAndEvent() {
tabIndex = getIntent().getIntExtra(TAB_KEY, -1);
TextView tv = findViewById(R.id.tv_title);
tv.setText("我的课程");
ImageView iv = findViewById(R.id.iv_back);
findViewById(R.id.tv_left_menu).setVisibility(View.GONE);
iv.setOnClickListener(view -> {
finish();
});
SearchBarView searchBarView = findViewById(R.id.search_bar);
searchBarView.initBarType(SearchBarView.JUMP_TO_SEARCH_COURSE, null);
TabLayout tabLayout = findViewById(R.id.my_courses_tabs);
ViewPager viewPager = findViewById(R.id.my_course_vp);
tabLayout.setupWithViewPager(viewPager);
viewPager.setAdapter(new MyCourseFragmentAdapter(getSupportFragmentManager()));
viewPager.setCurrentItem(2);
tabLayout.post(new Runnable() {
@Override
public void run() {
setIndicator(tabLayout, 15, 15);
}
});
//初始化倾诉红包
initConfideRedPacketView();
}
private void initConfideRedPacketView() {
ConfideRedPacketView confideRedPacketView = findViewById(R.id.confideRedPacketView);
confideRedPacketView.initData(View.VISIBLE);
confideRedPacketView.setConfide();
}
public void setIndicator(TabLayout tabs, int leftDip, int rightDip) {
Class<?> tabLayout = tabs.getClass();
Field tabStrip = null;
try {
tabStrip = tabLayout.getDeclaredField("mTabStrip");
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
tabStrip.setAccessible(true);
LinearLayout llTab = null;
try {
llTab = (LinearLayout) tabStrip.get(tabs);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
int left = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, leftDip, Resources.getSystem().getDisplayMetrics());
int right = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, rightDip, Resources.getSystem().getDisplayMetrics());
for (int i = 0; i < llTab.getChildCount(); i++) {
View child = llTab.getChildAt(i);
child.setPadding(0, 0, 0, 0);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.MATCH_PARENT, 1);
params.leftMargin = DisplayUtils.dip2px(this, left);
params.rightMargin = DisplayUtils.dip2px(this, right);
child.setLayoutParams(params);
child.invalidate();
}
}
static class MyCourseFragmentAdapter extends FragmentPagerAdapter {
private Fragment[] mFragments;
private String[] titles = new String[]{"收藏", "已购"};
public MyCourseFragmentAdapter(FragmentManager fm) {
super(fm);
mFragments = new Fragment[]{CourseListFragment.newInstance(2), CourseListFragment.newInstance(1)};
}
@Override
public Fragment getItem(int position) {
if (position == 0) {
UMEventUtils.umEvent("我的课程", "收藏", "收藏");
} else {
UMEventUtils.umEvent("我的课程", "已购", "已购");
}
return mFragments[position];
}
@Override
public int getCount() {
return mFragments.length;
}
@Override
public CharSequence getPageTitle(int position) {
return titles[position];
}
}
}
package com.yidianling.course.courseNew.sections;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.yidianling.common.tools.LogUtil;
import com.yidianling.course.R;
import com.yidianling.course.courseNew.BannerBean;
import com.yidianling.course.courseNew.CourseHeadPagerAdapter;
import com.yidianling.ydlcommon.adapter.section.Section;
import com.yidianling.ydlcommon.view.LoopViewPager;
import java.util.List;
/**
* Created by Jim on 2018/6/22 0022.
* 轮播图模版
*/
public class BannerSection extends Section {
private List<BannerBean> mBanners;
private final int IDENTIFY_TYPE = BANNER_SECTION;
public BannerSection(List<BannerBean> banners) {
super(R.layout.item_course_banner);
this.mBanners=banners;
}
@Override
public void bindViewHolder(RecyclerView.ViewHolder holder, int position) {
if (holder instanceof BannerViewHolder){
((BannerViewHolder) holder).notifyData(mBanners);
}
}
@Override
public int getTotalDataNum() {
return 1;
}
@Override
public int getItemViewType(int position) {
return combineType(IDENTIFY_TYPE, TYPE_BODY);
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view= LayoutInflater.from(parent.getContext()).inflate(itemResourceId,parent,false);
return new BannerViewHolder(view,mBanners);
}
@Override
public boolean isBelongTo(int viewType) {
return String.valueOf(viewType).startsWith(String.valueOf(IDENTIFY_TYPE));
}
@Override
public boolean isHeadType(int position) {
return false;
}
@Override
public boolean isFooterType(int position) {
return false;
}
@Override
public int getSectionId() {
return 0;
}
static class BannerViewHolder extends RecyclerView.ViewHolder {
private LoopViewPager mHeadViewPager;
private CourseHeadPagerAdapter mAdapter;
public BannerViewHolder(View itemView,List<BannerBean> banners) {
super(itemView);
mHeadViewPager=itemView.findViewById(R.id.vp_head_bar);
mAdapter=new CourseHeadPagerAdapter(banners,itemView.getContext());
mHeadViewPager.setAdapter(mAdapter);
}
public void notifyData(List<BannerBean> banners){
mAdapter=new CourseHeadPagerAdapter(banners,itemView.getContext());
mHeadViewPager.setAdapter(mAdapter);
}
}
}
package com.yidianling.course.courseNew.sections;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import com.yidianling.common.tools.RxDeviceTool;
import com.yidianling.course.R;
import com.yidianling.course.courseNew.CategoryItemView;
import com.yidianling.course.courseNew.LinkUrlRouterProtocol;
import com.yidianling.course.model.CatogoryBean;
import com.yidianling.ydlcommon.adapter.section.Section;
import com.yidianling.ydlcommon.utils.UMEventUtils;
import com.yidianling.ydlcommon.utils.actionutil.ActionCountUtils;
import com.yidianling.ydlcommon.utils.actionutil.BIConstants;
import java.util.List;
import cn.lankton.flowlayout.FlowLayout;
/**
* Created by Jim on 2018/6/25 0025.
*/
public class CategorySection extends Section {
private final int IDENTIFY_TYPE = CATEGORY_SECTION;
public List<CatogoryBean> datas;
public CategorySection(List<CatogoryBean> datas) {
super(R.layout.item_category2);
this.datas = datas;
}
@Override
public void bindViewHolder(RecyclerView.ViewHolder holder, int position) {
if (holder instanceof CategoryViewHolder) {
}
}
@Override
public int getTotalDataNum() {
return 1;
}
@Override
public int getItemViewType(int position) {
return combineType(IDENTIFY_TYPE, TYPE_BODY);
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(itemResourceId, parent, false);
return new CategoryViewHolder(view, datas);
}
@Override
public boolean isBelongTo(int viewType) {
return String.valueOf(viewType).startsWith(String.valueOf(IDENTIFY_TYPE));
}
@Override
public boolean isHeadType(int position) {
return false;
}
@Override
public boolean isFooterType(int position) {
return false;
}
@Override
public int getSectionId() {
return 0;
}
static class CategoryViewHolder extends RecyclerView.ViewHolder {
public CategoryViewHolder(View itemView, List<CatogoryBean> datas) {
super(itemView);
int width = RxDeviceTool.getScreenWidth(itemView.getContext());
FlowLayout flowLayout = itemView.findViewById(R.id.flow_layout);
int itemWidth = width / 4;
for (int i = 0; i < datas.size(); i++) {
CatogoryBean category = datas.get(i);
CategoryItemView ciView = new CategoryItemView(itemView.getContext());
ViewGroup.MarginLayoutParams params = new ViewGroup.MarginLayoutParams(itemWidth, WindowManager.LayoutParams.WRAP_CONTENT);
ciView.setLayoutParams(params);
ciView.setText(category.title);
ciView.setImage(category.image);
ciView.setOnClickListener(view -> {
UMEventUtils.umEvent("课程分类点击", "分类id", category.linkUrl);
UMEventUtils.umEvent("课程分类点击", "分类名称", category.title);
ActionCountUtils.Companion.count(BIConstants.CourseHomeEvent.POSITION_COURSE_HOME_CLASSIFICATION_CLICK, category.title);
if (!TextUtils.isEmpty(category.linkUrl)) {
LinkUrlRouterProtocol.jump(itemView.getContext(), category.linkUrl);
}
});
flowLayout.addView(ciView);
}
}
}
}
package com.yidianling.course.courseNew.sections;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.yidianling.course.R;
import com.yidianling.course.bean.CourseHomeBodyBean;
import com.yidianling.course.courseNew.LinkUrlRouterProtocol;
import com.yidianling.course.courseNew.viewholder.FooterMoreViewHolder;
import com.yidianling.course.courseNew.viewholder.SingleTitleHeaderViewHolder;
import com.yidianling.course.coursePlay.moudle.Course;
import com.yidianling.course.model.NormalCourseBean;
import com.yidianling.course.widget.CourseItemNewView;
import com.yidianling.ydlcommon.adapter.section.Section;
import com.yidianling.ydlcommon.utils.UMEventUtils;
import com.yidianling.ydlcommon.utils.actionutil.ActionCountUtils;
import com.yidianling.ydlcommon.utils.actionutil.BIConstants;
/**
* Created by Jim on 2018/6/25 0025.
* 分类课程模版
*/
public class ClassifiedCourseSection extends Section {
private final int IDENTIFY_TYPE = CLASSIFY_COURSE_SECTION;
private NormalCourseBean data;
private int totalNum;
private Context context;
public ClassifiedCourseSection(Context context, NormalCourseBean bean) {
super(R.layout.item_classified_title, R.layout.item_more, R.layout.item_course_list);
this.context = context;
this.data = bean;
initTotlaNum();
}
@Override
public void bindViewHolder(RecyclerView.ViewHolder holder, int position) {
if (holder instanceof FooterMoreViewHolder) {
((FooterMoreViewHolder) holder).titleView.setText(data.footer.title);
((FooterMoreViewHolder) holder).linearLayout.setOnClickListener(view -> {
UMEventUtils.umEvent(data.head.title, "更多课程", "更多课程");
LinkUrlRouterProtocol.jump(context, data.footer.linkUrl);
if (!TextUtils.isEmpty(data.head.title)) {
if (data.head.title.contains("线下")) {
ActionCountUtils.Companion.count(BIConstants.CourseHomeEvent.POSITION_COURSE_HOME_OFFLINE_CERTIFICATION_TRAINING_MORE_CLICK);
} else {
ActionCountUtils.Companion.count(BIConstants.CourseHomeEvent.POSITION_COURSE_HOME_CONSULTANT_COURSE_MORE_CLICK);
}
}
});
} else if (holder instanceof SingleTitleHeaderViewHolder) {
((SingleTitleHeaderViewHolder) holder).titleView.setText(data.head.title);
} else if (holder instanceof CourseItemViewHolder) {
CourseItemViewHolder realHolder = (CourseItemViewHolder) holder;
// if ((data.head != null && position == 1) || (data.head == null && position == 0)) {
// realHolder.hideDividerLine();
// } else {
// realHolder.tv_line_bottom.setVisibility(View.VISIBLE);
// }
CourseHomeBodyBean course = data.body.get(position - 1);
Course courseBean = switchData(course);
realHolder.courseItemNewView.setData(courseBean);
holder.itemView.setOnClickListener(view -> {
UMEventUtils.umEvent(data.head.title, data.head.title + "链接", course.linkUrl);
LinkUrlRouterProtocol.jump(context, courseBean.linkUrl);
if (!TextUtils.isEmpty(data.head.title)) {
if (data.head.title.contains("线下")) {
ActionCountUtils.Companion.count(BIConstants.CourseHomeEvent.POSITION_COURSE_HOME_OFFLINE_CERTIFICATION_TRAINING_XXX_CLICK + courseBean.id + "_click");
}
}
});
}
}
private Course switchData(CourseHomeBodyBean bean) {
Course course = new Course();
course.id = bean.id;
course.title = bean.title;
course.hostListPic = bean.hostListPic;
course.courseHostInfo = bean.courseHostInfo;
course.hostInfo = bean.hostInfo;
course.pic = bean.pic;
course.image = bean.image;
course.subCourseNum = bean.subCourseNum;
course.doctorName = bean.doctorName;
course.joinNum = bean.joinNum;
course.isInvite = bean.isInvite;
course.applyFee = bean.applyFee;
course.recommend = bean.recommend;
course.newCourse = bean.newCourse;
course.demoType = bean.demoType;
course.originalApplyFee = bean.originalApplyFee;
course.courseType = bean.courseType;
course.isBuy = bean.isBuy;
course.demoFile = bean.demoFile;
course.promotionApplyFee = bean.promotionApplyFee;
course.isPromotion = bean.isPromotion;
course.linkUrl = bean.linkUrl;
return course;
}
private void initTotlaNum() {
totalNum = 0;
if (data.head != null) {
totalNum++;
}
if (data.footer != null) {
totalNum++;
}
if (data.body != null) {
totalNum += data.body.size();
}
}
@Override
public int getTotalDataNum() {
return totalNum;
}
@Override
public int getItemViewType(int position) {
if (isHeadType(position)) {
return combineType(IDENTIFY_TYPE, TYPE_HEADER);
} else if (isFooterType(position)) {
return combineType(IDENTIFY_TYPE, TYPE_FOOTER);
} else {
return combineType(IDENTIFY_TYPE, TYPE_BODY);
}
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = null;
if (viewType == combineType(IDENTIFY_TYPE, TYPE_HEADER)) {
view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_classified_title, parent, false);
return new SingleTitleHeaderViewHolder(view);
} else if (viewType == combineType(IDENTIFY_TYPE, TYPE_FOOTER)) {
view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_more, parent, false);
return new FooterMoreViewHolder(view);
} else {
view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_course_list, parent, false);
return new CourseItemViewHolder(view);
}
}
@Override
public boolean isBelongTo(int viewType) {
return String.valueOf(viewType).startsWith(String.valueOf(IDENTIFY_TYPE));
}
@Override
public boolean isHeadType(int position) {
return data.head != null && position == 0;
}
@Override
public boolean isFooterType(int position) {
return data.footer != null && position == totalNum - 1;
}
@Override
public int getSectionId() {
return IDENTIFY_TYPE;
}
static class CourseItemViewHolder extends RecyclerView.ViewHolder {
public CourseItemNewView courseItemNewView;
public View tv_line_bottom;
public CourseItemViewHolder(View itemView) {
super(itemView);
courseItemNewView = itemView.findViewById(R.id.view_content);
tv_line_bottom = itemView.findViewById(R.id.tv_line_bottom);
}
public void hideDividerLine() {
tv_line_bottom.setVisibility(View.INVISIBLE);
}
}
}
package com.yidianling.course.courseNew.sections;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.yidianling.course.R;
import com.yidianling.ydlcommon.adapter.section.Section;
import com.yidianling.ydlcommon.view.BaseViewHolder;
/**
* Created by Jim on 2018/6/27 0027.
*/
public class ListEndSection extends Section {
private final int IDENTIFY_TYPE=LIST_END_SECTION;
public ListEndSection() {
super(R.layout.item_list_end);
}
private String title;
public ListEndSection(String title) {
super(R.layout.item_list_end);
this.title = title;
}
@Override
public void bindViewHolder(RecyclerView.ViewHolder holder, int position) {
}
@Override
public int getTotalDataNum() {
return 1;
}
@Override
public int getItemViewType(int position) {
return combineType(IDENTIFY_TYPE,TYPE_BODY);
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view= LayoutInflater.from(parent.getContext()).inflate(itemResourceId,parent,false);
BaseViewHolder viewHolder = new BaseViewHolder(view);
viewHolder.setText(R.id.tv_title, title);
return viewHolder;
}
@Override
public boolean isBelongTo(int viewType) {
return String.valueOf(viewType).startsWith(String.valueOf(IDENTIFY_TYPE));
}
@Override
public boolean isHeadType(int position) {
return false;
}
@Override
public boolean isFooterType(int position) {
return false;
}
@Override
public int getSectionId() {
return 0;
}
}
package com.yidianling.course.courseNew.sections;
import android.content.Context;
import android.support.v4.content.ContextCompat;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import com.yidianling.course.R;
import com.yidianling.course.bean.CourseHomeBodyBean;
import com.yidianling.course.courseNew.LinkUrlRouterProtocol;
import com.yidianling.course.courseNew.viewholder.FooterMoreViewHolder;
import com.yidianling.course.coursePlay.moudle.Course;
import com.yidianling.course.model.QulityCourseBean;
import com.yidianling.ydlcommon.adapter.section.Section;
import com.yidianling.ydlcommon.utils.UMEventUtils;
import com.yidianling.ydlcommon.utils.actionutil.ActionCountUtils;
import com.yidianling.ydlcommon.utils.actionutil.BIConstants;
/**
* Created by Jim on 2018/6/25 0025.
*/
public class QulityCourseSection extends Section {
private final int IDENTIFY_TYPE = QULITY_COURSE_SECTION;
private QulityCourseBean data;
private int totalNum = 0;
private static final int FREE = 0;
private static final int PAY = 1;
public static int type = PAY;
public void setType(int type) {
this.type = type;
initTotlaNum();
adapter.notifyDataSetChanged();
}
private RecyclerView.Adapter adapter;
private Context context;
public QulityCourseSection(Context context, QulityCourseBean data, RecyclerView.Adapter adapter) {
super(R.layout.item_head_quality_course, R.layout.item_more, R.layout.item_course_list);
this.context = context;
this.adapter = adapter;
this.data = data;
type = PAY;
initTotlaNum();
}
private void initTotlaNum() {
}
@Override
public void bindViewHolder(RecyclerView.ViewHolder holder, int position) {
if (holder instanceof FooterMoreViewHolder) {
((FooterMoreViewHolder) holder).titleView.setText(data.footer.title);
((FooterMoreViewHolder) holder).linearLayout.setOnClickListener(v -> {
UMEventUtils.umEvent("更多课程", "更多课程", "更多课程");
LinkUrlRouterProtocol.jump(context, data.footer.linkUrl + "?childId=" + (type + 1));
ActionCountUtils.Companion.count(BIConstants.CourseHomeEvent.POSITION_COURSE_HOME_EXCELLENT_COURSES_MORE_CLICK);
});
} else if (holder instanceof QulityCourseHeaderVH) {
((QulityCourseHeaderVH) holder).tv_title.setText(data.head.title);
((QulityCourseHeaderVH) holder).tv_tab1.setText(data.head.tab1Name);
((QulityCourseHeaderVH) holder).tv_tab2.setText(data.head.tab2Name);
if (type == PAY) {
((QulityCourseHeaderVH) holder).tv_tab2.setTextColor(ContextCompat.getColor(holder.itemView.getContext(), R.color.green_34cd65));
((QulityCourseHeaderVH) holder).iv_tab2.setVisibility(View.VISIBLE);
((QulityCourseHeaderVH) holder).tv_tab1.setTextColor(ContextCompat.getColor(holder.itemView.getContext(), R.color.grey_909599));
((QulityCourseHeaderVH) holder).iv_tab1.setVisibility(View.INVISIBLE);
} else {
((QulityCourseHeaderVH) holder).tv_tab1.setTextColor(ContextCompat.getColor(holder.itemView.getContext(), R.color.green_34cd65));
((QulityCourseHeaderVH) holder).iv_tab1.setVisibility(View.VISIBLE);
((QulityCourseHeaderVH) holder).tv_tab2.setTextColor(ContextCompat.getColor(holder.itemView.getContext(), R.color.grey_909599));
((QulityCourseHeaderVH) holder).iv_tab2.setVisibility(View.INVISIBLE);
}
} else if (holder instanceof ClassifiedCourseSection.CourseItemViewHolder) {
ClassifiedCourseSection.CourseItemViewHolder realHolder = (ClassifiedCourseSection.CourseItemViewHolder) holder;
// if ((data.head != null && position == 1) || (data.head == null && position == 0)) {
// realHolder.hideDividerLine();
// } else {
// realHolder.tv_line_bottom.setVisibility(View.VISIBLE);
// }
CourseHomeBodyBean course = data.body.get(type).get(position - 1);
Course courseBean = switchData(course);
realHolder.courseItemNewView.setData(courseBean);
holder.itemView.setOnClickListener(view -> {
UMEventUtils.umEvent("精品课程", "精品课程链接", courseBean.linkUrl);
LinkUrlRouterProtocol.jump(context, courseBean.linkUrl);
if (type == PAY) {
ActionCountUtils.Companion.count(BIConstants.CourseHomeEvent.POSITION_COURSE_HOME_EXCELLENT_COURSES_PAY_XXX_CLICK + courseBean.id + "_click");
} else {
ActionCountUtils.Companion.count(BIConstants.CourseHomeEvent.POSITION_COURSE_HOME_EXCELLENT_COURSES_FREE_XXX_CLICK + courseBean.id + "_click");
}
});
}
}
/**
* 这里是个坑
*
* @param bean
* @return
*/
private Course switchData(CourseHomeBodyBean bean) {
Course course = new Course();
course.id = bean.id;
course.title = bean.title;
course.hostListPic = bean.hostListPic;
course.courseHostInfo = bean.courseHostInfo;
course.pic = bean.pic;
course.image = bean.image;
course.hostInfo = bean.hostInfo;
course.subCourseNum = bean.subCourseNum;
course.doctorName = bean.doctorName;
course.joinNum = bean.joinNum;
course.isInvite = bean.isInvite;
course.applyFee = bean.applyFee;
course.recommend = bean.recommend;
course.newCourse = bean.newCourse;
course.demoType = bean.demoType;
course.originalApplyFee = bean.originalApplyFee;
course.isBuy = bean.isBuy;
course.demoFile = bean.demoFile;
course.promotionApplyFee = bean.promotionApplyFee;
course.courseType = bean.courseType;
course.isPromotion = bean.isPromotion;
course.linkUrl = bean.linkUrl;
return course;
}
@Override
public int getTotalDataNum() {
totalNum = 0;
if (data.head != null) {
totalNum++;
}
if (data.footer != null) {
totalNum++;
}
if (data.body != null) {
totalNum += data.body.get(type).size();
}
return totalNum;
}
@Override
public int getItemViewType(int position) {
if (isHeadType(position)) {
return combineType(IDENTIFY_TYPE, TYPE_HEADER);
} else if (isFooterType(position)) {
return combineType(IDENTIFY_TYPE, TYPE_FOOTER);
} else {
return combineType(IDENTIFY_TYPE, TYPE_BODY);
}
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (viewType == combineType(IDENTIFY_TYPE, TYPE_HEADER)) {
View view = LayoutInflater.from(parent.getContext()).inflate(headerResourceId, parent, false);
return new QulityCourseHeaderVH(this, view);
} else if (viewType == combineType(IDENTIFY_TYPE, TYPE_FOOTER)) {
View view = LayoutInflater.from(parent.getContext()).inflate(footerResourceId, parent, false);
return new FooterMoreViewHolder(view);
} else {
View view = LayoutInflater.from(parent.getContext()).inflate(itemResourceId, parent, false);
return new ClassifiedCourseSection.CourseItemViewHolder(view);
}
}
@Override
public boolean isBelongTo(int viewType) {
return String.valueOf(viewType).startsWith(String.valueOf(IDENTIFY_TYPE));
}
@Override
public boolean isHeadType(int position) {
return data.head != null && position == 0;
}
@Override
public boolean isFooterType(int position) {
return data.footer != null && position == totalNum - 1;
}
@Override
public int getSectionId() {
return IDENTIFY_TYPE;
}
static class QulityCourseHeaderVH extends RecyclerView.ViewHolder {
public TextView tv_title, tv_tab1, tv_tab2;
public ImageView iv_tab1, iv_tab2;
public QulityCourseHeaderVH(QulityCourseSection section, View itemView) {
super(itemView);
tv_title = itemView.findViewById(R.id.tv_title);
tv_tab1 = itemView.findViewById(R.id.tv_tab1);
iv_tab1 = itemView.findViewById(R.id.iv_tab1);
tv_tab2 = itemView.findViewById(R.id.tv_tab2);
iv_tab2 = itemView.findViewById(R.id.iv_tab2);
itemView.findViewById(R.id.ll_tab1).setOnClickListener(v -> {
UMEventUtils.umEvent("精品课程", "免费课程", "免费课程");
tv_tab1.setTextColor(ContextCompat.getColor(itemView.getContext(), R.color.green_34cd65));
iv_tab1.setVisibility(View.VISIBLE);
tv_tab2.setTextColor(ContextCompat.getColor(itemView.getContext(), R.color.grey_909599));
iv_tab2.setVisibility(View.INVISIBLE);
section.setType(FREE);
});
itemView.findViewById(R.id.ll_tab2).setOnClickListener(v -> {
UMEventUtils.umEvent("精品课程", "付费课程", "付费课程");
tv_tab2.setTextColor(ContextCompat.getColor(itemView.getContext(), R.color.green_34cd65));
iv_tab2.setVisibility(View.VISIBLE);
tv_tab1.setTextColor(ContextCompat.getColor(itemView.getContext(), R.color.grey_909599));
iv_tab1.setVisibility(View.INVISIBLE);
section.setType(PAY);
});
}
}
}
package com.yidianling.course.courseNew.sections;
import android.content.Context;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.yidianling.course.R;
import com.yidianling.course.bean.CourseHomeBodyBean;
import com.yidianling.course.courseNew.LinkUrlRouterProtocol;
import com.yidianling.course.courseNew.viewholder.SingleTitleHeaderViewHolder;
import com.yidianling.course.link.CourseLinkUrl;
import com.yidianling.course.model.NormalCourseBean;
import com.yidianling.ydlcommon.adapter.section.Section;
import com.yidianling.ydlcommon.utils.UMEventUtils;
import com.yidianling.ydlcommon.utils.actionutil.ActionCountUtils;
import com.yidianling.ydlcommon.utils.actionutil.BIConstants;
import com.yidianling.ydlcommon.view.BaseViewHolder;
import java.util.List;
/**
* Created by Jim on 2018/6/27 0027.
*/
public class TopicsCoursesSection extends Section {
private final int IDENTIFY_TYPE = TOPICS_COURSES_SECTION;
private Context mContext;
private NormalCourseBean data;
public TopicsCoursesSection(Context mContext, NormalCourseBean data) {
super(R.layout.item_classified_title, 0, R.layout.item_topics_courses);
this.mContext = mContext;
this.data = data;
}
@Override
public void bindViewHolder(RecyclerView.ViewHolder holder, int position) {
if (holder instanceof SingleTitleHeaderViewHolder) {
if (data.head != null) {
if (!TextUtils.isEmpty(data.head.title)) {
((SingleTitleHeaderViewHolder) holder).titleView.setText(data.head.title);
}
if (!TextUtils.isEmpty(data.head.subTitle)) {
((SingleTitleHeaderViewHolder) holder).subTitleView.setVisibility(View.VISIBLE);
((SingleTitleHeaderViewHolder) holder).subTitleView.setText(data.head.subTitle);
((SingleTitleHeaderViewHolder) holder).subTitleView.setOnClickListener(v -> {
UMEventUtils.umEvent("专题课程", "更多点击", "更多点击");
if (null != mContext) {
CourseLinkUrl.Companion.jump(mContext, data.head.subLinkUrl);
}
ActionCountUtils.Companion.count(BIConstants.CourseHomeEvent.POSITION_COURSE_HOME_THEMATIC_COURSES_MORE_CLICK);
});
} else {
((SingleTitleHeaderViewHolder) holder).subTitleView.setVisibility(View.GONE);
}
}
} else if (holder instanceof TopicsCoursesVH) {
((TopicsCoursesVH) holder).notifyData(data.body);
}
}
@Override
public int getTotalDataNum() {
return 2;
}
@Override
public int getItemViewType(int position) {
if (isHeadType(position)) {
return combineType(IDENTIFY_TYPE, TYPE_HEADER);
}
return combineType(IDENTIFY_TYPE, TYPE_BODY);
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = null;
if (viewType == combineType(IDENTIFY_TYPE, TYPE_HEADER)) {
view = LayoutInflater.from(parent.getContext()).inflate(headerResourceId, parent, false);
return new SingleTitleHeaderViewHolder(view);
}
view = LayoutInflater.from(parent.getContext()).inflate(itemResourceId, parent, false);
return new TopicsCoursesVH(view, data.body);
}
@Override
public boolean isBelongTo(int viewType) {
return String.valueOf(viewType).startsWith(String.valueOf(IDENTIFY_TYPE));
}
@Override
public boolean isHeadType(int position) {
return data.head != null && position == 0;
}
@Override
public boolean isFooterType(int position) {
return false;
}
@Override
public int getSectionId() {
return 0;
}
static class TopicsCoursesVH extends RecyclerView.ViewHolder {
private RecyclerView mRecyclerView;
private Adapter mAdapter;
public TopicsCoursesVH(View itemView, List<CourseHomeBodyBean> data) {
super(itemView);
mRecyclerView = itemView.findViewById(R.id.rcv_topics_courses);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(itemView.getContext());
linearLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
mRecyclerView.setLayoutManager(linearLayoutManager);
mAdapter = new Adapter(data, itemView.getContext());
mRecyclerView.setAdapter(mAdapter);
}
public void notifyData(List<CourseHomeBodyBean> data) {
mAdapter.data = data;
mAdapter.notifyDataSetChanged();
}
}
static class Adapter extends RecyclerView.Adapter<BaseViewHolder> {
private List<CourseHomeBodyBean> data;
private Context mContext;
public Adapter(List<CourseHomeBodyBean> data, Context context) {
this.data = data;
mContext = context;
}
public void setData(List<CourseHomeBodyBean> data) {
this.data = data;
}
@Override
public BaseViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_imag, parent, false);
return new BaseViewHolder(view);
}
@Override
public void onBindViewHolder(BaseViewHolder holder, int position) {
holder.setImageWithUrl(R.id.img, data.get(position).image);
holder.setOnClickListener(R.id.img, view -> {
UMEventUtils.umEvent("专题课程", "专题链接", data.get(position).linkUrl);
LinkUrlRouterProtocol.jump(mContext, data.get(position).linkUrl);
ActionCountUtils.Companion.count(BIConstants.CourseHomeEvent.POSITION_COURSE_HOME_THEMATIC_COURSES_XXX_CLICK + data.get(position).id + "_click");
});
}
@Override
public int getItemCount() {
return data.size();
}
}
}
package com.yidianling.course.courseNew.viewholder;
import android.content.Context;
import android.content.Intent;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.yidianling.common.tools.LogUtil;
import com.yidianling.course.R;
import com.yidianling.course.courseNew.courseList.CourseListContainerActivity;
//更多课程
public class FooterMoreViewHolder extends RecyclerView.ViewHolder {
public TextView titleView;
public LinearLayout linearLayout;
public FooterMoreViewHolder(View itemView) {
super(itemView);
titleView = itemView.findViewById(R.id.tv_title);
linearLayout = itemView.findViewById(R.id.ll_more);
}
}
\ No newline at end of file
package com.yidianling.course.courseNew.viewholder;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.yidianling.course.R;
public class SingleTitleHeaderViewHolder extends RecyclerView.ViewHolder {
public TextView titleView;
public TextView subTitleView;
public SingleTitleHeaderViewHolder(View itemView) {
super(itemView);
titleView = itemView.findViewById(R.id.single_title);
subTitleView = itemView.findViewById(R.id.tv_more);
}
public SingleTitleHeaderViewHolder(Context context, ViewGroup parent) {
super(LayoutInflater.from(context).inflate(R.layout.item_classified_title, parent, false));
titleView = itemView.findViewById(R.id.single_title);
subTitleView = itemView.findViewById(R.id.tv_more);
}
}
\ No newline at end of file
package com.yidianling.course.coursePlay
import android.app.Activity
import android.content.Intent
import android.text.Editable
import android.text.TextUtils
import android.text.TextWatcher
import com.alibaba.android.arouter.facade.annotation.Route
import com.yidianling.common.tools.ToastUtil
import com.yidianling.course.CourseConstants
import com.yidianling.course.R
import com.yidianling.course.coursePlay.common.net.Command
import com.yidianling.course.coursePlay.common.net.RetrofitUtils
import com.yidianling.ydlcommon.base.BaseActivity
import com.yidianling.ydlcommon.h5.H5Params
import com.yidianling.ydlcommon.h5.NewH5Activity
import com.yidianling.ydlcommon.log.LogHelper
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import kotlinx.android.synthetic.main.activity_course_commeny.*
/**
* @author jiucheng
* @描述:课程写评价页面
* @Copyright Copyright (c) 2018
* @Company 壹点灵
* @date 2019/7/2
*/
@Route(path = "/course/comment")
class CourseCommentActivity : BaseActivity() {
private var courseId: String? = null
companion object {
private const val COURSE_ID = "course_id"
fun startActivity(activity: Activity, courseId: String) {
var intent = Intent(activity, CourseCommentActivity::class.java)
intent.putExtra(COURSE_ID, courseId)
activity.startActivity(intent)
}
}
override fun layoutResId(): Int {
return R.layout.activity_course_commeny
}
override fun initDataAndEvent() {
courseId = intent.getStringExtra(COURSE_ID)
if (TextUtils.isEmpty(courseId)) {
ToastUtil.toastShort("参数错误,请重试")
return
}
iv_back.setOnClickListener {
finish()
}
tv_left_menu.setOnClickListener {
if (TextUtils.isEmpty(et_comment.text.toString())) {
ToastUtil.toastShort("请输入评论内容")
return@setOnClickListener
}
commitReply(et_comment.text.toString())
}
et_comment.addTextChangedListener(object : TextWatcher {
override fun afterTextChanged(s: Editable?) {
if (TextUtils.isEmpty(s)) {
tv_input_length.text = "0"
tv_input_length.setTextColor(resources.getColor(R.color.color_b3b3b3))
} else {
tv_input_length.text = s!!.length.toString()
tv_input_length.setTextColor(resources.getColor(R.color.color_242424))
}
}
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
}
})
}
//提交评论
private fun commitReply(content: String) {
showProgressDialog(null)
val cmd = Command.CourseCommitReply(courseId!!.toInt(), content)
RetrofitUtils.commitCourseReply(cmd)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ resp ->
dismissProgressDialog()
if (resp.code == 200) {
ToastUtil.toastShort(resp.msg)
val h5Params = H5Params(CourseConstants.COURSE_COMMENT_H5 + courseId, "全部评价")
NewH5Activity.start(this@CourseCommentActivity, h5Params)
this@CourseCommentActivity.finish()
} else {
ToastUtil.toastShort(resp.msg)
LogHelper.getInstance().writeLogSync("提交评论失败:" + resp.msg)
}
}, { t ->
dismissProgressDialog()
RetrofitUtils.handleError(this, t)
LogHelper.getInstance().writeLogSync("提交评论失败:" + t.message)
})
}
}
package com.yidianling.course.coursePlay
import android.annotation.SuppressLint
import android.text.TextUtils
import android.view.View
import android.widget.LinearLayout
import com.ydl.ydl_image.module.GlideApp
import com.yidianling.common.tools.ToastUtil
import com.yidianling.course.CourseConstants
import com.yidianling.course.R
import com.yidianling.ydlcommon.bean.CourseExtraBean
import com.yidianling.ydlcommon.h5.H5Params
import com.yidianling.ydlcommon.h5.NewH5Activity
import kotlinx.android.synthetic.main.item_course_play_head.view.*
/**
* 课程播放页面--recyclerView头view
* Created by harvie on 2017/6/26 0026.
*/
class CourseHeadView : LinearLayout {
//课程id
var courseId = ""
var activity: CoursePlayActivity? = null
constructor(context: CoursePlayActivity) : super(context) {
this.activity = context
View.inflate(context, R.layout.item_course_play_head, this)
initView()
}
fun initView() {
setCourseInfoClick()
}
//设置课程详情点击事件
private fun setCourseInfoClick() {
setOnClickListener {
if (TextUtils.isEmpty(courseId)) {
ToastUtil.toastShort("课程id错误")
} else {
activity!!.showVideoFloatView()
//跳转课程H5详情
NewH5Activity.start(activity, H5Params(CourseConstants.COURSE_DETAIL_H5 + courseId, null))
}
}
}
//设置数据
@SuppressLint("SetTextI18n")
fun setData(bean: CourseExtraBean) {
courseId = bean.id
GlideApp.with(context).load(bean.doctorHead).error(R.drawable.head_place_hold_pic).into(img_head)
if (TextUtils.isEmpty(bean.doctorName)) {
ll_info.visibility= View.GONE
}else{
ll_info.visibility= View.VISIBLE
}
text_user_name.text = bean.doctorName
text_user_des.text = bean.title
val types = when {
bean.mediaTypes == 1 -> "音频"
bean.mediaTypes == 2 -> "视频"
else -> "音频 视频"
}
tv_media_num.text = bean.serialsNumber.toString() + "节系列课 | $types"
}
}
\ No newline at end of file
package com.yidianling.course.coursePlay
import android.annotation.SuppressLint
import android.content.Intent
import android.content.res.Configuration
import android.graphics.Color
import android.os.Build
import android.os.Handler
import android.support.v7.widget.LinearLayoutManager
import android.support.v7.widget.OrientationHelper
import android.text.TextUtils
import android.view.View
import android.view.ViewGroup
import android.view.WindowManager
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.TextView
import com.alibaba.android.arouter.facade.annotation.Route
import com.bumptech.glide.Glide
import com.dou361.ijkplayer.widget.PlayStateParams
import com.dou361.ijkplayer.widget.PlayerView
import com.ydl.ydl_image.module.GlideApp
import com.ydl.ydl_pay.CommonPayDialog
import com.ydl.ydl_router.manager.YDLRouterManager
import com.yidianling.common.tools.RxImageTool
import com.yidianling.common.tools.RxNetTool
import com.yidianling.common.tools.ToastUtil
import com.yidianling.course.R
import com.yidianling.course.coursePlay.presenter.CoursePlayPresenter
import com.yidianling.ydlcommon.BuildConfig
import com.yidianling.ydlcommon.adapter.CommonRecyclerAdapter
import com.yidianling.ydlcommon.base.BaseActivity
import com.yidianling.ydlcommon.bean.CourseMediaBean
import com.yidianling.ydlcommon.bean.CourseMediaDetailBean
import com.yidianling.ydlcommon.data.ShareData
import com.yidianling.ydlcommon.data.YdlDataManager
import com.yidianling.ydlcommon.dialog.CommonDialog
import com.yidianling.ydlcommon.dialog.YDLShareDialog
import com.yidianling.ydlcommon.player.YDLMusicHelper
import com.yidianling.ydlcommon.player.util.UtilH
import com.yidianling.ydlcommon.router.IYDLRouterConstant
import com.yidianling.ydlcommon.router.YdlCommonRouterManager
import com.yidianling.ydlcommon.tool.StatusBarUtils
import com.yidianling.ydlcommon.utils.PlayerFloatHelper
import com.yidianling.ydlcommon.utils.ScreenUtil
import com.yidianling.ydlcommon.utils.UMEventUtils
import com.yidianling.ydlcommon.utils.Utils
import com.yidianling.ydlcommon.view.BaseViewHolder
import kotlinx.android.synthetic.main.activity_course_play.*
import org.json.JSONException
import org.json.JSONObject
import java.util.*
/**
* 课程播放页面
*/
@Route(path = "/course/play")
class CoursePlayActivity : BaseActivity() {
private val ROUTER_PARAMS = "routerParam"
/*******************播放器模块*******************/
//音视频模块
var play_view: PlayViewInterface? = null
//当前播放模式 0音频播放 1视频播放
var play_type = 0
/**********************中间内容模块************************/
var headview: CourseHeadView? = null
var adapter: CommonRecyclerAdapter<CourseMediaBean>? = null
//播放列表
var playList: ArrayList<CourseMediaBean> = ArrayList()
var presenter: CoursePlayPresenter? = null
var index = 0 //当前播放下标
//课程id
var course_id = 0
//是否全屏 0:否 1 全屏
var fullScreen = 0
var courPlayBean: CourseMediaDetailBean? = null
//外部选中要播放的音/视频文件地址
private var receiverPlayUrl: String? = ""
var from: Int = 0
private var handler = Handler()
//视频播放器view
var videoView: PlayerView? = null
//视频是否在播放
var isVideoPlay = false
//TODO 播放状态统一
var isShowAnim = true
//是否是悬浮窗进入
private var isFromFloatView = false
private var isCancelNetCheck = false
override fun layoutResId(): Int {
return R.layout.activity_course_play
}
override fun initDataAndEvent() {
//获取参数
getParam()
if (course_id == 0) {
ToastUtil.toastShort("参数错误")
finish()
}
presenter = CoursePlayPresenter(this)
initView()
initWindows()
initData()
nestedScrollView.scrollTo(0, 0)
}
fun initView() {
iv_back.setOnClickListener {
UMEventUtils.umEvent("返回点击", "返回", "返回")
onBackPressed()
}
iv_share.setOnClickListener {
UMEventUtils.umEvent("分享点击", "分享", "分享")
//分享
share(courPlayBean?.courseExtra?.shareData)
}
StatusBarUtils.setWindowStatusBarColor(mContext, R.color.transparent)
tv_write_comment.setOnClickListener {
if (!Utils.isFastClick()) {
showVideoFloatView()
CourseCommentActivity.startActivity(this@CoursePlayActivity, course_id.toString())
}
}
text_price?.setOnClickListener {
//参加课程
addCourseOrder()
}
recy_list?.isNestedScrollingEnabled = false
recy_list?.layoutManager = LinearLayoutManager(this, OrientationHelper.VERTICAL, false)
adapter = CommonRecyclerAdapter<CourseMediaBean>(recy_list, R.layout.dialog_course_playlist_item)
.setBindDataCallback(object : CommonRecyclerAdapter.BindDataCallback<CourseMediaBean> {
override fun bindDatabindData(holder: BaseViewHolder, bean: CourseMediaBean, position: Int) {
var gifView: ImageView = holder.getView(R.id.gifView)
var playView: ImageView = holder.getView(R.id.ic_play_view)
var bodyView: LinearLayout = holder.getView(R.id.lin_body)
if (index == position) {
gifView.visibility = View.VISIBLE
playView.visibility = View.GONE
bodyView.setBackgroundColor(this@CoursePlayActivity.resources.getColor(R.color.color_F8FCFF))
if (isShowAnim) {
Glide.with(this@CoursePlayActivity).asGif().load(R.drawable.music).into(gifView)
} else {
Glide.with(this@CoursePlayActivity).asBitmap().load(R.drawable.music).into(gifView)
}
holder.setTextColor(R.id.text_title, this@CoursePlayActivity.resources.getColor(R.color.google_green))
} else {
gifView.visibility = View.GONE
playView.visibility = View.VISIBLE
bodyView.setBackgroundColor(this@CoursePlayActivity.resources.getColor(R.color.white))
if (courPlayBean?.courseExtra?.isBuy!!) {
GlideApp.with(this@CoursePlayActivity).load(R.drawable.ico_kcml_play).into(playView)
} else {
if (bean.isDemo) {
GlideApp.with(this@CoursePlayActivity).load(R.drawable.ico_kcml_play).into(playView)
} else {
GlideApp.with(this@CoursePlayActivity).load(R.drawable.ico_kcml_lock).into(playView)
}
}
holder.setTextColor(R.id.text_title, this@CoursePlayActivity.resources.getColor(R.color.black_deep))
}
var test: TextView = holder.getView(R.id.text_test)
//试听标签
if (bean.isDemo) {
test.visibility = View.VISIBLE
} else {
test.visibility = View.GONE
}
holder.setText(R.id.text_title, bean.title)
holder.setOnClickListener(R.id.lin_body) {
if (position < 0) {
return@setOnClickListener
}
if (index == position) {
// if (play_type == 0) {//音频
// if (!YDLMusicHelper.isCoursePlaying()) {
// //暂停状态 开始播放
// YDLMusicHelper.start()
// }
// if (play_type == 1) {//视屏
// //暂停状态 开始播放
// videoView?.startPlay()
// }
// }
} else {
if (!bean.isDemo && !courPlayBean!!.courseExtra.isBuy) {
CommonDialog(this@CoursePlayActivity)
.setMessage("\n购买课程,获取完整课程内容\n")
.setLeftOnclick("放弃") {
}
.setRightClick("购买") {
//跳转支付页
addCourseOrder()
}
.setCancelAble(false)
.show()
return@setOnClickListener
}
UtilH.saveProgress(this@CoursePlayActivity, playList[index].url, 0)
if (play_type == 1) {
//暂停状态 开始播放
(play_view as CoursePlayItemViewVideo)?.play(position)
}
if (play_type == 0) {
if (RxNetTool.isWifi(this@CoursePlayActivity)) {
(play_view as CoursePlayItemViewAudio).playView!!.play(position)
} else {
if ((play_view as CoursePlayItemViewAudio).hasEnsureNetStatus) {
(play_view as CoursePlayItemViewAudio).playView!!.play(position)
} else {
(play_view as CoursePlayItemViewAudio).setData(position, playList, courPlayBean!!.courseExtra, from)
}
}
}
index = position
adapter?.notifyDataSetChanged()
}
}
}
})
headview = CourseHeadView(this)
//添加头部和底部view
adapter!!.addHeadView(headview)
recy_list.adapter = adapter
}
override fun onNewIntent(intent: Intent?) {
var new_course_id = 0
if (intent != null) {
new_course_id = intent.getIntExtra("course_id", 0)
}
if (new_course_id == 0) {
ToastUtil.toastShort("参数错误")
finish()
}
if (new_course_id != course_id) {
course_id = new_course_id
initData()
}
}
/**
* 获取路由传递的参数
*/
private fun getParam() {
if (null == intent) {
return
}
if (intent.hasExtra(ROUTER_PARAMS)){
//路由传递的入参
val json = intent.getStringExtra(ROUTER_PARAMS)
try {
val jsonObject = JSONObject(json)
//课程ID
course_id = jsonObject.getInt(IYDLRouterConstant.EXTRA_ID)
} catch (e: JSONException) {
e.printStackTrace()
}
return
}
//正常跳转所传参数
course_id = intent.getIntExtra("course_id", 0)
//mediaType是服务端新定义的媒体类型,1.音频 2.视频 ,与本地定义类型不同,先不改本地定义数据类型
var mediaType = intent.getStringExtra("mediaType")
if (TextUtils.equals(mediaType, "1")) {
play_type = 0
} else if (TextUtils.equals(mediaType, "2")) {
play_type = 1
}
fullScreen = intent.getIntExtra("fullScreen", 0)
receiverPlayUrl = intent.getStringExtra("coursePlayUrl")
isFromFloatView = intent.getBooleanExtra("isFromFloatView", false)
if (!TextUtils.isEmpty(receiverPlayUrl) && isFromFloatView) {
isCancelNetCheck = true
}
try {
if (YDLMusicHelper.isCoursePlaying() && TextUtils.isEmpty(receiverPlayUrl)) {
receiverPlayUrl = YDLMusicHelper.getCurrentData()?.url
}
} catch (e: Exception) {
}
from = intent.getIntExtra("from", 0)
}
private fun initWindows() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
val window = window
//获取状态栏高度
var statusBarheight: Int = ScreenUtil.getStatusBarHeight(mContext)
//设置边距
setMargins(title_bar_layout, RxImageTool.dp2px(15f), statusBarheight, RxImageTool.dp2px(15f), 0)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
window.statusBarColor = Color.TRANSPARENT
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LAYOUT_STABLE
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
} else {
window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
}
}
}
private fun setMargins(v: View?, l: Int, t: Int, r: Int, b: Int) {
if (v != null) {
if (v.layoutParams is ViewGroup.MarginLayoutParams) {
val p = v.layoutParams as ViewGroup.MarginLayoutParams
p.setMargins(l, t, r, b)
v.requestLayout()
}
}
}
private fun initData() {
//获取数据
presenter?.getInitData(course_id)
}
//跟新view显示
@SuppressLint("SetTextI18n")
fun updateView(bean: CourseMediaDetailBean) {
courPlayBean = bean
playList.clear()
setPlayList(bean)
if (!TextUtils.isEmpty(receiverPlayUrl)) {
for ((index, element) in playList.withIndex()) {
if (TextUtils.equals(receiverPlayUrl, element.url) || TextUtils.equals(receiverPlayUrl!!.replace("http", "https"), element.url)) {
this@CoursePlayActivity.index = index
}
}
}
play_type = if (playList[index].mediaType == 1) {
0
} else {
1
}
try {
if (play_type == 1) {
//视频播放销毁音频服务
YDLMusicHelper.stop()
}
if (YDLMusicHelper.isConfidePlaying() || YDLMusicHelper.isFMPlaying()) {
YDLMusicHelper.stop()
}
} catch (e: Exception) {
e.printStackTrace()
}
if (play_type == 1) {//视频
play_view = CoursePlayItemViewVideo.create(this, play_type)
(play_view as CoursePlayItemViewVideo).hasEnsureNetStatus = isCancelNetCheck
frame_play.addView(play_view as CoursePlayItemViewVideo)
} else {//音频
play_view = CoursePlayItemViewAudio.create(this, play_type)
(play_view as CoursePlayItemViewAudio).hasEnsureNetStatus = isCancelNetCheck
frame_play.addView(play_view as CoursePlayItemViewAudio)
}
if (play_type == 0) {
handler.postDelayed({
play_view?.setData(index, playList, bean.courseExtra, from)
}, 500)
} else {
play_view?.setData(index, playList, bean.courseExtra, from)
}
if (videoView != null && play_type == 1 && fullScreen == 1) {
videoView!!.toggleFullScreen()
videoView!!.setNetWorkTypeTie(false)
videoView!!.startPlay()
}
//专家简介部分
headview?.setData(bean.courseExtra)
tv_title_full.text = bean.courseExtra.title
text_price.text = "立即购买 ¥" + bean.courseExtra.applyFee
if (bean.courseExtra.isBuy) {
//已报名
text_price.visibility = View.GONE
tv_write_comment.visibility = View.VISIBLE
//评论数量是大于 1,表示已经已经评论过,不再显示底部的评论区域
if (bean.courseExtra.userCommentNum >= 1) {
rl_write_bottom.visibility = View.GONE
}
} else {
//未报名
text_price.visibility = View.VISIBLE
tv_write_comment.visibility = View.GONE
}
}
//设置播放列表数据
private fun setPlayList(bean: CourseMediaDetailBean) {
if (bean.voiceSample.courseMedia != null && bean.voiceSample.courseMedia.isNotEmpty()) {
for (voiceSampleData in bean.voiceSample.courseMedia) {
voiceSampleData.isDemo = true
playList.add(voiceSampleData)
}
}
if (bean.voiceWhole.courseMedia != null && bean.voiceWhole.courseMedia.isNotEmpty()) {
for (voiceCourseData in bean.voiceWhole.courseMedia) {
playList.add(voiceCourseData)
}
}
adapter!!.update(playList)
}
fun updatePlayingListStatus(index: Int) {
if (index < playList.size && this.index != index) {
this.index = index
adapter?.notifyDataSetChanged()
}
}
fun showPlayAnim(isShowAnim: Boolean) {
this.isShowAnim = isShowAnim
if (adapter != null) {
adapter?.notifyDataSetChanged()
}
}
fun showLoadingDialog() {
showProgressDialog(null)
}
fun dismissLoadingDialog() {
dismissProgressDialog()
}
//参加课程
fun addCourseOrder() {
if (course_id == 0) {
ToastUtil.toastShort("请退出页面重试")
return
}
val userInfo = YdlCommonRouterManager.getYdlCommonRoute().getUserInfo()
if (userInfo == null || TextUtils.isEmpty(userInfo.userId)) {
YDLRouterManager.router(IYDLRouterConstant.ROUTER_MINE_LOGIN)
return
}
val build = CommonPayDialog.Build(mContext)
.setCourseId(course_id.toString())
.setToken(userInfo.token)
.setUid(userInfo.userId)
.setFfrom(YdlDataManager.getRam().getChannelName())
.setListener(object : CommonPayDialog.OnPayResultListener {
override fun onSuccesed() {
//刷新界面
initData()
}
override fun onFailed() {
}
})
.setIsTestEnvironment(BuildConfig.DEBUG)
build.build().show()
}
/**
* 分享
*/
private fun share(share: ShareData?) {
if (share == null) {
ToastUtil.toastShort("缺少参数")
return
}
val dialog = YDLShareDialog.style1(this, share.title, share.share_url, share.desc, share.cover, "", "")
dialog.setCallBack(object : YDLShareDialog.ICallBack {
override fun callBack(type: Int) {
if (1 == type) {
if (!YdlCommonRouterManager.getYdlCommonRoute().isLogin()) {
YdlCommonRouterManager.getYdlCommonRoute().startChooseLoginWay(this@CoursePlayActivity)
} else {
//分享到心事动态
toTrend(share)
}
}
}
})
dialog.show(fragmentManager, "lose")
}
private fun toTrend(share: ShareData) {
var url = if (TextUtils.isEmpty(share.url)) share.share_url else share.url
YdlCommonRouterManager.getYdlCommonRoute().publishArticleToTrend(this@CoursePlayActivity, url!!, share.cover!!, share.title!!)
}
override fun onPause() {
super.onPause()
videoView?.onPause()
play_view?.onPause()
}
override fun onResume() {
super.onResume()
play_view?.onResume()
if (PlayerFloatHelper.isShow(this)) {
PlayerFloatHelper.removeView(this)
}
}
override fun onConfigurationChanged(newConfig: Configuration) {
super.onConfigurationChanged(newConfig)
if (play_type == 1) {
if (newConfig.screenHeightDp > newConfig.screenWidthDp) {
//显示底部评论按钮
rl_write_bottom.visibility = View.VISIBLE
tv_title_full.visibility = View.GONE
nestedScrollView.isVerticalFadingEdgeEnabled = true
nestedScrollView.isVerticalScrollBarEnabled = true
recy_list.visibility = View.VISIBLE
videoView?.hideBack(true)
} else {
rl_write_bottom.visibility = View.GONE
tv_title_full.visibility = View.VISIBLE
nestedScrollView.isVerticalFadingEdgeEnabled = false
nestedScrollView.isVerticalScrollBarEnabled = false
recy_list.visibility = View.GONE
videoView?.hideBack(false)
}
videoView?.onConfigurationChanged(newConfig)
handler.postDelayed({
if (newConfig.screenHeightDp > newConfig.screenWidthDp) {
videoView?.fullScreenView!!.setImageResource(R.drawable.ico_play_float_full)
} else {
videoView?.fullScreenView!!.setImageResource(R.drawable.ico_play_minify)
}
}, 300)
}
}
override fun onBackPressed() {
if (showVideoFloatView()) {
super.onBackPressed()
}
}
fun showVideoFloatView(): Boolean {
if (play_type == 0) {
if (YDLMusicHelper.isCoursePlaying()) {
YDLMusicHelper.cover = courPlayBean?.courseExtra?.pic
YDLMusicHelper.name = courPlayBean?.courseExtra?.doctorName
}
} else {
if (videoView?.onBackPressed() == true) {
return false
}
if (isVideoPlay) {
var status = Utils.getValue(videoView, "status")
//视频课程正在播放中
if (status == PlayStateParams.STATE_PLAYING) {
YDLMusicHelper.title = courPlayBean?.courseExtra?.title
YDLMusicHelper.cover = courPlayBean?.courseExtra?.pic
YDLMusicHelper.name = courPlayBean?.courseExtra?.doctorName
YDLMusicHelper.isVideoPlaying = true
YDLMusicHelper.playType = 1
YDLMusicHelper.courseVideoUlr = (play_view as CoursePlayItemViewVideo).videoUrl
YDLMusicHelper.course_id = courPlayBean?.courseExtra?.id!!.toInt()
PlayerFloatHelper.show(this)
}
}
}
return true
}
override fun onDestroy() {
videoView?.onDestroy()
play_view?.onDestroy()
play_view = null
super.onDestroy()
}
}
package com.yidianling.course.coursePlay
import android.annotation.SuppressLint
import android.text.TextUtils
import android.view.ViewGroup
import android.widget.RelativeLayout
import com.yidianling.common.tools.RxDeviceTool
import com.yidianling.common.tools.RxNetTool
import com.yidianling.ydlcommon.bean.CourseExtraBean
import com.yidianling.ydlcommon.bean.CourseMediaBean
import com.yidianling.ydlcommon.dialog.CommonDialog
import com.yidianling.ydlcommon.player.MusicInfoBean
import com.yidianling.ydlcommon.player.YDLMusicHelper
import com.yidianling.ydlcommon.player.player.HPlayStatusListener
import com.yidianling.ydlcommon.player.view.HPlayView
/**
* 课程播放器的item
* Created by harvie on 2017/6/26 0026.
*/
class CoursePlayItemViewAudio : RelativeLayout, PlayViewInterface {
var activity: CoursePlayActivity? = null
private var courseExtra: CourseExtraBean? = null
var playView: HPlayView? = null
//播放列表
var playList: ArrayList<CourseMediaBean> = ArrayList()
var hasEnsureNetStatus = false
var currentIndex = 0
companion object {
fun create(activity: CoursePlayActivity, playType: Int): PlayViewInterface {
return CoursePlayItemViewAudio(activity)
}
}
@SuppressLint("InvalidWakeLockTag")
private constructor(context: CoursePlayActivity) : super(context) {
playView = HPlayView(context)
var width = RxDeviceTool.getScreenWidth(context)
var heigth = width * 9 / 16
var layoutP = ViewGroup.LayoutParams(LayoutParams.MATCH_PARENT, heigth)
playView?.layoutParams = layoutP
this.addView(playView)
activity = context
initView()
}
fun initView() {
setListener()
}
override fun onResume() {
}
override fun onPause() {
}
override fun onNewIntent() {
}
//设置监听事件
fun setListener() {
playView?.listener = object : HPlayStatusListener {
override fun isCanPlay(data: MusicInfoBean?): Boolean {
var canPlay = false
//判断当前课程是否试听
if (data?.isTestPlay == true) {
canPlay = true
} else {
//非试听
if (courseExtra!!.isBuy) {
//已购买
canPlay = true
} else {
//未购买,判断是否是试听课程
//即未购买,也不是试听,弹窗提示
if (activity == null) return false
CommonDialog(activity)
.setMessage("\n购买课程,获取完整课程内容\n")
.setLeftOnclick("放弃") {
}
.setRightClick("购买") {
//跳转支付页
activity?.addCourseOrder()
}
.setCancelAble(false)
.show()
}
}
return canPlay
}
override fun onPrepared(data: MusicInfoBean?, index: Int) {
//更新播放列表的状态
activity!!.updatePlayingListStatus(index)
}
}
}
/**
* 设置显示数据
*/
override fun setData(index: Int, list: ArrayList<CourseMediaBean>, courseExtra: CourseExtraBean, from: Int) {
if (list.isEmpty()) return
playList.clear()
playList.addAll(list)
this.courseExtra = courseExtra
currentIndex = index
YDLMusicHelper.course_id = courseExtra.id.toInt()
if (courseExtra.isBuy) {
playView?.setAutoNext(true)
} else {
//未购买,取消自动播放
playView?.setAutoNext(false)
}
playView?.setImageBackground(courseExtra.pic)
playView!!.setData(stringToMusicPlayerList(playList))
if (playView?.control?.isPlaying() == true) {
hasEnsureNetStatus = true
}
if (RxNetTool.isWifi(activity!!)) {
if (playView?.control?.isPlaying() == true && (from == 1 || from == 2)) {
if (TextUtils.equals(playView?.getCurrentUrl(), list[currentIndex].url)) {
playView?.updateView(currentIndex)
} else {
playView?.play(currentIndex)
}
} else {
playView?.play(index)
}
} else {
if (hasEnsureNetStatus) {
if (playView?.control?.isPlaying() == true && (from == 1 || from == 2)) {
if (TextUtils.equals(playView?.getCurrentUrl(), list[currentIndex].url)) {
playView?.updateView(currentIndex)
} else {
playView?.play(currentIndex)
}
} else {
playView?.play(currentIndex)
}
} else {
playView?.showNetNotice {
hasEnsureNetStatus = true
if (playView?.control?.isPlaying() == true && (from == 1 || from == 2)) {
if (TextUtils.equals(playView?.getCurrentUrl(), list[currentIndex].url)) {
playView?.updateView(currentIndex)
} else {
playView?.play(currentIndex)
}
} else {
playView?.play(currentIndex)
}
}
}
}
}
//将列表转为播放器可用列表
private fun stringToMusicPlayerList(list: List<CourseMediaBean>): ArrayList<MusicInfoBean> {
var nlist = ArrayList<MusicInfoBean>()
try {
for (i in list.indices) {
var be = MusicInfoBean()
be.url = list[i].url
be.pic = courseExtra!!.pic
be.isTestPlay = !courseExtra!!.isBuy
be.title = list[i].title
nlist.add(be)
}
} catch (e: Exception) {
e.printStackTrace()
}
return nlist
}
override fun onDestroy() {
//释放播放器
if (playView?.control?.isPlaying() != true) {
playView?.onDestroy()
playView = null
YDLMusicHelper.stop()
} else {
playView?.onDestroy()
playView = null
}
}
}
\ No newline at end of file
package com.yidianling.course.coursePlay
import android.annotation.SuppressLint
import android.content.Context
import android.os.Handler
import android.os.PowerManager
import android.view.View
import android.widget.RelativeLayout
import com.dou361.ijkplayer.widget.PlayStateParams
import com.dou361.ijkplayer.widget.PlayerView
import com.ydl.ydl_image.module.GlideApp
import com.yidianling.course.R
import com.yidianling.ydlcommon.bean.CourseExtraBean
import com.yidianling.ydlcommon.bean.CourseMediaBean
import com.yidianling.ydlcommon.dialog.CommonDialog
import com.yidianling.ydlcommon.player.YDLMusicHelper
import com.yidianling.ydlcommon.player.util.UtilH
import tv.danmaku.ijk.media.player.IMediaPlayer
import java.text.SimpleDateFormat
import java.util.*
/**
* 课程播放器的item
* Created by harvie on 2017/6/26 0026.
*/
class CoursePlayItemViewVideo : RelativeLayout, PlayViewInterface {
//播放列表
private var playList: ArrayList<CourseMediaBean> = ArrayList()
private var courseExtra: CourseExtraBean? = null
var activity: CoursePlayActivity? = null
var videoUrl: String? = null
//播放模式
var playMoudle = 0 //默认为0 音频播放 1视频播放
var timer = Timer()
var index = 0
private var isVideoPlaying = true
private var mHandler = Handler()
var hasEnsureNetStatus = false
private val formatter = SimpleDateFormat("mm:ss", Locale.getDefault())
private var wakeLock: PowerManager.WakeLock? = null
companion object {
fun create(activity: CoursePlayActivity, playType: Int): CoursePlayItemViewVideo {
return CoursePlayItemViewVideo(activity, playType)
}
}
@SuppressLint("InvalidWakeLockTag")
private constructor(context: CoursePlayActivity, playMoudle: Int) : super(context) {
this.playMoudle = playMoudle
View.inflate(context, R.layout.view_course_play_item, this)
activity = context
initView()
wakeLock = (activity!!.getSystemService(Context.POWER_SERVICE) as PowerManager)
.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK or PowerManager.ON_AFTER_RELEASE, "CoursePlayItemViewVideo")
}
override fun onNewIntent() {
}
fun initView() {
findViewById<View>(R.id.simple_player_settings_container).visibility = View.GONE
findViewById<View>(R.id.app_video_center_box).visibility = View.GONE //
setListener()
//开启定时器实时记录播放位置
startTimer()
}
private fun startTimer() {
timer?.schedule(object : TimerTask() {
override fun run() {
if (isVideoPlaying) {
var time = activity?.videoView?.currentPosition ?: 0
if (time < 3000) return
UtilH.saveProgress(context, videoUrl, time)
}
}
}, 1000, 1000)
}
//设置监听事件
private fun setListener() {
}
private fun playNext() {
// var size: Int = playList.size
// if ((size - 1) > bean?.attachmentIndex ?: 0) {
// //这里请勿给index先赋值,判断可播放后会自动赋值
// val index = bean?.attachmentIndex ?: 0
// play(index!! + 1, true)
// UtilH.saveProgress(activity, playList[index].playUrl, 0);
// }
}
override fun onResume() {
if (wakeLock != null) {
wakeLock!!.acquire()
}
activity?.videoView?.onResume()
var hisTime1 = UtilH.getProgress(context, videoUrl)
activity?.videoView?.seekTo(hisTime1)
}
override fun onPause() {
if (wakeLock != null) {
if (wakeLock!!.isHeld) {
wakeLock!!.release()
}
}
}
/**
* 播放音频
* index 播放下标
*/
fun play(index: Int) {
this.index = index
var canPlay = false
//判断当前课程是否试听
if (playList[index].isDemo) {
canPlay = true
} else {
//非试听
if (courseExtra!!.isBuy) {
//已购买
canPlay = true
} else {
//未购买,判断是否是试听课程
//即未购买,也不是试听,弹窗提示
CommonDialog(activity)
.setMessage("\n购买课程,获取完整课程内容\n")
.setLeftOnclick("放弃") {
}
.setRightClick("购买") {
//跳转支付页
activity?.addCourseOrder()
}
.setCancelAble(false)
.show()
}
}
if (canPlay) {
YDLMusicHelper.playingType = YDLMusicHelper.PLAY_TYPE_COURSE
var url = playList[index].url
url = url.replace("https", "http")
videoUrl = url
var hisTime = UtilH.getProgress(context, url)
try {
activity?.videoView = PlayerView(activity)
.setScaleType(PlayStateParams.fitparent)
.hideMenu(true)
.hideRotation(true)
.setNetWorkTypeTie(!hasEnsureNetStatus)
.hideBack(true)
.hideSteam(true)
.setAutoReConnect(true, 3)
.forbidTouch(false)
.setOnInfoListener(object : IMediaPlayer.OnInfoListener {
override fun onInfo(mp: IMediaPlayer, what: Int, extra: Int): Boolean {
if (what == PlayStateParams.STATE_PAUSED) {
this@CoursePlayItemViewVideo.findViewById<View>(R.id.rl_play_pause_layout).visibility = View.VISIBLE
} else {
this@CoursePlayItemViewVideo.findViewById<View>(R.id.rl_play_pause_layout).visibility = View.GONE
}
if (what == PlayStateParams.STATE_PLAYING) {
this@CoursePlayItemViewVideo.findViewById<View>(R.id.app_video_loading).visibility = View.GONE
}
if (what == PlayStateParams.MEDIA_INFO_BUFFERING_END
|| what == PlayStateParams.MEDIA_INFO_AUDIO_RENDERING_START
|| what == PlayStateParams.MEDIA_INFO_VIDEO_RENDERING_START
|| what == PlayStateParams.STATE_PLAYING
) {
activity?.isVideoPlay = true
this@CoursePlayItemViewVideo.findViewById<View>(R.id.ll_bg).visibility = View.GONE
} else {
mHandler.postDelayed({
this@CoursePlayItemViewVideo.findViewById<View>(R.id.ll_bg).visibility = View.VISIBLE
}, 550)
}
if (what == PlayStateParams.STATE_COMPLETED) {
isVideoPlaying = false
UtilH.saveProgress(this@CoursePlayItemViewVideo.activity, videoUrl, 0)
if (playList.size - 1 > this@CoursePlayItemViewVideo.index) {
//播放下一曲
play(this@CoursePlayItemViewVideo.index + 1)
activity!!.updatePlayingListStatus(this@CoursePlayItemViewVideo.index)
}
} else {
isVideoPlaying = true
}
return true
}
})
.showThumbnail { ivThumbnail ->
run {
ivThumbnail.alpha = 0.5f
GlideApp.with(context)
.load(courseExtra!!.pic)
.into(ivThumbnail)
}
}
.setPlaySource(url)
.startPlay()
.seekTo(hisTime)
val layout = activity?.window?.attributes
layout?.screenBrightness = -1f
activity?.window?.attributes = layout
} catch (e: Exception) {
e.printStackTrace()
}
}
}
/**
* 设置显示数据
*/
override fun setData(index: Int, list: ArrayList<CourseMediaBean>, courseExtra: CourseExtraBean, from: Int) {
if (list.isEmpty()) return
playList.clear()
playList.addAll(list)
this.courseExtra = courseExtra
play(index)
}
override fun onDestroy() {
timer.cancel()
}
}
\ No newline at end of file
package com.yidianling.course.coursePlay
import android.support.v7.widget.LinearLayoutManager
import android.support.v7.widget.RecyclerView
import com.cxzapp.yidianling.common.view.FootViewLoadMore
import com.ydl.ydl_image.module.GlideApp
import com.yidianling.common.tools.LogUtil
import com.yidianling.common.tools.ToastUtil
import com.yidianling.course.R
import com.yidianling.course.coursePlay.common.net.Command
import com.yidianling.course.coursePlay.common.net.RetrofitUtils
import com.yidianling.course.coursePlay.moudle.CoursePlayBean
import com.yidianling.ydlcommon.adapter.CommonRecyclerAdapter
import com.yidianling.ydlcommon.base.BaseActivity
import com.yidianling.ydlcommon.view.BaseViewHolder
import com.yidianling.ydlcommon.view.CircleImageView
import com.yidianling.ydlcommon.view.TitleBar
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
/**
* 课程课后笔记列表
*
*/
class CourseReplyListActivity : BaseActivity() {
override fun layoutResId(): Int {
return R.layout.activity_course_reply_list
}
override fun initDataAndEvent() {
course_id = intent.getIntExtra("course_id", 0)
initView()
getListData(false)
}
var title_bar: TitleBar? = null
var recycler_list: RecyclerView? = null
var footView: FootViewLoadMore? = null
var adapter: CommonRecyclerAdapter<CoursePlayBean.Comments>? = null
var page = 1 //分页
//课程id
var course_id = 0
fun initView() {
title_bar = findViewById<TitleBar>(R.id.title_bar)
recycler_list = findViewById<RecyclerView>(R.id.recycler_list)
recycler_list?.layoutManager = LinearLayoutManager(mContext, LinearLayoutManager.VERTICAL, false)
adapter = CommonRecyclerAdapter<CoursePlayBean.Comments>(recycler_list, R.layout.item_course_play_recylist)
.setBindDataCallback(object : CommonRecyclerAdapter.BindDataCallback<CoursePlayBean.Comments> {
override fun bindDatabindData(holder: BaseViewHolder, t: CoursePlayBean.Comments, position: Int) {
//绑定数据
var img: CircleImageView = holder.getView(R.id.img_head)
GlideApp.with(applicationContext).load(t.head).into(img)
holder.setText(R.id.text_name, t.name)
holder.setText(R.id.text_time, t.create_time)
holder.setText(R.id.text_des, t.content)
}
})
.setOnLoadMoreListener(object : CommonRecyclerAdapter.OnLoadMoreLIstener {
override fun onLoadMore() {
getListData(true)
LogUtil.e("---------------------------------------")
}
})
footView = FootViewLoadMore(mContext)
adapter?.addFootView(footView)
recycler_list?.adapter = adapter
}
//获取列表数据
fun getListData(isLoadMore: Boolean) {
if (isLoadMore) {
page++
} else {
page = 1
}
if (isLoadMore) {
footView?.onLoading()
} else {
showProgressDialog(null)
}
val cmd = Command.CourseReplyList(course_id, page)
RetrofitUtils.courseReplyList(cmd)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ resp ->
if (!isLoadMore) {
dismissProgressDialog()
}
if (resp.code == 0) {
//跟新view显示
updateView(isLoadMore, resp.data as List<CoursePlayBean.Comments>)
} else {
footView?.onError()
ToastUtil.toastShort(resp.msg)
}
}, {
throwable->
footView?.onError()
if (!isLoadMore) {
dismissProgressDialog()
}
RetrofitUtils.handleError(mContext, throwable)
})
}
//跟新视图
fun updateView(isLoadMore: Boolean, list: List<CoursePlayBean.Comments>) {
if (list == null) return
if (list.size == 0) {
footView?.onFinish()
return
}
if (isLoadMore) {
adapter?.addDatas(list)
} else {
adapter?.update(list)
}
}
}
package com.yidianling.course.coursePlay
import com.yidianling.ydlcommon.bean.CourseExtraBean
import com.yidianling.ydlcommon.bean.CourseMediaBean
import java.util.*
/**
* 音视频播放器view基类接口
* Created by hgw on 2018/4/3.
*/
interface PlayViewInterface {
fun onPause()
fun onResume()
fun onDestroy()
//from 1表示通知栏进来,2表示悬浮按钮进来 index:播放下标
fun setData(index: Int, list: ArrayList<CourseMediaBean>, courseExtra: CourseExtraBean, from: Int)
fun onNewIntent()
}
\ No newline at end of file
package com.yidianling.course.coursePlay.common.net;
import com.yidianling.course.CourseConstants;
import com.yidianling.ydlcommon.http.BaseCommand;
import com.yidianling.ydlcommon.router.YdlCommonOut;
/**
* Created by Jim on 2018/2/26 0026.
*/
public class Command {
//获取课程播放页 初始化数据
public static class GetCoursePlayData extends BaseCommand {
public int course_id;
public int type;
public GetCoursePlayData(int course_id, int type) {
this.course_id = course_id;
this.type = type;
}
}
//参加课程
public static class CourseAddOrder extends BaseCommand {
public int course_id;
public String from;
public CourseAddOrder(int course_id) {
this.course_id = course_id;
this.from = YdlCommonOut.Companion.getChannelName();
}
}
//课程提交回复
public static class CourseCommitReply extends BaseCommand {
public int courseId;
public String content;//评论内容
public CourseCommitReply(int course_id, String content) {
this.courseId = course_id;
this.content = content;
}
}
//课程播放页--点赞
public static class CoursePlayZan extends BaseCommand {
public int course_id;
public CoursePlayZan(int course_id) {
this.course_id = course_id;
}
}
//课程课后笔记列表
public static class CourseReplyList extends BaseCommand {
public int course_id;
public int page;
public CourseReplyList(int course_id, int page) {
this.page = page;
this.course_id = course_id;
}
}
//获取课程列表
public static class GetCourse extends BaseCommand {
public int page;
public int type;
public int child_type;
public GetCourse(int page, int type) {
this.page = page;
this.type = type;
}
public GetCourse(int page, int type,int child_type) {
this.page = page;
this.type = type;
this.child_type=child_type;
}
public String getUrl() {
return CourseConstants.ALL_COURSE;
}
}
//获取课程专题
public static class CourseSpecial extends BaseCommand {
public int special_id;
public CourseSpecial(int special_id) {
this.special_id = special_id;
}
}
}
package com.yidianling.course.coursePlay.common.net;
import com.yidianling.course.bean.CourseCouponBean;
import com.yidianling.course.bean.PostersShareBean;
import com.yidianling.course.courseNew.home.ResultBean;
import com.yidianling.course.coursePlay.moudle.Course;
import com.yidianling.course.coursePlay.moudle.CourseAddOrderBean;
import com.yidianling.course.coursePlay.moudle.CourseListDataBean;
import com.yidianling.course.coursePlay.moudle.CoursePlayBean;
import com.yidianling.course.model.CourseCategoryBean;
import com.yidianling.course.model.TopicCourseBean;
import com.yidianling.ydlcommon.http.BaseAPIResponse;
import com.yidianling.ydlcommon.http.BaseResponse;
import java.util.List;
import java.util.Map;
import io.reactivex.Observable;
import okhttp3.RequestBody;
import retrofit2.http.Body;
import retrofit2.http.FieldMap;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.GET;
import retrofit2.http.POST;
import retrofit2.http.Query;
import retrofit2.http.Url;
/**
* Created by Jim on 2018/2/26 0026.
*/
public interface NetApiStore {
//获取课程列表
@retrofit2.http.Headers("Content-Type:application/json")
@GET()
Observable<BaseAPIResponse<CourseListDataBean>> getCourseList(@Url String url);
//获取课程列表
@FormUrlEncoded
@POST("course/list")
Observable<BaseResponse<List<Course>>> getPhpCourseList(@FieldMap Map<String, String> params);
// //获取课程播放页 初始化数据
// @FormUrlEncoded
// @POST("course/play")
// Observable<BaseResponse<CoursePlayBean>> getCoursePlayData(@FieldMap Map<String, String> params);
//课程课后笔记列表
@FormUrlEncoded
@POST("course/comments")
Observable<BaseResponse<List<CoursePlayBean.Comments>>> courseReplyList(@FieldMap Map<String, String> params);
//课程提交回复
@FormUrlEncoded
@POST("auth/course/comments/add")
Observable<BaseResponse<Object>> commitCourseReply(@FieldMap Map<String, String> params);
//课程播放页--点赞
@FormUrlEncoded
@POST("course/zan")
Observable<BaseResponse<Object>> coursePlayZan(@FieldMap Map<String, String> params);
//参加课程
@FormUrlEncoded
@POST("course/add-order")
Observable<BaseResponse<CourseAddOrderBean>> addCourseOrder(@FieldMap Map<String, String> params);
//首页课程
@GET("auth/course/home")
Observable<BaseAPIResponse<List<ResultBean>>> getCourseHomePageDatas();
//获取课程海报分享数据
@GET("auth/course/posters/share")
Observable<BaseResponse<PostersShareBean>> getPosterData(@Query("id") String courseId);
//首页分类
@FormUrlEncoded
@POST("course/cats")
Observable<BaseResponse<List<CourseCategoryBean>>> getCourseCats(@FieldMap Map<String, String> params);
//课程筛选分类
@GET("auth/course/search/newsample")
Observable<BaseAPIResponse<CourseCategoryBean>> getCourseListCategory();
// //首页分类
// @FormUrlEncoded
// @POST("course/course-special")
// Observable<BaseResponse<TopicCourseBean>> getCourseTopic(@FieldMap Map<String, String> params);
//课程专题列表接口
@GET("auth/course/new/listCoursesBySpecialId")
Observable<BaseAPIResponse<TopicCourseBean>> getCourseSpecial(@Query("specialId") String uid);
/**
* 获取可以领取的优惠券
*
* @param uid uid
* @param services 适用服务 1预约咨询 2电话倾诉 3课程(用户课程 专家课程) 5测评
* @param receiveType 领取条件方式 1前台领取 2链接领取
* @param applyEnds 适用终端 1PC官网 2wap站点 3用户app 4好杮app 5专家app
* @return
*/
@GET("marketing/coupon/new/available")
Observable<BaseResponse<List<CourseCouponBean>>> getCourseCoupons(@Query("uid") String uid,
@Query("services") String services,
@Query("receiveType") String receiveType,
@Query("applyEnds") String applyEnds);
//领取优惠券
@POST("marketing/coupon/new/receives")
Observable<BaseResponse<List<String>>> receiveCoupon(@Body RequestBody body);
}
package com.yidianling.course.coursePlay.common.net;
import android.content.Context;
import com.yidianling.course.bean.CourseCouponBean;
import com.yidianling.course.bean.PostersShareBean;
import com.yidianling.course.courseNew.home.ResultBean;
import com.yidianling.course.coursePlay.moudle.Course;
import com.yidianling.course.coursePlay.moudle.CourseAddOrderBean;
import com.yidianling.course.coursePlay.moudle.CoursePlayBean;
import com.yidianling.course.model.CourseCategoryBean;
import com.yidianling.course.model.TopicCourseBean;
import com.yidianling.ydlcommon.http.BaseAPIResponse;
import com.yidianling.ydlcommon.http.BaseCommand;
import com.yidianling.ydlcommon.http.BaseResponse;
import com.yidianling.ydlcommon.http.FormatText;
import com.yidianling.ydlcommon.http.YdlRetrofitUtils;
import java.util.List;
import io.reactivex.Observable;
import okhttp3.MediaType;
import okhttp3.RequestBody;
import retrofit2.Retrofit;
import static com.yidianling.ydlcommon.http.YdlRetrofitUtils.getMaps;
import static com.yidianling.ydlcommon.http.YdlRetrofitUtils.getPostList;
/**
* Created by Jim on 2018/2/26 0026.
*/
public class RetrofitUtils {
public static void handleError(Context context, Throwable e) {
YdlRetrofitUtils.handleError(context, e);
}
public static Retrofit getRxRetrofit() {
return YdlRetrofitUtils.getRxRetrofit();
}
//课程提交回复
public static Observable<BaseResponse<Object>> commitCourseReply(Command.CourseCommitReply cmd) {
List<FormatText> list = getPostList(cmd);
return YdlRetrofitUtils.getRxRetrofit().newBuilder().baseUrl(YdlRetrofitUtils.SERVER_API_JAVA_URL).build().create(NetApiStore.class).commitCourseReply(getMaps(list));
}
//获取课程海报分享数据
public static Observable<BaseResponse<PostersShareBean>> getPosterData(String courseId) {
return YdlRetrofitUtils.getRxRetrofit().newBuilder().baseUrl(YdlRetrofitUtils.SERVER_API_JAVA_URL).build().create(NetApiStore.class).getPosterData(courseId);
}
//课程播放页--点赞
public static Observable<BaseResponse<Object>> coursePlayZan(Command.CoursePlayZan cmd) {
List<FormatText> list = getPostList(cmd);
return getRxRetrofit().create(NetApiStore.class).coursePlayZan(getMaps(list));
}
//课程课后笔记列表
public static Observable<BaseResponse<List<CoursePlayBean.Comments>>> courseReplyList(Command.CourseReplyList cmd) {
List<FormatText> list = getPostList(cmd);
return getRxRetrofit().create(NetApiStore.class).courseReplyList(getMaps(list));
}
public static Observable<BaseAPIResponse<List<ResultBean>>> getCoursesHomePage() {
return getRxRetrofit().newBuilder().baseUrl(YdlRetrofitUtils.SERVER_API_JAVA_URL).build().create(NetApiStore.class).getCourseHomePageDatas();
}
//获取课程列表(php接口)
public static Observable<BaseResponse<List<Course>>> getCourseList(Command.GetCourse cmd) {
List<FormatText> list = getPostList(cmd);
return getRxRetrofit().create(NetApiStore.class).getPhpCourseList(getMaps(list));
}
//获取课程列表分类
public static Observable<BaseResponse<List<CourseCategoryBean>>> getCourseListCategory(BaseCommand cmd) {
List<FormatText> list = getPostList(cmd);
return getRxRetrofit().create(NetApiStore.class).getCourseCats(getMaps(list));
}
//获取课程列表分类
public static Observable<BaseAPIResponse<CourseCategoryBean>> getCourseListCategory() {
return getRxRetrofit().newBuilder().baseUrl(YdlRetrofitUtils.SERVER_API_JAVA_URL).build().create(NetApiStore.class).getCourseListCategory();
}
//获取课程专题
public static Observable<BaseAPIResponse<TopicCourseBean>> getCourseTopic(String id) {
return getRxRetrofit().newBuilder().baseUrl(YdlRetrofitUtils.SERVER_API_JAVA_URL).build().create(NetApiStore.class).getCourseSpecial(id);
}
/**
* 获取可以领取的优惠券
*
* @param uid uid
* @param services 适用服务 1预约咨询 2电话倾诉 3课程(用户课程 专家课程) 5测评
* @param receiveType 领取条件方式 1前台领取 2链接领取
* @param applyEnds 适用终端 1PC官网 2wap站点 3用户app 4好杮app 5专家app
* @return
*/
public static Observable<BaseResponse<List<CourseCouponBean>>> getCourseCoupons(String uid, String services, String receiveType, String applyEnds) {
return YdlRetrofitUtils.getRxRetrofit().newBuilder().baseUrl(YdlRetrofitUtils.SERVER_COUPON_URL)
.build().create(NetApiStore.class).getCourseCoupons(uid, services, receiveType, applyEnds);
}
//领取优惠券
public static Observable<BaseResponse<List<String>>> receiveCoupon(String couponIds) {
RequestBody body = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), couponIds);
return YdlRetrofitUtils.getRxRetrofit().newBuilder().baseUrl(YdlRetrofitUtils.SERVER_COUPON_URL).build().create(NetApiStore.class).receiveCoupon(body);
}
}
package com.yidianling.course.coursePlay.dialog
/**
* 课程播放列表dialog 实体类
* Created by harvie on 2017/6/29 0029.
*/
class CoursePlayListBean{
var isPlay = false //当前是否在播放
var title = "" //课程标题
var playUrl = "" //播放地址
var isTestPlay = false //是否试听音频
var playTime = "00:00" //音频时长
}
\ No newline at end of file
package com.yidianling.course.coursePlay.dialog
import android.app.Activity
import android.app.Dialog
import android.content.Context
import android.os.Bundle
import android.support.v7.widget.LinearLayoutManager
import android.support.v7.widget.RecyclerView
import android.view.Gravity
import android.view.View
import android.view.Window
import android.widget.ImageView
import android.widget.TextView
import com.ydl.ydl_image.module.GlideApp
import com.yidianling.course.R
import com.yidianling.ydlcommon.adapter.CommonRecyclerAdapter
import com.yidianling.ydlcommon.view.BaseViewHolder
/**
* 课程播放列表dialog
* Created by harvie on 2017/6/29 0029.
*/
class CoursePlayListDialog : Dialog {
var mContext: Context? = null
var recyList: RecyclerView? = null
var textClose: TextView? = null
var index = 0 //当前播放下标
var itemListener: ItemClickListener? = null
var adapter: CommonRecyclerAdapter<CoursePlayListBean>? = null
constructor(context: Context?) : super(context, R.style.commonDialog) {
mContext = context
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
requestWindowFeature(Window.FEATURE_NO_TITLE)
setContentView(R.layout.dialog_course_playlist)
val m = window.windowManager
val d = m.defaultDisplay
val p = window.attributes
p.width = d.width //设置dialog的宽度为当前手机屏幕的宽度
p.height = (d.height * 5 / 10)
window.attributes = p
window.setGravity(Gravity.BOTTOM)
initView()
}
//跟新当前播放下标
fun updateIndex(inde: Int) {
index = inde
adapter?.notifyDataSetChanged()
}
fun initView() {
recyList = findViewById<RecyclerView>(R.id.recy_list)
textClose = findViewById<TextView>(R.id.text_close)
textClose?.setOnClickListener {
dismiss()
}
recyList?.layoutManager = LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false)
adapter = CommonRecyclerAdapter<CoursePlayListBean>(recyList, R.layout.dialog_course_playlist_item)
.setBindDataCallback(object : CommonRecyclerAdapter.BindDataCallback<CoursePlayListBean> {
override fun bindDatabindData(holder: BaseViewHolder, t: CoursePlayListBean, position: Int) {
var gifView: ImageView = holder.getView(R.id.gifView)
if (index == position) {
GlideApp.with(context).load(R.drawable.music).into(gifView)
gifView.visibility = View.VISIBLE
holder.setTextColor(R.id.text_title, context.resources.getColor(R.color.google_green))
} else {
gifView.visibility = View.GONE
holder.setTextColor(R.id.text_title, context.resources.getColor(R.color.black_deep))
}
var test: TextView = holder.getView(R.id.text_test)
if (t.isTestPlay) {
test.visibility = View.VISIBLE
} else {
test.visibility = View.GONE
}
holder.setText(R.id.text_title, t.title)
holder.setText(R.id.text_time, "" + t.playTime)
holder.setOnClickListener(R.id.lin_body) {
//item点击事件
var boo = itemListener?.itemClick(position) ?: false
if (boo) {
index = position
adapter?.notifyDataSetChanged()
}
}
}
})
recyList?.adapter = adapter
}
fun scrollToPosition(i: Int) {
recyList?.scrollToPosition(i)
}
//设置item点击事件
fun setItemClickListener(itemListener: ItemClickListener): CoursePlayListDialog {
this.itemListener = itemListener
return this
}
//设置列表数据
fun setList(playIndex: Int, list: List<CoursePlayListBean>?) {
this.index = playIndex
if (list != null) {
for (i in list.indices) {
list[i].isPlay = i == playIndex
}
adapter?.update(list)
}
}
//跟新列表状态
fun updateAdapter() {
adapter?.notifyDataSetChanged()
}
//列表点击事件
interface ItemClickListener {
fun itemClick(indec: Int): Boolean
}
override fun show() {
if (null == mContext) {
return
}
if (mContext is Activity) {
if ((mContext as Activity).isFinishing) {
return
}
}
super.show()
}
}
\ No newline at end of file
package com.yidianling.course.coursePlay.http
/**
* @author yuanwai
* @描述:课程列表页接口实现模型
* @Copyright Copyright (c) 2018
* @Company 壹点灵
* @date 2018/12/11
*/
object CourseListDataManager{
fun getHttp(): ICourseListHttp = CourseListHttpImpl.getInstance()
}
\ No newline at end of file
package com.yidianling.course.coursePlay.http
import com.yidianling.course.coursePlay.common.net.NetApiStore
import com.yidianling.course.coursePlay.moudle.CourseListDataBean
import com.yidianling.ydlcommon.http.BaseAPIResponse
import com.yidianling.ydlcommon.http.RxUtils
import com.yidianling.ydlcommon.http.YdlRetrofitUtils
import io.reactivex.Observable
/**
* @author yuanWai
* @描述:课程列表页接口实现类
* @Copyright Copyright (c) 2018
* @Company 壹点灵
* @date 2018/12/12
*/
class CourseListHttpImpl : ICourseListHttp{
companion object {
fun getInstance(): CourseListHttpImpl {
return Holder.INSTANCE
}
}
object Holder {
val INSTANCE = CourseListHttpImpl()
}
private val netApiStore: NetApiStore by lazy {
YdlRetrofitUtils.getRxRetrofit().newBuilder().baseUrl(YdlRetrofitUtils.SERVER_API_JAVA_URL).build().create(NetApiStore::class.java)
}
override fun getCourseList(params: String): Observable<BaseAPIResponse<CourseListDataBean>> {
return RxUtils.mapObservable(CourseListParams(""))
.flatMap {netApiStore.getCourseList(YdlRetrofitUtils.SERVER_API_JAVA_URL + "auth/course/getList?" + params)
}
}
}
\ No newline at end of file
package com.yidianling.course.coursePlay.http
/**
* @author yuanWai
* @描述:
* @Copyright Copyright (c) 2018
* @Company 壹点灵
* @date 2018/12/12
*/
data class CourseListParams(val params : String)
\ No newline at end of file
package com.yidianling.course.coursePlay.http
import com.yidianling.course.coursePlay.moudle.CourseListDataBean
import com.yidianling.ydlcommon.http.BaseAPIResponse
import io.reactivex.Observable
/**
* @author yuanwai
* @描述:课程列表页请求接口
* @Copyright Copyright (c) 2018
* @Company 壹点灵
* @date 2018/12/11
*/
interface ICourseListHttp{
/**
* 专家搜索页请求
*/
fun getCourseList(params : String): Observable<BaseAPIResponse<CourseListDataBean>>
}
\ No newline at end of file
package com.yidianling.course.coursePlay.moudle;
import com.yidianling.course.bean.CourseHostInfoBean;
import com.yidianling.ydlcommon.data.ShareData;
//课程列表
//课程
public class Course {
/**
* 课程id
*/
public String id;
/**
* 课程标题
*/
public String title;
public String courseType;
public String image;
public String pic;
/**
* 课程价格
*/
public String applyFee;
/**
* 分享数据
*/
public ShareData share;
/**
* 课程原价
*/
public String originalApplyFee;
/**
* 课程报名人数
*/
public int joinNum;
/**
* 是否显示返利标签
* 0不显示 1显示
*/
public int isInvite;
/**
* 促销标签:
* 是否促销 1活动中 2结束or没开始 3倒计时
*/
public String isPromotion;
/**
* 课程促销价
*/
public String promotionApplyFee;
/**
* 主讲人是否开通私聊 0否1是
*/
public int isOpenChat;
/**
* 是否显示私聊,倾诉,咨询三个按钮入口
*/
public int isShowHostButton;
/**
* 私聊页面统一路由
*/
public String chatLinkUri;
public String doctorName;
public String linkUrl;
/**
* 评论的次数
*/
public int userCommentNum;
/**
* 子课程数量
*/
public int subCourseNum;
/**
* 热门课程 1不是 2是 ,
*/
public int recommend;
/**
* 新门课程 1是 2不是 ,
*/
public int newCourse;
/**
* 主讲人展示的信息
*/
public String hostInfo;
/**
* 课程封面
*/
public String hostListPic;
/**
* 试听附件
*/
public String demoFile;
/**
* 0无 1音频 2视频
*/
public int demoType;
/**
* 是否已购买
*/
public boolean isBuy = false;
public CourseHostInfoBean courseHostInfo;
}
\ No newline at end of file
package com.yidianling.course.coursePlay.moudle
/**
* 参加课程返回值
* Created by hgw on 2017/7/2.
*/
class CourseAddOrderBean{
var payId = "" //支付id
var title = ""
var orderId = "" //订单id
var uid = 0
var money = "" //支付金额
var type = 0 //支付类型
var succ = "" //支付成功跳转链接
}
package com.yidianling.course.coursePlay.moudle
import com.yidianling.ydlcommon.bean.YDLBaseDataBean
/**
* @author yuanWai
* @描述:
* @Copyright Copyright (c) 2018
* @Company 壹点灵
* @date 2018/12/12
*/
data class CourseListDataBean(val list : List<Course>) : YDLBaseDataBean()
\ No newline at end of file
package com.yidianling.course.coursePlay.moudle
import com.yidianling.ydlcommon.data.ShareData
import java.util.*
/**
* 课程播放页 数据实例
* Created by harvie on 2017/6/28 0028.
*/
public class CoursePlayBean {
var id = 0
var host_uid = 0
var apply_fee = 0.00f
var zan_count = 0
var is_zan = 0 //1.已赞 2.未赞
var title = ""
var pic = ""
var is_buy = 0 //1.已报名 2.未报名
var share: ShareData? = null
var button_status = 0 //1.显示购买按钮 2.不显示 按钮文案统一:参加课程
//播放列表
var attachmentMedia: ArrayList<String>? = null
//试听列表
var attachmentDemo: ArrayList<String>? = null
//专家详情
var doctor: Doctor? = null
//评论
var comments: ArrayList<Comments>? = null
var attachmentTitle: ArrayList<String>? = null
var attachmentIndex = 0
var courseIds: ArrayList<String>? = null
//专家详情
inner class Doctor {
var doctor_id = 0
var uid = 0
var head = ""
var name = ""
var desc = ""
var consult_num = "" //咨询人数
var ths_num = "" //感谢数
var fans_num = "" //粉丝数量
}
//评论列表实体类
public class Comments {
var uid = ""
var create_time = ""
var content = ""
var name = ""
var head = ""
}
}
\ No newline at end of file
package com.yidianling.course.coursePlay.presenter
import com.yidianling.common.tools.ToastUtil
import com.yidianling.ydlcommon.bean.CourseMediaDetailBean
import com.yidianling.course.coursePlay.CoursePlayActivity
import com.yidianling.course.coursePlay.common.net.RetrofitUtils
import com.yidianling.ydlcommon.http.api.ApiRequestUtil
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
/**
* 课程播放页--数据传输与逻辑处理层
* Created by harvie on 2017/6/28 0028.
*/
class CoursePlayPresenter(val view: CoursePlayActivity) {
fun getInitData(course_id: Int) {
view.showLoadingDialog()
ApiRequestUtil.getCoursePlayData(course_id.toString())
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ resp ->
view.dismissLoadingDialog()
if (resp.code == 200) {
//跟新view显示
if (resp.data != null && resp.data is CourseMediaDetailBean) {
view.updateView(resp.data as CourseMediaDetailBean)
} else {
ToastUtil.toastShort("解析出错")
}
} else {
ToastUtil.toastShort(resp.msg)
}
}, { t ->
view.dismissLoadingDialog()
RetrofitUtils.handleError(view, t)
})
}
}
\ No newline at end of file
package com.yidianling.course.courseSearch
import android.support.v7.widget.LinearLayoutManager
import android.text.TextUtils
import android.util.Log
import android.view.View
import android.view.WindowManager
import android.widget.ImageView
import com.alibaba.android.arouter.facade.annotation.Route
import com.ydl.base_module.ui.searchbarview.SearchBarView
import com.ydl.ydl_image.config.SimpleImageOpConfiger
import com.ydl.ydl_image.listener.YDLImageRecyclerOnScrollListener
import com.ydl.ydl_image.manager.YDLImageCacheManager
import com.yidianling.common.tools.ToastUtil
import com.yidianling.course.CourseConstants
import com.yidianling.course.R
import com.yidianling.course.coursePlay.moudle.Course
import com.yidianling.course.courseSearch.http.CourseSearchApiUtils
import com.yidianling.course.courseSearch.view.ICourseSearchView
import com.yidianling.ydlcommon.base.BaseActivity
import com.yidianling.ydlcommon.data.ShareData
import com.yidianling.ydlcommon.h5.H5Params
import com.yidianling.ydlcommon.h5.NewH5Activity
import com.yidianling.ydlcommon.http.ThrowableConsumer
import com.yidianling.ydlcommon.router.IYDLRouterConstant
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.functions.Consumer
import io.reactivex.schedulers.Schedulers
import kotlinx.android.synthetic.main.activity_course_search.*
import org.json.JSONException
import org.json.JSONObject
/**
* @author <a href="https://www.jianshu.com/u/c1e5310dd724">xujian</a>
* @描述: 课程搜索页面
* @Copyright Copyright (c) 2019
* @Company 壹点灵
* @date 2019/01/07
*/
@Route(path = "/course/search")
class CourseSearchActivity : BaseActivity(), CourseSearchAdapter.OnItemClick, ICourseSearchView {
private var inputString: String = ""
private var nowPage = 1
private var courseList: ArrayList<Course> = ArrayList()
private val ROUTER_PARAMS = "routerParam"
private var courseSearchAdapter: CourseSearchAdapter? = null
private var courseSearchAdapterWrapper: CourseSearchAdapterWrapper? = null
override fun layoutResId(): Int {
return R.layout.activity_course_search
}
override fun initDataAndEvent() {
// showUnusualView("请输入要搜索的内容")
getParam()
initBackBtn()
initSearchBar()
initSwipeRefreshLayout()
initRecyclerView()
}
/**
* 获取路由传递的参数
*/
private fun getParam() {
if (null == intent || !intent.hasExtra(ROUTER_PARAMS)) {
return
}
//路由传递的入参
val json = intent.getStringExtra(ROUTER_PARAMS)
try {
val jsonObject = JSONObject(json)
//搜索关键字
inputString = jsonObject.getString(IYDLRouterConstant.EXTRA_KEYWORD)
activity_course_search_search_bar_view.setText(inputString)
} catch (e: JSONException) {
e.printStackTrace()
}
}
/**
* 初始化返回按钮
*/
private fun initBackBtn() {
activity_course_back_btn.setOnClickListener { finish() }
}
/**
* 初始化顶部搜索框并监听键盘搜索按钮
*/
private fun initSearchBar() {
window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE)
activity_course_search_search_bar_view.initBarType(SearchBarView.ENABLE_INPUT, object : SearchBarView.SearchCallBack {
override fun cloase() {
finish()
}
override fun clickSearchBtn(str: String) {
inputString = str
if (TextUtils.isEmpty(str)) {
// showUnusualView("请输入要搜索的内容")
ToastUtil.toastShort("请输入要搜索的内容")
return
}
loadCourseList(true)
}
})
}
/**
* 设置下拉刷新
*/
private fun initSwipeRefreshLayout() {
activity_course_search_swipe_refresh_layout.setOnRefreshListener {
loadCourseList(true)
}
}
/**
* 初始化列表并监听滑动到底部 footer Item加载更多
*/
private fun initRecyclerView() {
if (null == courseSearchAdapterWrapper) {
courseSearchAdapter = CourseSearchAdapter(this, CourseSearchActicity@ this, courseList!!)
courseSearchAdapter!!.setOnItemClickListener(this)
activity_course_search_recycler.layoutManager = LinearLayoutManager(this)
courseSearchAdapterWrapper = CourseSearchAdapterWrapper(
this,
courseSearchAdapter!!,
20,
activity_course_search_recycler)
.setOnLoadMoreListener(object : CourseSearchAdapterWrapper.OnLoadMoreListener {
override fun onLoadMore() {
loadCourseList(false)
}
})
activity_course_search_recycler.adapter = courseSearchAdapterWrapper
//滑动监听 图片是否加载
activity_course_search_recycler.addOnScrollListener(YDLImageRecyclerOnScrollListener(CourseSearchActicity@ this))
loadCourseList(true)
}
}
/**
* item点击事件
*/
override fun onItemClickEvent(position: Int) {
var courseItem = courseList[position]
if (null != courseItem) {
val h5Params = H5Params(CourseConstants.COURSE_DETAIL_H5 + courseItem.id, this.getString(R.string.course_detail))
if (null != courseItem.share && !TextUtils.isEmpty(courseItem.share.share_url)) {
val shareData = ShareData(courseItem.share.share_url, courseItem.share.title, courseItem.share.cover, courseItem.share.desc)
h5Params.shareData = shareData
}
NewH5Activity.start(this, h5Params)
}
}
/**
* 加载图片
*/
override fun showImage(url: String?, imageView: ImageView, width: Int, height: Int) {
val sp = SimpleImageOpConfiger()
sp.heigt = height
sp.width = width
sp.errorPic = R.drawable.default_img
sp.loadingPic = R.drawable.default_img
YDLImageCacheManager.showImage(CourseSearchActicity@ this, url, imageView, sp)
}
/**
* 根据输入搜索专家课程
* type true代表首次加载,false代表加载下一页
*/
fun loadCourseList(type: Boolean) {
if (TextUtils.isEmpty(inputString)) {
activity_course_search_swipe_refresh_layout.isRefreshing = false
return
}
when (type) {
//如果是首次加载,则当前页面重置为1,数据清空
true -> {
nowPage = 1
activity_course_search_swipe_refresh_layout.isRefreshing = true
}
//如果不是首次加载,则页面+1
false -> {
nowPage++
}
}
CourseSearchApiUtils.courseSearchList(nowPage, inputString)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(Consumer {
if (it.data.list.isNotEmpty()) {
hideUnusualPage()
if (type) {
courseList.clear()
}
courseList.addAll(it.data.list)
courseSearchAdapterWrapper!!.insertData()
} else {
if (!type) {
courseSearchAdapterWrapper!!.noMoreData()
} else {
showUnusualView("没有搜到相关信息,换个关键词看看吧", true)
}
}
activity_course_search_swipe_refresh_layout.isRefreshing = false
}, object : ThrowableConsumer() {
override fun accept(msg: String) {
Log.i("testtest", msg)
activity_course_search_swipe_refresh_layout.isRefreshing = false
showUnusualView("请检查你的网络设置", false)
}
})
}
/**
* 显示异常页面
*/
private fun showUnusualView(desc: String, isEmpty: Boolean) {
if (!TextUtils.isEmpty(desc)) activity_course_search_unusual_layout_desc.text = desc
activity_course_search_unusual_layout.visibility = View.VISIBLE
activity_course_search_recycler.visibility = View.GONE
iv_empty.setImageResource(if (isEmpty) R.drawable.ico_img_zixun_empty else R.drawable.blank)
}
/**
* 隐藏异常页面
*/
fun hideUnusualPage() {
activity_course_search_unusual_layout.visibility = View.GONE
activity_course_search_recycler.visibility = View.VISIBLE
}
}
\ No newline at end of file
package com.yidianling.course.courseSearch
import android.content.Context
import android.support.v7.widget.RecyclerView
import android.view.ViewGroup
import com.yidianling.common.tools.RxImageTool
import com.yidianling.course.coursePlay.moudle.Course
import com.yidianling.course.courseSearch.view.ICourseSearchView
import com.yidianling.course.widget.CourseItemNewView
/**
* @author <a href="https://www.jianshu.com/u/c1e5310dd724">xujian</a>
* @描述: 课程搜索页面列表适配器
* @Copyright Copyright (c) 2019
* @Company 壹点灵
* @date 2019/01/07
*/
class CourseSearchAdapter(private val mContext: Context, private val mCourseSearchView: ICourseSearchView, private val list: List<Course>) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
private var itemListener: OnItemClick? = null
private var dp145: Int = 0
private var dp80: Int = 0
init {
dp145 = RxImageTool.dip2px(145f)
dp80 = RxImageTool.dip2px(80f)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CourseSearchViewHolder {
return CourseSearchViewHolder(CourseItemNewView(mContext))
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
val bean = list[position]
when (holder) {
is CourseSearchViewHolder -> {
holder.mView.setData(bean)
holder.mView.setOnClickListener {
itemListener?.onItemClickEvent(position)
}
}
}
}
fun setOnItemClickListener(listener: OnItemClick) {
itemListener = listener
}
interface OnItemClick {
fun onItemClickEvent(position: Int)
}
override fun getItemCount(): Int {
return list.size
}
//自定义的ViewHolder,持有每个Item的的所有界面元素
inner class CourseSearchViewHolder(var mView: CourseItemNewView) : RecyclerView.ViewHolder(mView)
}
\ No newline at end of file
package com.yidianling.course.courseSearch
import android.content.Context
import android.support.v7.widget.LinearLayoutManager
import android.support.v7.widget.RecyclerView
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import com.yidianling.course.R
/**
* @author <a href="https://www.jianshu.com/u/c1e5310dd724">xujian</a>
* @描述: 课程搜索页面列表适配器包装类,包装了底部item(加载中和到达底部item的变化,还有上拉到底部的监听)
* @Copyright Copyright (c) 2019
* @Company 壹点灵
* @date 2019/01/07
*/
class CourseSearchAdapterWrapper(
context: Context,
val mAdapter: RecyclerView.Adapter<RecyclerView.ViewHolder>,
val initialPageCount: Int,
val recycler: RecyclerView)
: RecyclerView.Adapter<RecyclerView.ViewHolder>() {
private var mInflater: LayoutInflater? = null
private var footerType = TYPE_FOOTER_LOADING //默认为正在加载
private var lastVisibleItem:Int = 0
private var onLoadMoreListener: OnLoadMoreListener? = null
private var isLoading:Boolean? = null
init {
isLoading = true
mInflater = LayoutInflater.from(context)
}
companion object {
const val TYPE_FOOTER_LOADING = 100000001 //底部正在加载view
const val TYPE_FOOTER_NOMORE = 100000002 //底部无更多数据view
}
/**
* 加1是因为包装类为自定义的adapter增加了一个footer
*/
override fun getItemCount(): Int = mAdapter.itemCount + 1
override fun getItemViewType(position: Int): Int {
//如果首次加载的数据少于 initialPageCount 行,则表明没有更多数据了,直接返回TYPE_FOOTER_NOMORE类型footer
if (position == mAdapter.itemCount && mAdapter.itemCount < initialPageCount) return TYPE_FOOTER_NOMORE
return when (position < mAdapter.itemCount) {
true -> mAdapter.getItemViewType(position)
false -> footerType!!
}
}
override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): RecyclerView.ViewHolder {
var view:View? = null
return when (viewType) {
TYPE_FOOTER_LOADING -> {
FooterHolder(mInflater!!.inflate(R.layout.footer, parent, false), TYPE_FOOTER_LOADING)
}
TYPE_FOOTER_NOMORE -> {
FooterHolder(mInflater!!.inflate(R.layout.footer, parent, false), TYPE_FOOTER_NOMORE)
}
else -> {
mAdapter.onCreateViewHolder(parent, viewType)
}
}
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder?, position: Int) {
when (holder) {
is FooterHolder -> { }
else -> {
mAdapter.onBindViewHolder(holder, position)
}
}
}
//需要加载更多数据时调用
fun insertData() {
footerType = TYPE_FOOTER_LOADING
notifyDataSetChanged()
isLoading = false
}
//没有更多数据时候调用
fun noMoreData() {
footerType = TYPE_FOOTER_NOMORE
notifyItemChanged(mAdapter.itemCount)
isLoading = false
}
fun setOnScrollerListener() {
recycler.addOnScrollListener(object: RecyclerView.OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView?, dx: Int, dy: Int) {
val layoutManager = recyclerView?.layoutManager
when (layoutManager) {
is LinearLayoutManager -> {
lastVisibleItem = layoutManager.findLastVisibleItemPosition()
}
//这里现在只写了LinearLayoutManager的代码,后续补充
}
}
override fun onScrollStateChanged(recyclerView: RecyclerView?, newState: Int) {
if (newState == RecyclerView.SCROLL_STATE_IDLE //停止滚动
&& footerType == TYPE_FOOTER_LOADING //footer状态为加载更多
&& lastVisibleItem >= mAdapter.itemCount //最后一个显示的item序号大于适配器item数量,即显示了footer
&& isLoading == false) //当前没有在onLoadMore状态
{
isLoading = true
onLoadMoreListener?.onLoadMore()
}
}
})
}
fun setOnLoadMoreListener (listener: OnLoadMoreListener): CourseSearchAdapterWrapper {
this.onLoadMoreListener = listener
//设置滑动监听
setOnScrollerListener()
return this
}
interface OnLoadMoreListener {
fun onLoadMore() //加载更多
}
/**
* 自定义的底部item,后续会继续暴露方法给外部动态设置加载更多时候的gif图
*/
class FooterHolder(view: View, type:Int): RecyclerView.ViewHolder(view) {
var txt: TextView? = null
init {
txt = view.findViewById(R.id.footer_txt)
when (type) {
TYPE_FOOTER_LOADING -> {
txt!!.text = "正在加载..."
}
TYPE_FOOTER_NOMORE -> {
txt!!.text = "已经到达底部"
}
}
}
}
}
\ No newline at end of file
package com.yidianling.course.courseSearch;
import com.yidianling.course.coursePlay.moudle.Course;
import java.util.List;
public class CourseSearchBean {
private int pageNum;
private int pageSize;
private int size;
private int startRow;
private int endRow;
private int pages;
private int prePage;
private int nextPage;
private boolean isFirstPage;
private boolean isLastPage;
private boolean hasPreviousPage;
private boolean hasNextPage;
private int navigatePages;
private int navigateFirstPage;
private int navigateLastPage;
private int total;
private List<Integer> navigatepageNums;
public List<Course> list; //用的是ListBean类,上面的暂时没有用到
public int getPageNum() {
return pageNum;
}
public void setPageNum(int pageNum) {
this.pageNum = pageNum;
}
public int getPageSize() {
return pageSize;
}
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
public int getSize() {
return size;
}
public void setSize(int size) {
this.size = size;
}
public int getStartRow() {
return startRow;
}
public void setStartRow(int startRow) {
this.startRow = startRow;
}
public int getEndRow() {
return endRow;
}
public void setEndRow(int endRow) {
this.endRow = endRow;
}
public int getPages() {
return pages;
}
public void setPages(int pages) {
this.pages = pages;
}
public int getPrePage() {
return prePage;
}
public void setPrePage(int prePage) {
this.prePage = prePage;
}
public int getNextPage() {
return nextPage;
}
public void setNextPage(int nextPage) {
this.nextPage = nextPage;
}
public boolean isIsFirstPage() {
return isFirstPage;
}
public void setIsFirstPage(boolean isFirstPage) {
this.isFirstPage = isFirstPage;
}
public boolean isIsLastPage() {
return isLastPage;
}
public void setIsLastPage(boolean isLastPage) {
this.isLastPage = isLastPage;
}
public boolean isHasPreviousPage() {
return hasPreviousPage;
}
public void setHasPreviousPage(boolean hasPreviousPage) {
this.hasPreviousPage = hasPreviousPage;
}
public boolean isHasNextPage() {
return hasNextPage;
}
public void setHasNextPage(boolean hasNextPage) {
this.hasNextPage = hasNextPage;
}
public int getNavigatePages() {
return navigatePages;
}
public void setNavigatePages(int navigatePages) {
this.navigatePages = navigatePages;
}
public int getNavigateFirstPage() {
return navigateFirstPage;
}
public void setNavigateFirstPage(int navigateFirstPage) {
this.navigateFirstPage = navigateFirstPage;
}
public int getNavigateLastPage() {
return navigateLastPage;
}
public void setNavigateLastPage(int navigateLastPage) {
this.navigateLastPage = navigateLastPage;
}
public int getTotal() {
return total;
}
public void setTotal(int total) {
this.total = total;
}
public List<Integer> getNavigatepageNums() {
return navigatepageNums;
}
public void setNavigatepageNums(List<Integer> navigatepageNums) {
this.navigatepageNums = navigatepageNums;
}
}
\ No newline at end of file
package com.yidianling.course.courseSearch.http
import com.yidianling.course.courseSearch.CourseSearchBean
import com.yidianling.ydlcommon.http.BaseAPIResponse
import com.yidianling.ydlcommon.http.BaseResponse
import com.yidianling.ydlcommon.http.YdlRetrofitUtils
import io.reactivex.Observable
/**
* @author <a href="https://www.jianshu.com/u/c1e5310dd724">xujian</a>
* @描述:
* @Copyright Copyright (c) 2019
* @Company 壹点灵
* @date 2019/01/10
*/
class CourseSearchApiUtils {
companion object {
/**
* 专家课程搜索列表
*/
fun courseSearchList(page:Int, keyWord:String) : Observable<BaseAPIResponse<CourseSearchBean>> {
return YdlRetrofitUtils.getRxRetrofit().newBuilder().baseUrl(YdlRetrofitUtils.SERVER_API_JAVA_URL).build()
.create(CourseSearchListApi::class.java).courseSearchList(page, keyWord)
}
}
}
\ No newline at end of file
package com.yidianling.course.courseSearch.http
import com.yidianling.course.courseSearch.CourseSearchBean
import com.yidianling.ydlcommon.http.BaseAPIResponse
import io.reactivex.Observable
import retrofit2.http.*
/**
* @author <a href="https://www.jianshu.com/u/c1e5310dd724">xujian</a>
* @描述: 课程搜索列表Api
* @Copyright Copyright (c) 2019
* @Company 壹点灵
* @date 2019/01/08
*/
interface CourseSearchListApi{
//专家课程搜索列表
@GET("auth/course/getList")
fun courseSearchList(@Query("page")page: Int, @Query("keyWord")keyWord: String): Observable<BaseAPIResponse<CourseSearchBean>>
}
\ No newline at end of file
package com.yidianling.course.courseSearch.http
import com.yidianling.course.courseSearch.CourseSearchBean
import com.yidianling.ydlcommon.http.BaseAPIResponse
import com.yidianling.ydlcommon.http.BaseResponse
import io.reactivex.Observable
/**
* @author <a href="https://www.jianshu.com/u/c1e5310dd724">xujian</a>
* @描述: 课程搜索列表请求接口
* @Copyright Copyright (c) 2019
* @Company 壹点灵
* @date 2019/01/08
*/
interface ICourseSearchListHttp{
/**
* 课程专题列表
*/
fun courseSearchList(page:Int, keyWord:String): Observable<BaseAPIResponse<CourseSearchBean>>
}
\ No newline at end of file
package com.yidianling.course.courseSearch.view
import android.widget.ImageView
/**
* @author yuanWai
* @描述:
* @Copyright Copyright (c) 2018
* @Company 壹点灵
* @date 2019/1/11
*/
interface ICourseSearchView{
fun showImage(url : String?,imageView : ImageView,width : Int,height : Int)
}
\ No newline at end of file
package com.yidianling.course.course_special_list.activity
import android.content.Context
import android.support.v4.widget.SwipeRefreshLayout
import android.support.v7.widget.LinearLayoutManager
import android.view.View
import com.ydl.ydlcommon.base.BaseMvpActivity
import com.ydl.ydlcommon.view.swapelayout.YDLAdapterWrapper
import com.ydl.ydlcommon.view.swapelayout.YDLSwipeToLoadHelper
import com.yidianling.common.tools.ToastUtil
import com.yidianling.course.R
import com.yidianling.course.course_special_list.adapter.CourseSpecialListAdapter
import com.yidianling.course.course_special_list.bean.CourseSpecialItemBean
import com.yidianling.course.course_special_list.contract.ICourseSpecialListContract
import com.yidianling.course.course_special_list.event.CourseSpecialListEventImpl
import com.yidianling.course.course_special_list.event.ICourseSpecialListEvent
import com.yidianling.course.course_special_list.presenter.CourseSpecialListPresenterImpl
import kotlinx.android.synthetic.main.course_special_list_activity.*
import kotlinx.android.synthetic.main.layout_title_bar.*
/**
* @author yuanwai
* @描述:课程专题列表页
* @Copyright Copyright (c) 2018
* @Company 壹点灵
* @date 2018/9/18
*/
class CourseSpecialListActivity :
BaseMvpActivity<ICourseSpecialListContract.View, ICourseSpecialListContract.Presenter>(),
ICourseSpecialListContract.View, SwipeRefreshLayout.OnRefreshListener, YDLSwipeToLoadHelper.LoadMoreListener {
/**
* 课程专题事件接口
*/
private var mCourseSpecialListEvent: ICourseSpecialListEvent? = null
/**
* 课程专题列表适配器
*/
private var mListAdapter: CourseSpecialListAdapter? = null
/**
* 适配器包装 处理上拉加载更多
*/
private var mAdapterWrapper: YDLAdapterWrapper? = null
/**
* 下拉刷新组件
*/
private var mLoadMoreHelper: YDLSwipeToLoadHelper? = null
/**
* 页码
*/
private var page: Int = 1
override fun createPresenter(): ICourseSpecialListContract.Presenter {
return CourseSpecialListPresenterImpl(this)
}
override fun getContext(): Context {
return CourseSpecialListActivity@ this
}
override fun layoutResId(): Int {
return R.layout.course_special_list_activity
}
override fun initDataAndEvent() {
initView()
mCourseSpecialListEvent = CourseSpecialListEventImpl(CourseSpecialListActivity@ this)
initAdapter()
//加载本地缓存
mPresenter.loadLocalData()
//加载网络接口
mPresenter.specialListRequest(page)
}
private fun initView() {
iv_back.setOnClickListener {
finish()
}
tv_title.text = resources.getString(R.string.course_special_list_title)
tv_left_menu.visibility = View.GONE
}
/**
* 初始化适配器
*/
private fun initAdapter() {
if (null == mListAdapter) {
mListAdapter = CourseSpecialListAdapter(ArrayList(), mCourseSpecialListEvent!!)
}
//onMeasure中导致mCurrentTargetOffsetTop为负数了 所以需要手动设置下距离 不然 显示不出来 下拉动画 蛋疼
swipelayout.setProgressViewOffset(false, 0, 52)
swipelayout.isRefreshing = true
swipelayout.setOnRefreshListener(this)
swipelayout.setColorSchemeResources(R.color.main_theme)
rv_list.layoutManager = LinearLayoutManager(this)
if (null == mAdapterWrapper) {
mAdapterWrapper = YDLAdapterWrapper(mListAdapter!!)
}
mLoadMoreHelper = YDLSwipeToLoadHelper(rv_list, mAdapterWrapper!!)
mLoadMoreHelper!!.setLoadMoreListener(this)
rv_list.adapter = mAdapterWrapper
}
override fun specialListResponse(list: List<CourseSpecialItemBean>) {
hideError()
swipelayout.isRefreshing = false
mListAdapter!!.updataItems(list)
// 刷新完成是解禁上拉加载更多
mLoadMoreHelper!!.setSwipeToLoadEnabled(true)
if (null == list || list.size < 10) {
mLoadMoreHelper!!.setNoMoreData()
}
mAdapterWrapper!!.notifyDataSetChanged()
}
override fun specialListRequestFail() {
showError()
}
override fun loadMoreResponse(list: List<CourseSpecialItemBean>) {
mListAdapter!!.addItems(list)
// 刷新完成是解禁上拉加载更多
if (null == list || list.size < 10) {
mLoadMoreHelper!!.setNoMoreData()
} else {
mLoadMoreHelper!!.setLoadMoreFinish()
}
mAdapterWrapper!!.notifyDataSetChanged()
}
private fun showError() {
swipelayout.isRefreshing = false
rv_list.visibility = View.GONE
v_no_network.visibility = View.VISIBLE
}
private fun hideError() {
swipelayout.isRefreshing = false
rv_list.visibility = View.VISIBLE
v_no_network.visibility = View.GONE
}
override fun showError(msg: String?) {
swipelayout.isRefreshing = false
ToastUtil.toastShort(msg)
}
override fun onRefresh() {
//禁止上拉加载更多
mLoadMoreHelper!!.setSwipeToLoadEnabled(false)
page = 1
mPresenter.specialListRequest(page)
}
override fun onLoad() {
page++
mPresenter.specialListRequest(page)
}
}
\ No newline at end of file
package com.yidianling.course.course_special_list.adapter
import android.support.v7.widget.RecyclerView
import android.view.ViewGroup
import com.yidianling.course.course_special_list.widget.CourseSpecialListItemView
import com.yidianling.course.course_special_list.bean.CourseSpecialItemBean
import com.yidianling.course.course_special_list.event.ICourseSpecialListEvent
import java.util.*
/**
* @author yuanwai
* @描述:课程专题列表适配器
* @Copyright Copyright (c) 2018
* @Company 壹点灵
* @date 2018/9/18
*/
class CourseSpecialListAdapter(private var mListData: List<CourseSpecialItemBean>,
private var courseSpecialListEvent: ICourseSpecialListEvent) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
fun updataItems(list: List<CourseSpecialItemBean>) {
if (null == mListData || mListData.isEmpty()) {
mListData = ArrayList()
} else {
(mListData as ArrayList).clear()
}
(mListData as ArrayList).addAll(list)
}
fun addItems(list: List<CourseSpecialItemBean>) {
if (null == mListData || mListData.isEmpty()) {
mListData = ArrayList()
}
(mListData as ArrayList).addAll(list)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return CourseSpecialItemViewHolder(CourseSpecialListItemView(parent.context, courseSpecialListEvent))
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) =
if (holder is CourseSpecialItemViewHolder && null != holder.courseSpecialItemView) {
holder.courseSpecialItemView!!.initData(mListData[position])
} else {
}
override fun getItemCount(): Int {
return mListData.size
}
/**
* 课程专题列表viewHolder
*/
inner class CourseSpecialItemViewHolder(itemView: CourseSpecialListItemView) : RecyclerView.ViewHolder(itemView) {
var courseSpecialItemView: CourseSpecialListItemView? = null
init {
courseSpecialItemView = itemView
}
}
}
\ No newline at end of file
package com.yidianling.course.course_special_list.bean
/**
* @author yuanwai
* @描述:课程专题列表页数据bean
* @Copyright Copyright (c) 2018
* @Company 壹点灵
* @date 2018/9/18
*/
data class CourseSpecialItemBean(
/**
* 专题Id
*/
val id: String?,
/**
* 专题名称
*/
val name: String?,
/**
* 专题图片地址
*/
val pic: String?,
val totalValidCourse: String?,
/**
* 共多少节课程 文案
*/
val courseNumContent: String?)
\ No newline at end of file
package com.yidianling.course.course_special_list.bean
class CourseSpecialListBean{
var list:List<CourseSpecialItemBean>? = null
}
\ No newline at end of file
package com.yidianling.course.course_special_list.contract
import android.content.Context
import com.ydl.ydlcommon.mvp.base.IModel
import com.ydl.ydlcommon.mvp.base.IPresenter
import com.ydl.ydlcommon.mvp.base.IView
import com.yidianling.course.course_special_list.bean.CourseSpecialItemBean
import com.yidianling.course.course_special_list.bean.CourseSpecialListBean
import com.yidianling.course.course_special_list.http.CourseSpecialListParam
import io.reactivex.Observable
/**
* @author yuanwai
* @描述:课程专题列表页约束类
* @Copyright Copyright (c) 2018
* @Company 壹点灵
* @date 2018/9/18
*/
interface ICourseSpecialListContract {
//View接口
interface View : IView {
/**
* 课程专题列表页数据请求结果
* @param list 数据集合
*/
fun specialListResponse(list: List<CourseSpecialItemBean>)
/**
* 课程专题列表加载更多请求结果
*/
fun loadMoreResponse(list: List<CourseSpecialItemBean>)
/**
* 倾诉首页数据请求失败
*/
fun specialListRequestFail()
/**
* 显示错误信息
*/
fun showError(msg: String?)
fun getContext(): Context
}
interface Presenter : IPresenter<View> {
/**
* 加载本地缓存
*/
fun loadLocalData()
/**
* 课程专题列表数据请求
*/
fun specialListRequest(page: Int)
/**
* 课程专题列表加载更多
*/
fun loadMore(page: Int)
}
interface Model : IModel {
/**
* 倾诉首页数据请求
*/
fun specialListRequest(param: CourseSpecialListParam): Observable<CourseSpecialListBean>
}
}
\ No newline at end of file
package com.yidianling.course.course_special_list.event
import android.content.Context
import android.text.TextUtils
import com.yidianling.course.courseNew.CourseTopicActivity
/**
* @author yuanwai
* @描述:课程专题列表事件实现类
* @Copyright Copyright (c) 2018
* @Company 壹点灵
* @date 2018/9/18
*/
class CourseSpecialListEventImpl(private var mContext: Context) : ICourseSpecialListEvent{
/**
* 跳转课程专题页
*/
override fun toCourseSpecial(id: String?) {
if (TextUtils.isEmpty(id)){
return
}
CourseTopicActivity.start(mContext,id!!)
}
}
\ No newline at end of file
package com.yidianling.course.course_special_list.event
/**
* @author yuanwai
* @描述:课程专题列表页事件类
* @Copyright Copyright (c) 2018
* @Company 壹点灵
* @date 2018/9/18
*/
interface ICourseSpecialListEvent{
/**
* 跳转课程专题页
*/
fun toCourseSpecial(id : String?)
}
\ No newline at end of file
package com.yidianling.course.course_special_list.http
import com.ydl.ydlcommon.data.http.BaseAPIResponse
import com.yidianling.course.course_special_list.bean.CourseSpecialListBean
import io.reactivex.Observable
import retrofit2.http.GET
import retrofit2.http.QueryMap
/**
* @author yuanwai
* @描述:课程专题列表Api
* @Copyright Copyright (c) 2018
* @Company 壹点灵
* @date 2018/9/18
*/
interface CourseSpecialListApi {
//课程专题列表
@GET("auth/course/listCoursesBySpecialId")
fun courseSpecialList(@QueryMap params: Map<String, String>): Observable<BaseAPIResponse<CourseSpecialListBean>>
}
\ No newline at end of file
package com.yidianling.course.course_special_list.http
/**
* @author yuanwai
* @描述:课程专题列表接口实现模型
* @Copyright Copyright (c) 2018
* @Company 壹点灵
* @date 2018/9/18
*/
object CourseSpecialListDataManager{
fun getHttp(): ICourseSpecialListHttp = CourseSpecialListHttpImpl.getInstance()
}
\ No newline at end of file
package com.yidianling.course.course_special_list.http
import com.ydl.ydlcommon.data.http.BaseAPIResponse
import com.ydl.ydlcommon.data.http.BaseCommand
import com.ydl.ydlcommon.data.http.FormatText
import com.ydl.ydlcommon.utils.NetworkParamsUtils
import com.ydl.ydlnet.YDLHttpUtils
import com.yidianling.course.course_special_list.bean.CourseSpecialListBean
import io.reactivex.Observable
/**
* @author yuanwai
* @描述:课程专题列表接口实现类
* @Copyright Copyright (c) 2018
* @Company 壹点灵
* @date 2018/9/18
*/
class CourseSpecialListHttpImpl private constructor() : ICourseSpecialListHttp {
companion object {
fun getInstance(): CourseSpecialListHttpImpl {
return Holder.INSTANCE
}
fun clearCourseSpecialListApi() {
Holder.INSTANCE.courseSpecialListApi = null
}
}
object Holder {
val INSTANCE = CourseSpecialListHttpImpl()
}
fun getPostList(crq: BaseCommand): List<FormatText> {
return NetworkParamsUtils.getPostList(crq)
}
fun getMaps(list: List<FormatText>): Map<String, String> {
return NetworkParamsUtils.getMaps(list)
}
private var courseSpecialListApi: CourseSpecialListApi? = null
override fun courseSpecialList(param: CourseSpecialListParam): Observable<BaseAPIResponse<CourseSpecialListBean>> {
val list = getPostList(param)
return YDLHttpUtils.getInstance().newBuilder().baseUrl(NetworkParamsUtils.SERVER_API_JAVA_URL)
.build().create<CourseSpecialListApi>(CourseSpecialListApi::class.java!!).courseSpecialList(getMaps(list))
}
}
\ No newline at end of file
package com.yidianling.course.course_special_list.http
import com.ydl.ydlcommon.data.http.BaseCommand
/**
* @author yuanwai
* @描述:课程专题列表请求参数bean
* @Copyright Copyright (c) 2018
* @Company 壹点灵
* @date 2018/9/18
*/
data class CourseSpecialListParam(var page: Int, var specialId: Int = 0, var perPageRows: Int = 20) : BaseCommand()
\ No newline at end of file
package com.yidianling.course.course_special_list.http
import com.yidianling.course.course_special_list.bean.CourseSpecialItemBean
import com.yidianling.course.course_special_list.bean.CourseSpecialListBean
import com.yidianling.ydlcommon.http.BaseAPIResponse
import com.yidianling.ydlcommon.http.BaseResponse
import io.reactivex.Observable
/**
* @author yuanwai
* @描述:课程专题列表请求接口
* @Copyright Copyright (c) 2018
* @Company 壹点灵
* @date 2018/9/18
*/
interface ICourseSpecialListHttp{
/**
* 课程专题列表
*/
fun courseSpecialList(param: CourseSpecialListParam): Observable<BaseAPIResponse<CourseSpecialListBean>>
}
\ No newline at end of file
package com.yidianling.course.course_special_list.model
import com.yidianling.course.course_special_list.bean.CourseSpecialItemBean
import com.yidianling.course.course_special_list.bean.CourseSpecialListBean
import com.yidianling.course.course_special_list.contract.ICourseSpecialListContract
import com.yidianling.course.course_special_list.http.CourseSpecialListDataManager
import com.yidianling.course.course_special_list.http.CourseSpecialListParam
import com.yidianling.ydlcommon.http.RxUtils
import io.reactivex.Observable
/**
* @author yuanwai
* @描述:课程专题列表数据模型实现类
* @Copyright Copyright (c) 2018
* @Company 壹点灵
* @date 2018/9/18
*/
class CourseSpecialListModelImpl : ICourseSpecialListContract.Model{
override fun specialListRequest(param: CourseSpecialListParam): Observable<CourseSpecialListBean> {
return CourseSpecialListDataManager.getHttp().courseSpecialList(param).compose(RxUtils.resultJavaData())
}
}
\ No newline at end of file
package com.yidianling.course.course_special_list.presenter
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import com.yidianling.common.tools.RxNetTool
import com.yidianling.course.course_special_list.bean.CourseSpecialItemBean
import com.yidianling.course.course_special_list.contract.ICourseSpecialListContract
import com.yidianling.course.course_special_list.http.CourseSpecialListParam
import com.yidianling.course.course_special_list.model.CourseSpecialListModelImpl
import com.yidianling.ydlcommon.http.ThrowableConsumer
import com.yidianling.ydlcommon.mvp.RxPresenter
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.functions.Consumer
import io.reactivex.schedulers.Schedulers
/**
* @author yuanwai
* @描述:课程专题列表逻辑实现类
* @Copyright Copyright (c) 2018
* @Company 壹点灵
* @date 2018/9/18
*/
class CourseSpecialListPresenterImpl (view: ICourseSpecialListContract.View) :
RxPresenter<ICourseSpecialListContract.View, ICourseSpecialListContract.Model>(view), ICourseSpecialListContract.Presenter{
override fun createModel(): ICourseSpecialListContract.Model {
return CourseSpecialListModelImpl()
}
/**
* 加载本地缓存
*/
override fun loadLocalData() {
}
override fun specialListRequest(page: Int) {
if (!RxNetTool.isConnected(view.getContext())){
view.specialListRequestFail()
return
}
requestList(page,false)
}
/**
* 测试方法
*/
private fun test(loadMore: Boolean){
var json = "[{\"id\":123,\"name\":\"教你让孩子赢在起跑线上,情商高的孩子更容易成功\",\"pic\":\"https://img.ydlcdn.com/file/2017/12/21/wmgpjndoczjhk6ld.png\",\"courseNumContent\":\"共12节课程\"},{\"id\":123,\"name\":\"教你让孩子赢在起跑线上,情商高的孩子更容易成功\",\"pic\":\"https://img.ydlcdn.com/file/2017/12/21/wmgpjndoczjhk6ld.png\",\"courseNumContent\":\"共12节课程\"},{\"id\":123,\"name\":\"教你让孩子赢在起跑线上,情商高的孩子更容易成功\",\"pic\":\"https://img.ydlcdn.com/file/2017/12/21/wmgpjndoczjhk6ld.png\",\"courseNumContent\":\"共12节课程\"},{\"id\":123,\"name\":\"教你让孩子赢在起跑线上,情商高的孩子更容易成功\",\"pic\":\"https://img.ydlcdn.com/file/2017/12/21/wmgpjndoczjhk6ld.png\",\"courseNumContent\":\"共12节课程\"},{\"id\":123,\"name\":\"教你让孩子赢在起跑线上,情商高的孩子更容易成功\",\"pic\":\"https://img.ydlcdn.com/file/2017/12/21/wmgpjndoczjhk6ld.png\",\"courseNumContent\":\"共12节课程\"},{\"id\":123,\"name\":\"教你让孩子赢在起跑线上,情商高的孩子更容易成功\",\"pic\":\"https://img.ydlcdn.com/file/2017/12/21/wmgpjndoczjhk6ld.png\",\"courseNumContent\":\"共12节课程\"},{\"id\":123,\"name\":\"教你让孩子赢在起跑线上,情商高的孩子更容易成功\",\"pic\":\"https://img.ydlcdn.com/file/2017/12/21/wmgpjndoczjhk6ld.png\",\"courseNumContent\":\"共12节课程\"},{\"id\":123,\"name\":\"教你让孩子赢在起跑线上,情商高的孩子更容易成功\",\"pic\":\"https://img.ydlcdn.com/file/2017/12/21/wmgpjndoczjhk6ld.png\",\"courseNumContent\":\"共12节课程\"},{\"id\":123,\"name\":\"教你让孩子赢在起跑线上,情商高的孩子更容易成功\",\"pic\":\"https://img.ydlcdn.com/file/2017/12/21/wmgpjndoczjhk6ld.png\",\"courseNumContent\":\"共12节课程\"},{\"id\":123,\"name\":\"教你让孩子赢在起跑线上,情商高的孩子更容易成功\",\"pic\":\"https://img.ydlcdn.com/file/2017/12/21/wmgpjndoczjhk6ld.png\",\"courseNumContent\":\"共12节课程\"}]"
val gson = Gson()
val list = gson.fromJson<List<CourseSpecialItemBean>>(json, object : TypeToken<List<CourseSpecialItemBean>>() {}.type)
if (loadMore){
view.loadMoreResponse(list)
}else{
view.specialListResponse(list)
}
}
override fun loadMore(page: Int) {
if (!RxNetTool.isConnected(view.getContext())){
view.showError("网络不给力")
return
}
requestList(page,true)
}
/**
* 接口请求
* @param page 页码
* @param loadMore 是否为上拉加载更多
*/
private fun requestList(page: Int,loadMore : Boolean){
val disposable = model.specialListRequest(CourseSpecialListParam(page,0))
.subscribeOn(Schedulers.io())
.map { it }
.filter { it != null }
.observeOn(AndroidSchedulers.mainThread())
.subscribe(Consumer {
if (loadMore){
view.loadMoreResponse(it.list?:ArrayList())
}else{
view.specialListResponse(it.list?:ArrayList())
}
}, object : ThrowableConsumer() {
override fun accept(msg: String) {
if (loadMore){
view.showError(msg)
}else{
view.specialListRequestFail()
}
}
})
addDisposable(disposable)
}
}
\ No newline at end of file
package com.yidianling.course.course_special_list.widget
import android.annotation.SuppressLint
import android.content.Context
import android.support.constraint.ConstraintLayout
import android.text.TextUtils
import android.view.View
import com.ydl.ydl_image.module.GlideApp
import com.yidianling.course.R
import com.yidianling.course.course_special_list.bean.CourseSpecialItemBean
import com.yidianling.course.course_special_list.event.ICourseSpecialListEvent
import kotlinx.android.synthetic.main.course_special_item_view.view.*
/**
* @author yuanwai
* @描述:课程专题列表 Item View
* @Copyright Copyright (c) 2018
* @Company 壹点灵
* @date 2018/9/18
*/
class CourseSpecialListItemView(
private var mContext: Context,
private var courseSpecialListEvent: ICourseSpecialListEvent
) : ConstraintLayout(mContext) {
private var cacheBean: CourseSpecialItemBean? = null
init {
initView()
}
/**
* 界面初始化
*/
private fun initView() {
View.inflate(context, R.layout.course_special_item_view, this)
setOnClickListener {
if (null != cacheBean) {
courseSpecialListEvent.toCourseSpecial(cacheBean!!.id)
}
}
}
/**
* 数据赋值
*/
@SuppressLint("SetTextI18n")
fun initData(bean: CourseSpecialItemBean?) {
cacheBean = bean
if (null == bean) {
visibility = View.GONE
return
}
visibility = View.VISIBLE
//专题图片
if (!TextUtils.isEmpty(bean.pic)) {
GlideApp.with(context).load(bean.pic).dontAnimate().into(iv_head)
}
//专题名称
tv_title.text = bean.name
tv_courseNumContent.text = "共" + bean.totalValidCourse + "节课程"
}
}
\ No newline at end of file
import android.content.Intent
import android.net.Uri
import android.text.TextUtils
import com.ydl.ydl_router.manager.YDLRouterManager
import com.yidianling.common.tools.LogUtil
import com.yidianling.common.tools.RxDeviceTool
import com.yidianling.course.BuildConfig
import com.yidianling.course.CourseConstants
import com.yidianling.course.courseNew.mine.MyCourseActivity
import com.yidianling.course.course_special_list.activity.CourseSpecialListActivity
import com.yidianling.course.flutterPlugin.CourseSendPlugin
import com.yidianling.course.router.CourseIn
import com.yidianling.ydlcommon.app.YdlCommonApp
import com.yidianling.ydlcommon.flutter.base.BaseFlutterFragment
import com.yidianling.ydlcommon.h5.H5Params
import com.yidianling.ydlcommon.h5.NewH5Activity
import com.yidianling.ydlcommon.player.YDLMusicHelper
import com.yidianling.ydlcommon.router.YdlCommonRouterManager
import com.yidianling.ydlcommon.utils.PlayerFloatHelper
import com.yidianling.ydlcommon.view.PlayerFloatView
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
import io.flutter.view.FlutterView
/**
* @author jiucheng
* @描述:
* @Copyright Copyright (c) 2018
* @Company 壹点灵
* @date 2019/10/18
*/
class CoursePlugin : MethodChannel.MethodCallHandler {
private var mFragment: BaseFlutterFragment? = null
private constructor(fragment: BaseFlutterFragment) {
mFragment = fragment
}
companion object {
const val CHANNEL: String = "base/channel/native/get"
const val GETPUBLICPARAMAS: String = "getPublicParamas"
const val JUMPURL: String = "jumpUrl"
const val PLAYCOURSEFILE: String = "playCourseFile"
const val PAUSECOURSEPLAY: String = "pauseCoursePlay"
fun rigister(fragment: BaseFlutterFragment, flutterView: FlutterView) {
MethodChannel(flutterView, CHANNEL).setMethodCallHandler(CoursePlugin(fragment))
}
}
override fun onMethodCall(methodCall: MethodCall, result: MethodChannel.Result) {
when (methodCall.method) {
GETPUBLICPARAMAS -> {
val mMap = mutableMapOf<String, Any>()
mMap["isDevelopment"] = BuildConfig.DEBUG
mMap["uid"] = YdlCommonRouterManager.getYdlCommonRoute().getUid().toString()
mMap["accessToken"] = YdlCommonRouterManager.getYdlCommonRoute().getAccessToken()
?: ""
mMap["isFromApp"] = "1"
mMap["version"] = RxDeviceTool.getAppVersionName(YdlCommonApp.getApp())
mMap["osBuild"] = RxDeviceTool.getBuildMANUFACTURER() + "," + RxDeviceTool.getBuildBrandModel() + "," + RxDeviceTool.getOsBuileVersion() + "," + RxDeviceTool.getAppVersionName(YdlCommonApp.getApp())
result.success(mMap)
}
JUMPURL -> {
var jumpUrl: String? = methodCall.arguments.toString()
if (!TextUtils.isEmpty(jumpUrl)) {
when {
jumpUrl!!.contains("user/login") -> mFragment!!.startActivity(CourseIn.loginWayIntent(mFragment!!.activity))
jumpUrl.contains("course/myCourse") -> MyCourseActivity.start(mFragment!!.activity)
jumpUrl.contains("course/specialList") -> //跳转专题列表页
mFragment!!.activity.startActivity(Intent(mFragment!!.activity, CourseSpecialListActivity::class.java))
jumpUrl.contains("course/detail") -> {
var uri = Uri.parse(jumpUrl)
var id = uri.getQueryParameter("id")
val h5Params = H5Params(CourseConstants.COURSE_DETAIL_H5 + id, "课程详情")
NewH5Activity.start(mFragment!!.activity, h5Params)
}
else -> YDLRouterManager.router(jumpUrl)
}
}
}
PLAYCOURSEFILE -> {
var fileInfo: Map<*, *> = methodCall.arguments as Map<*, *>
LogUtil.e("播放地址:$fileInfo")
playMedia(fileInfo)
}
PAUSECOURSEPLAY -> {
if (YDLMusicHelper.isPlaying()) {
YDLMusicHelper.pause()
PlayerFloatHelper.updatePlayState()
}
}
}
}
private fun playMedia(fileInfo: Map<*, *>) {
if (PlayerFloatHelper.isShow(mFragment!!.activity)) {
PlayerFloatHelper.hide()
PlayerFloatHelper.removeView(mFragment!!.activity)
YDLMusicHelper.clearTempData()
YDLMusicHelper.stop()
} else {
PlayerFloatHelper.removeView(mFragment!!.activity)
}
YDLMusicHelper.title = fileInfo["title"].toString()
YDLMusicHelper.name = fileInfo["name"].toString()
YDLMusicHelper.cover = fileInfo["cover"].toString()
YDLMusicHelper.course_id = fileInfo["courseId"] as Int
YDLMusicHelper.isCanClick = false
var demoType = fileInfo["demoType"] as Int
var url = fileInfo["url"].toString()
if (demoType == 1) {
YDLMusicHelper.playType = 0
PlayerFloatHelper.show(mFragment!!.activity)
YDLMusicHelper.coursePlay(url)
}
if (demoType == 2) {
YDLMusicHelper.playType = 1
YDLMusicHelper.courseVideoUlr = url
PlayerFloatHelper.show(mFragment!!.activity)
}
PlayerFloatHelper.addClickListener(object : PlayerFloatView.FloatViewPlayListener {
override fun onStartClick() {
if (!YDLMusicHelper.isCanClick && YDLMusicHelper.course_id != 0) {
CourseSendPlugin.sendMsg(true)
}
}
override fun onPlayFinish() {
PlayerFloatHelper.hide()
YDLMusicHelper.clearTempData()
YDLMusicHelper.stop()
}
override fun onPauseClick() {
if (!YDLMusicHelper.isCanClick && YDLMusicHelper.course_id != 0) {
CourseSendPlugin.sendMsg(false)
}
}
})
}
}
\ No newline at end of file
package com.yidianling.course.flutterPlugin
import com.ydl.ydlcommon.flutter.io.flutter.facade.FlutterFragment
import io.flutter.plugin.common.EventChannel
import io.flutter.view.FlutterView
/**
* @author jiucheng
* @描述:
* @Copyright Copyright (c) 2018
* @Company 壹点灵
* @date 2019/10/25
*/
object CourseSendPlugin {
private var messageChannel: EventChannel? = null
const val CHANNEL: String = "base/channel/native/post"
private var mFragment: FlutterFragment? = null
private var eventSink: EventChannel.EventSink? = null
fun initContext(fragment: FlutterFragment, view: FlutterView): CourseSendPlugin {
mFragment = fragment
messageChannel = EventChannel(view, CHANNEL)
messageChannel!!.setStreamHandler(object : EventChannel.StreamHandler {
override fun onListen(p0: Any?, event: EventChannel.EventSink?) {
eventSink = event
}
override fun onCancel(p0: Any?) {
}
})
return this
}
fun sendMsg(isPlaying: Boolean) {
eventSink!!.success(isPlaying)
}
}
\ No newline at end of file
package com.yidianling.course.link
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.text.TextUtils
import com.yidianling.course.courseNew.CourseTopicActivity
import com.yidianling.course.course_special_list.activity.CourseSpecialListActivity
/**
* @author yuanwai
* @描述:路由
* @Copyright Copyright (c) 2018
* @Company 壹点灵
* @date 2018/9/19
*/
class CourseLinkUrl{
companion object {
fun jump(context: Context,url : String?){
if (TextUtils.isEmpty(url)){
return
}
var uri = Uri.parse(url)
if (null == uri){
return
}
newLink(context,uri)
}
//新版本路由协议 ydl-user://xxx/xxx/?id=3
private fun newLink(context: Context, uri: Uri){
when(uri.host){
"course" ->{
//课程
if ("/special" == uri.path){
//专题页
var id = uri.getQueryParameter("id")
if (TextUtils.isEmpty(id)){
return
}
//跳转课程专题页面
CourseTopicActivity.start(context,id)
}else if("/speciallist" == uri.path){
//跳转专题列表页
context.startActivity(Intent(context, CourseSpecialListActivity::class.java))
}
}
}
}
}
}
\ No newline at end of file
package com.yidianling.course.model;
/**
* Created by Jim on 2018/6/22 0022.
*/
public class Banner {
public String imagUrl;
}
package com.yidianling.course.model;
/**
* Created by Jim on 2018/7/14 0014.
*/
public class CatogoryBean {
public String title;
public String image;
public String linkUrl;
}
package com.yidianling.course.model;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import org.json.JSONException;
import org.json.JSONObject;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
/**
* Created by Jim on 2018/7/14 0014.
*/
public class ClassifiedCoursesBean {
public Head head;
public Body body;
public Footer footer;
public static class Head {
/**
* title : 精品课程
* tab1Name : 免费课程
* tab2Name : 付费课程
*/
public String title;
public String tab1Name;
public String tab2Name;
}
public static class Body {
public List<TabListBean> oneTabList;
public List<TabListBean> twoTabList;
public static class TabListBean {
/**
* id : 6
* image : https://img.ydlcdn.com/file/2015/11/zawz18il050dybbm.jpg
* title : 阳光心灵分享会第一期:谈谈心中的那缕烦忧
* expert :
* price : 30.00
* popularity : 67
* linkUrl : https://testh2.yidianling.com/course/6
*/
public String id;
public String image;
public String title;
public String expert;
public String price;
public String popularity;
public String linkUrl;
}
}
public static class Footer {
public String title;
public String linkUrl;
}
}
package com.yidianling.course.model;
import com.google.gson.annotations.SerializedName;
public class CourseBean {
public String id;
public String image;
public String title;
public String leftBottom;
public String rightBottom;
public String linkUrl;
/**
* 是否显示返利标签
* 0不显示 1显示
*/
public int isInvite;
/**
* 促销标签:
* 1活动中 2结束or没开始 3倒计时
* <p>
* 1和3都显示促销标签
* <p>
* if(is_promotion == 1) 时 列表金额取 promotion_apply_fee字段
*/
@SerializedName("isPromotion")
//这么java接口和php接口字段名不同,兼容两个接口
public String is_promotion;
@SerializedName("promotionApplyFee")
public String promotion_apply_fee;
}
\ No newline at end of file
package com.yidianling.course.model;
import java.util.List;
/**
* Created by Jim on 2018/7/16 0016.
*/
public class CourseCategoryBean {
public String name;
public String pinyin;
public String value;
public int parentId;
public int id;
public String type;
public List<CourseCategoryBean> childSample;
}
package com.yidianling.course.model;
/**
* @author <a href="https://www.jianshu.com/u/c1e5310dd724">xujian</a>
* @描述: 用于存放私聊,倾诉,咨询三个按钮
* @Copyright Copyright (c) 2018
* @Company 壹点灵
* @date 2018/12/26
*/
public class LocalButtonShownBean {
public int type; //0隐藏1显示
public String name; //按钮描述
public LocalButtonShownBean(int type, String name) {
this.type = type;
this.name = name;
}
}
package com.yidianling.course.model;
import com.yidianling.course.bean.CourseHomeBodyBean;
import com.yidianling.course.courseNew.home.ResultBean;
import java.util.List;
/**
* @author : Zhangwenchao
* @e-mail : zhangwch@yidianling.com
* @time : 2018/7/14
*/
public class NormalCourseBean {
public ResultBean.Head head;
public List<CourseHomeBodyBean> body;
public ResultBean.Footer footer;
public int type;
public boolean diviLine;
}
package com.yidianling.course.model;
import com.yidianling.course.bean.CourseHomeBodyBean;
import com.yidianling.course.courseNew.home.ResultBean;
import java.util.ArrayList;
import java.util.List;
/**
* @author : Zhangwenchao
* @e-mail : zhangwch@yidianling.com
* @time : 2018/7/14
*/
public class QulityCourseBean {
public ResultBean.Head head;
public List<ArrayList<CourseHomeBodyBean>> body;
public ResultBean.Footer footer;
public int type;
public boolean diviLine;
}
package com.yidianling.course.model
import com.yidianling.course.coursePlay.moudle.Course
import com.yidianling.ydlcommon.data.ShareData
/**
* Created by Jim on 2018/7/16 0016.
*/
class TopicCourseBean {
/**
* id : 3
* name : 测试
* pic : https://img.yidianling.com/file/2018/07/03/0bqebfh6mc7taj4x.jpg
* explain : 11111
* course : 98,77,887
* course_list : [{"id":"77","title":"哈哈哈哈哈哈哈哈哈哈哈","cat":"1","pic":"https://img.ydlcdn.com/file/2017/07/07/uxeypkdttgeym75o.JPG","tags":"亲子课程,青春期教育","desc":"发表打发打发","content":"
*
*短发科技大会发来打发打发<\/p>","content_image_url":"","host_uid":"5","host_phone":"13506648571","can_apply":"1","is_show":"1","course_start_time":"2017-07-08 00:00:00","apply_start_time":null,"apply_end_time":null,"apply_fee":"0.00","original_apply_fee":"0.00","city":"","address":"","is_online":"1","person_limit":null,"read_nums":"111","is_banner":"1","is_recommend":"1","hot_sort":"0","create_time":"2017-07-07 14:44:51","update_time":"2017-07-12 02:14:43","course_type":"3","type":"1","attachment":"","attachment1":"","attachment2":"","attachment3":"","attachment4":"","attachment5":"","demo1":"","demo2":"","demo3":"","demo4":"","demo_option":"2","parent_id":"0","comment_num":"0","video_youku":"","video_display":"1","object":"0","chat_team":"13","fit_group":"","join_way":"","out_join_num":"{\"千聊\":0,\"荔枝FM\":0,\"喜马拉雅\":0}","is_recommend_app":"1","only_doctor_show":"2","settle_rule_id":"1","effect_time":null,"expire_time":null},{"id":"98","title":"ACT(接纳与承诺疗法)理论及案例实操","cat":"7","pic":"https://img.ydlcdn.com/file/2017/09/13/7qudmjpkieh30fkq.jpg","tags":"湿哒哒撒所多所大","desc":"啥答案多撒多撒多所","content":"
*
*实打实大奥所大所<\/p>","content_image_url":"","host_uid":"5","host_phone":"13506648571","can_apply":"1","is_show":"1","course_start_time":null,"apply_start_time":null,"apply_end_time":null,"apply_fee":"5.00","original_apply_fee":"0.00","city":"","address":"","is_online":"1","person_limit":null,"read_nums":"303","is_banner":"2","is_recommend":"1","hot_sort":"2","create_time":"2017-09-14 08:11:49","update_time":"2018-07-15 10:24:15","course_type":"6","type":"1","attachment":"","attachment1":"","attachment2":"","attachment3":"","attachment4":"","attachment5":"","demo1":"","demo2":"","demo3":"","demo4":"","demo_option":"2","parent_id":"0","comment_num":"0","video_youku":"","video_display":"1","object":"0","chat_team":"0","fit_group":"","join_way":"","out_join_num":"{\"千聊\":0,\"荔枝FM\":0,\"喜马拉雅\":0}","is_recommend_app":"1","only_doctor_show":"2","settle_rule_id":"1","effect_time":null,"expire_time":null},{"id":"887","title":"孤独患者45","cat":"1","pic":"https://img.ydlcdn.com/file/2017/12/21/wmgpjndoczjhk6ld.png","tags":"1","desc":"1","content":"
*
*1111<\/p>","content_image_url":"","host_uid":"5","host_phone":"13506648571","can_apply":"1","is_show":"1","course_start_time":null,"apply_start_time":null,"apply_end_time":null,"apply_fee":"0.00","original_apply_fee":"0.00","city":"","address":"","is_online":"1","person_limit":null,"read_nums":"0","is_banner":"1","is_recommend":"1","hot_sort":"0","create_time":"2018-06-29 07:44:00","update_time":"2018-07-03 06:22:58","course_type":"1","type":"1","attachment":"https://img.ydlcdn.com/file/2018/03/28/u8srdrvo9pfaqsli.mp3","attachment1":"","attachment2":"","attachment3":"","attachment4":"","attachment5":"","demo1":"","demo2":"","demo3":"","demo4":"","demo_option":"2","parent_id":"0","comment_num":"0","video_youku":"","video_display":"1","object":"1","chat_team":"0","fit_group":"","join_way":"","out_join_num":"{\"千聊\":0,\"荔枝FM\":0,\"喜马拉雅\":0}","is_recommend_app":"1","only_doctor_show":"2","settle_rule_id":"0","effect_time":null,"expire_time":null}]
*/
var id: String? = null
var name: String? = null
var pic: String? = null
var explain: String? = null
var course: String? = null
var courses: List<Course>? = null
var share: ShareData? = null
}
package com.yidianling.course.router
import android.app.Activity
import android.content.Intent
import com.yidianling.router.RouterManager
import com.yidianling.router.user.UserResponse
/**
* author : Zhangwenchao
* e-mail : zhangwch@yidianling.com
* time : 2018/04/25
*/
object CourseIn {
fun isLogin(): Boolean {
return RouterManager.getUserRouter()?.isLogin()?:false
}
fun getUserInfo(): UserResponse.UserInfo? {
return RouterManager.getUserRouter()?.getUserInfo()
}
fun loginWayIntent(activity: Activity): Intent? {
return RouterManager.getUserRouter()?.loginWayIntent(activity)
}
fun mainIntent(activity: Activity): Intent? {
return RouterManager.getAppRouter()?.mainIntent(activity)
}
}
\ No newline at end of file
package com.yidianling.course.router
import android.app.Activity
import com.yidianling.course.courseNew.CourseTopicActivity
import com.yidianling.router.course.ICourseRouter
import com.yidianling.ydlcommon.player.YDLMusicHelper
/**
* Created by hgw on 2018/5/3.
*/
class CourseRouterImp : ICourseRouter{
override fun closePlayer() {
if (YDLMusicHelper.isCoursePlaying()) {
YDLMusicHelper.stop()
}
}
override fun isPlaying(): Boolean {
return YDLMusicHelper.isPlaying()
}
override fun play(){
YDLMusicHelper.replay()
}
override fun pause(){
YDLMusicHelper.pause()
}
override fun startCoursePlayPage(activity: Activity, from: Int) {
YDLMusicHelper.startCoursePlayActivity(activity,from)
}
override fun courseTopic(activity: Activity, id: String){
return CourseTopicActivity.start(activity, id)
}
}
\ No newline at end of file
package com.yidianling.course.widget
import android.content.Context
import android.text.SpannableString
import android.text.Spanned
import android.text.TextUtils
import android.text.style.AbsoluteSizeSpan
import android.view.View
import android.view.ViewGroup
import android.widget.LinearLayout
import com.yidianling.common.tools.RxImageTool
import com.yidianling.course.R
import com.yidianling.course.bean.CourseCouponBean
import kotlinx.android.synthetic.main.view_course_coupon_detail.view.*
import java.lang.Float
import java.math.BigDecimal
/**
* @author jiucheng
* @描述:课程优惠券详情页面
* @Copyright Copyright (c) 2018
* @Company 壹点灵
* @date 2019/3/27
*/
class CourseCouponDetailView : LinearLayout {
constructor(context: Context) : super(context) {
initView()
}
private fun initView() {
orientation = LinearLayout.HORIZONTAL
val params = LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, RxImageTool.dp2px(90f))
params.bottomMargin = RxImageTool.dp2px(10f)
layoutParams = params
setBackgroundResource(R.drawable.img_course_coupon_detail_bg)
View.inflate(context, R.layout.view_course_coupon_detail, this)
}
fun setData(beanCourse: CourseCouponBean, hasReceived: Boolean, event: (toLink: String) -> Unit) {
if (TextUtils.equals(beanCourse.type, "1")) {//立减
val amountStr = "¥${beanCourse.amount}"
val sp = SpannableString(amountStr)
sp.setSpan(AbsoluteSizeSpan(16, true), 0, 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
tv_price.text = sp
} else {//折扣
val a1 = BigDecimal(Float.toString(beanCourse.discount.toFloat()))
val b1 = BigDecimal(Float.toString(10f))
val result = a1.multiply(b1).toFloat()// 相乘结果
val discountStr = "${result}折"
val discountSp = SpannableString(discountStr)
discountSp.setSpan(AbsoluteSizeSpan(16, true), discountStr.length - 1, discountStr.length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
tv_price.text = discountSp
}
tv_title.text = beanCourse.title
tv_duration.text = beanCourse.effective
tv_use_condition.text = beanCourse.rangeCont
tv_discountCont.text = beanCourse.discountCont
if (TextUtils.isEmpty(beanCourse.discountCont) && beanCourse.useCondition == "1") {
tv_discountCont.text = "无限制"
}
tv_use.visibility = if (hasReceived) View.VISIBLE else View.GONE
tv_use.setOnClickListener {
event(beanCourse.toLink)
}
}
fun setUseVisibility(hasReceived: Boolean) {
tv_use.visibility = if (hasReceived) View.VISIBLE else View.GONE
}
}
package com.yidianling.course.widget
import android.app.Activity
import android.app.Dialog
import android.graphics.drawable.ColorDrawable
import android.os.Bundle
import android.text.TextUtils
import android.view.View
import android.view.ViewGroup
import android.widget.LinearLayout
import com.yidianling.common.tools.RxImageTool
import com.yidianling.course.R
import com.yidianling.course.bean.CourseCouponBean
import kotlinx.android.synthetic.main.dialog_course_coupon.*
/**
* @author jiucheng
* @描述:课程优惠券
* @Copyright Copyright (c) 2018
* @Company 壹点灵
* @date 2019/3/25
*/
class CourseCouponDialog(private var activity: Activity?, var list: List<CourseCouponBean>, var listener: OnClickEnsureListener?) : Dialog(activity) {
var status: Int = STATUS_RECEIVER
private var courseCouponBean: CourseCouponBean? = null
//领取成功的张数
private var successCount = 0
companion object {
var STATUS_RECEIVER = 0 //立即领取
var STATUS_GET = 1 //查看我的卡券
}
init {
this.courseCouponBean = list[0]
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.dialog_course_coupon)
setCanceledOnTouchOutside(false)
setCardViewHeight()
initCouponView(list, false)
iv_close.setOnClickListener {
dismiss()
}
tv_ensure.setOnClickListener {
if (listener != null) {
if (status == STATUS_GET && successCount == 0) {
dismiss()
} else {
listener!!.clickEnsure(status)
}
}
}
window.setBackgroundDrawable(ColorDrawable())
updateUiByStatus()
}
private fun setCardViewHeight() {
if (list.size < 2) {
var parms = LinearLayout.LayoutParams(RxImageTool.dp2px(310f), RxImageTool.dp2px(300f))
parms.leftMargin = RxImageTool.dp2px(32f)
parms.rightMargin = RxImageTool.dp2px(32f)
card_view.layoutParams = parms
}
}
private fun updateDetailView() {
repeat(ll_content.childCount) {
var view = ll_content.getChildAt(it)
if (view is CourseCouponDetailView) {
view.setUseVisibility(true)
}
}
}
/**
* [status] 状态码
* [ids] 领取成功的优惠券id
*/
fun updateStatus(status: Int, ids: List<String>?) {
this.status = status
//对比领取成功的id和所有优惠券的id
if (this.status == STATUS_GET) {
if (ids == null || ids.isEmpty()) {
successCount = 0
ll_content.removeAllViews()
} else {
successCount = ids.size
compareOriginalWithSuccess(ids)
}
}
updateUiByStatus()
}
private fun updateUiByStatus() {
var title = ""
var ensureText = ""
when (status) {
STATUS_RECEIVER -> {
title = "有${list.size}张课程优惠券可领取"
ensureText = "立即领取"
}
STATUS_GET -> {
if (successCount == 0) {
title = "优惠券已经被领光啦"
ensureText = "看看课程吧"
iv_empty.visibility = View.VISIBLE
scrollview.visibility = View.GONE
} else {
title = if (successCount == list.size) {
"领取成功"
} else {
"您成功领取${successCount}张优惠券"
}
if (successCount != list.size) {
tv_introduction.visibility = View.VISIBLE
}
ensureText = "查看我的卡券"
updateDetailView()
}
}
}
tv_title.text = title
tv_ensure.text = ensureText
}
private fun initCouponView(list: List<CourseCouponBean>?, hasReceived: Boolean) {
ll_content.removeAllViews()
if (list!!.size == 1) {
var params = LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
params.topMargin = RxImageTool.dp2px(26f)
scrollview.layoutParams = params
}
repeat(list!!.size) { it ->
val couponDetailView = CourseCouponDetailView(activity!!)
couponDetailView.setData(list[it], hasReceived) {
if (listener != null) {
listener!!.clickUse(it)
}
}
ll_content.addView(couponDetailView)
}
}
private fun compareOriginalWithSuccess(ids: List<String>) {
if (ids.size == list!!.size) {
return
}
val resultList = ArrayList<CourseCouponBean>()
repeat(ids.size) {
val id = ids[it]
for (bean in list!!) {
if (TextUtils.equals(id, bean.id)) {
resultList.add(bean)
}
}
}
initCouponView(resultList, true)
}
interface OnClickEnsureListener {
fun clickEnsure(status: Int)
fun clickUse(toLink: String)
}
override fun show() {
if (null == activity || activity!!.isFinishing) {
return
}
super.show()
}
}
\ No newline at end of file
package com.yidianling.course.widget
import android.annotation.SuppressLint
import android.content.Context
import android.graphics.Paint
import android.support.constraint.ConstraintLayout
import android.text.TextUtils
import android.util.AttributeSet
import android.view.View
import com.alibaba.android.arouter.launcher.ARouter
import com.ydl.ydl_image.module.GlideApp
import com.yidianling.common.tools.RxImageTool
import com.yidianling.course.CourseConstants
import com.yidianling.course.R
import com.yidianling.course.coursePlay.moudle.Course
import com.yidianling.ydlcommon.h5.H5Params
import com.yidianling.ydlcommon.h5.NewH5Activity
import com.yidianling.ydlcommon.player.YDLMusicHelper
import com.yidianling.ydlcommon.utils.PlayerFloatHelper
import com.yidianling.ydlcommon.utils.actionutil.ActionCountUtils
import com.yidianling.ydlcommon.utils.actionutil.BIConstants
import com.yidianling.ydlcommon.view.PlayerFloatView
import kotlinx.android.synthetic.main.item_course_new_list_view.view.*
/**
* @author jiucheng
* @描述:课程列表页改版后的itemView
* @Copyright Copyright (c) 2018
* @Company 壹点灵
* @date 2019/8/13
*/
class CourseItemNewView : ConstraintLayout {
private var mContext: Context
private lateinit var course: Course
private var statusListener: PlayerFloatView.FloatViewPlayListener? = null
private var headUrl: String = ""
private var doctorName: String = ""
constructor(mContext: Context) : super(mContext) {
this.mContext = mContext
initView()
}
constructor(mContext: Context, arrt: AttributeSet) : super(mContext, arrt) {
this.mContext = mContext
initView()
}
fun initView() {
View.inflate(mContext, R.layout.item_course_new_list_view, this)
var parmas = LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT)
layoutParams = parmas
setPadding(RxImageTool.dp2px(13f), 0, RxImageTool.dp2px(15f), 0)
}
@SuppressLint("SetTextI18n")
fun setData(course: Course) {
this.course = course
if (!TextUtils.isEmpty(course.hostListPic)) {
headUrl = course.hostListPic
} else {
if (course.courseHostInfo != null && !TextUtils.isEmpty(course.courseHostInfo.doctorHead)) {
headUrl = course.courseHostInfo.doctorHead
}
}
GlideApp.with(mContext)
.load(headUrl)
.into(iv_head)
tv_title.text = course.title
if (!TextUtils.isEmpty(course.doctorName)) {
doctorName = course.doctorName
} else {
if (course.courseHostInfo != null && !TextUtils.isEmpty(course.courseHostInfo.doctorName)) {
doctorName = course.courseHostInfo.doctorName
}
}
var info = ""
if (!TextUtils.isEmpty(course.hostInfo)) {
info = course.hostInfo
} else {
if (course.courseHostInfo != null && !TextUtils.isEmpty(course.courseHostInfo.title)) {
info = course.courseHostInfo.title
}
}
if (TextUtils.isEmpty(doctorName) || TextUtils.isEmpty(info)) {
tv_doctor_info.text = "壹点灵课程精选讲师"
} else {
tv_doctor_info.text = "$doctorName · $info"
}
tv_course_info.text = "共${course.subCourseNum}讲"
tv_course_num.text = "${course.joinNum}人已学"
if (course.subCourseNum == 0) {
tv_course_info.visibility = View.GONE
view_line.visibility = View.GONE
} else {
tv_course_info.visibility = View.VISIBLE
view_line.visibility = View.VISIBLE
}
if (course.isInvite == 0) {
tv_fan_li.visibility = View.GONE
} else {
tv_fan_li.visibility = View.VISIBLE
}
if (course.newCourse == 1) {
iv_new.visibility = View.VISIBLE
} else {
iv_new.visibility = View.GONE
}
if (course.recommend == 2) {
iv_hot.visibility = View.VISIBLE
} else {
iv_hot.visibility = View.GONE
}
if (course.demoType == 0) {
iv_play.visibility = View.GONE
} else {
iv_play.visibility = View.VISIBLE
}
iv_play.setOnClickListener {
playMedia()
ActionCountUtils.count(BIConstants.CourseListEvent.POSITION_COURSE_LIST_AUDITION_CLICK, course.id)
}
tv_view_course.setOnClickListener {
if (TextUtils.equals(course.courseType, "1") || TextUtils.equals(course.courseType, "7") || TextUtils.equals(course.courseType, "6")) {
ARouter.getInstance()
.build("/course/play")
.withInt("course_id", course.id.toInt())
.navigation()
} else {
val h5Params = H5Params(CourseConstants.COURSE_DETAIL_H5 + course.id, "课程详情")
NewH5Activity.start(mContext, h5Params)
}
ActionCountUtils.count(BIConstants.CourseListEvent.POSITION_COURSE_LIST_XXX_CLICK + course.id + "_click")
}
if (!TextUtils.isEmpty(course.applyFee)) {
if (course.applyFee.contains(".")) {
tv_price.text = course.applyFee.split(".")[0]
tv_price_decimal.text = "." + course.applyFee.split(".")[1]
} else {
tv_price.text = course.applyFee
tv_price_decimal.text = ".00"
}
}
if (TextUtils.equals("1", course.isPromotion) || TextUtils.equals("3", course.isPromotion)) {
tv_cu_xiao.visibility = View.VISIBLE
if (TextUtils.equals("1", course.isPromotion)) {
if (course.promotionApplyFee.contains(".")) {
tv_price.text = course.promotionApplyFee.split(".")[0]
tv_price_decimal.text = "." + course.promotionApplyFee.split(".")[1]
} else {
tv_price.text = course.promotionApplyFee
tv_price_decimal.text = ".00"
}
}
} else {
tv_cu_xiao.visibility = View.GONE
}
if (course.isBuy) {
tv_view_course.visibility = View.VISIBLE
if (TextUtils.equals(course.courseType, "1") || TextUtils.equals(course.courseType, "7") || TextUtils.equals(course.courseType, "6")) {
tv_view_course.text = "立即听课"
} else {
tv_view_course.text = "查看课程"
}
tv_original_price.visibility = View.GONE
tv_price_si.visibility = View.GONE
tv_price.visibility = View.GONE
tv_price_decimal.visibility = View.GONE
} else {
tv_view_course.visibility = View.GONE
tv_original_price.visibility = View.VISIBLE
tv_price_si.visibility = View.VISIBLE
tv_price.visibility = View.VISIBLE
tv_price_decimal.visibility = View.VISIBLE
if (TextUtils.isEmpty(course.originalApplyFee) || TextUtils.equals(course.originalApplyFee, "0") || TextUtils.equals(course.originalApplyFee, "0.0") || TextUtils.equals(course.originalApplyFee, "0.00")) {
tv_original_price.visibility = View.GONE
} else {
tv_original_price.visibility = View.VISIBLE
}
tv_original_price.text = "¥" + course.originalApplyFee
tv_original_price.paint.flags = Paint.STRIKE_THRU_TEXT_FLAG
}
}
private fun playMedia() {
if (PlayerFloatHelper.isShow(mContext)) {
PlayerFloatHelper.hide()
PlayerFloatHelper.removeView(mContext)
YDLMusicHelper.clearTempData()
YDLMusicHelper.stop()
} else {
PlayerFloatHelper.removeView(mContext)
}
YDLMusicHelper.title = course.title
YDLMusicHelper.name = doctorName
YDLMusicHelper.cover = if (!TextUtils.isEmpty(course.image)) course.image else course.pic
YDLMusicHelper.course_id = course.id.toInt()
YDLMusicHelper.isCanClick = false
if (course.demoType == 1) {
YDLMusicHelper.playType = 0
PlayerFloatHelper.show(mContext)
YDLMusicHelper.coursePlay(course.demoFile)
}
if (course.demoType == 2) {
YDLMusicHelper.playType = 1
YDLMusicHelper.courseVideoUlr = course.demoFile
PlayerFloatHelper.show(mContext)
}
if (statusListener == null) {
statusListener = object : PlayerFloatView.FloatViewPlayListener {
override fun onStartClick() {
}
override fun onPlayFinish() {
PlayerFloatHelper.hide()
YDLMusicHelper.clearTempData()
YDLMusicHelper.stop()
}
override fun onPauseClick() {
}
}
PlayerFloatHelper.addClickListener(statusListener as PlayerFloatView.FloatViewPlayListener)
}
}
fun setBottomLineGone() {
view_bottom_line.visibility = View.INVISIBLE
}
fun setBottomLineVisible() {
view_bottom_line.visibility = View.VISIBLE
}
fun hideListenerButton() {
tv_view_course.visibility = View.GONE
}
}
\ No newline at end of file
package com.yidianling.course.widget
import android.annotation.SuppressLint
import android.app.Activity
import android.graphics.Paint
import android.support.v7.widget.CardView
import android.text.TextUtils
import android.util.Base64
import android.view.View
import com.bumptech.glide.load.engine.DiskCacheStrategy
import com.bumptech.glide.request.RequestOptions
import com.ydl.ydl_image.module.GlideApp
import com.ydl.ydl_image.transform.GlideRoundTopTransform
import com.yidianling.common.tools.RxImageTool
import com.yidianling.course.R
import com.yidianling.course.bean.PostersShareBean
import kotlinx.android.synthetic.main.view_course_poster_template.view.*
import java.util.concurrent.Executors
/**
* @author jiucheng
* @描述:课程海报模板
* @Copyright Copyright (c) 2018
* @Company 壹点灵
* @date 2019/8/6
*/
@SuppressLint("ViewConstructor")
class CoursePosterTemplate(var mContext: Activity) : CardView(mContext) {
init {
initView()
}
/**
* 界面初始化
*/
private fun initView() {
// radius = RxImageTool.dp2px(10f).toFloat()
View.inflate(context, R.layout.view_course_poster_template, this)
}
@SuppressLint("SetTextI18n")
fun setData(bean: PostersShareBean, isDefault: Boolean) {
setType(isDefault)
val myOptions = RequestOptions()
.transform(GlideRoundTopTransform(mContext, 10))
GlideApp.with(mContext)
.load(bean.pic)
.apply(myOptions)
.disallowHardwareConfig()
.into(iv_pic)
tv_title.text = bean.title
tv_intro.text = bean.desc
tv_price.text = bean.applyFee
if (TextUtils.equals("1", bean.isPromotion) || TextUtils.equals("3", bean.isPromotion)) {
tv_price.text = bean.promotionApplyFee
}
tv_original_price.text = "原价" + bean.originalApplyFee
tv_original_price.paint.flags = Paint.STRIKE_THRU_TEXT_FLAG
tv_course_num.text = bean.subCourseNum
tv_view_count.text = bean.readNums
if (bean.shareUser != null) {
if (!TextUtils.isEmpty(bean.shareUser!!.nickName)) {
tv_user_name.text = bean.shareUser!!.nickName
}
if (!TextUtils.isEmpty(bean.shareUser!!.head)) {
GlideApp.with(mContext)
.load(bean.shareUser!!.head)
.disallowHardwareConfig()
.into(iv_head)
}
}
if (!TextUtils.isEmpty(bean.qrCodeByte)) {
if (bean.qrCodeByte.contains(",")) {
bean.qrCodeByte = bean.qrCodeByte.split(",")[1]
}
Executors.newCachedThreadPool().execute {
var imageByte = Base64.decode(bean.qrCodeByte, Base64.DEFAULT)
mContext!!.runOnUiThread {
GlideApp.with(this)
.load(imageByte)
.diskCacheStrategy(DiskCacheStrategy.NONE)
.disallowHardwareConfig()
.into(iv_qrc_code)
}
}
}
}
private fun setType(isDefault: Boolean) {
root_layout.setBackgroundResource(if (isDefault) R.drawable.poster_one else R.drawable.poster_two)
view_line.isEnabled = isDefault
iv_poster_one.isEnabled = isDefault
iv_poster_two.isEnabled = isDefault
}
}
package com.yidianling.course.widget
import android.content.Context
import android.support.v4.view.ViewPager
import android.view.View
import com.yidianling.common.tools.RxImageTool
/**
* @author jiucheng
* @描述:实现ViewPager左右滑动时的时差
* @Copyright Copyright (c) 2018
* @Company 壹点灵
* @date 2019/8/6
*/
class CustomPagerTransformer(var mContext: Context) : ViewPager.PageTransformer {
private var maxTranslateOffsetX: Int = 0
private var viewPager: ViewPager? = null
init {
this.maxTranslateOffsetX = RxImageTool.dp2px(40f)
}
override fun transformPage(view: View, position: Float) {
if (viewPager == null) {
viewPager = view.parent as ViewPager?
}
val leftInScreen = view.left - viewPager!!.scrollX
val centerXInViewPager = leftInScreen + view.measuredWidth / 2
val offsetX = centerXInViewPager - viewPager!!.measuredWidth / 2
val offsetRate = offsetX.toFloat() * 0.38f / viewPager!!.measuredWidth
val scaleFactor = 1 - Math.abs(offsetRate)
if (scaleFactor > 0) {
view.scaleX = scaleFactor
view.scaleY = scaleFactor
view.translationX = -maxTranslateOffsetX * offsetRate
}
}
}
\ No newline at end of file
package com.yidianling.course.widget
import android.content.Context
import android.graphics.Color
import android.text.Editable
import android.text.TextUtils
import android.text.TextWatcher
import android.util.AttributeSet
import android.view.Gravity
import android.view.View
import android.view.inputmethod.InputMethodManager
import android.widget.LinearLayout
import android.widget.TextView
import com.ydl.ydl_router.manager.YDLRouterManager
import com.ydl.ydlcommon.router.IYDLRouterConstant
import com.ydl.ydlcommon.utils.actionutil.ActionCountUtils
import com.ydl.ydlcommon.utils.actionutil.BIConstants
import com.yidianling.common.tools.RxImageTool
import com.yidianling.course.R
import kotlinx.android.synthetic.main.common_search_bar.view.*
/**
* @author <a href="https://www.jianshu.com/u/c1e5310dd724">xujian</a>
* @描述:
* @Copyright Copyright (c) 2019
* @Company 壹点灵
* @date 2019/01/07
*/
class SearchBarView : LinearLayout {
private var barType: Int = JUMP_TO_SEARCH_COURSE
private var searchCallBack: SearchCallBack? = null
companion object {
/**
* Bar功能类型
* 0.点击跳转搜索课程页面
* 1.点击输入文本,此时需要设置EditText为可输入状态
*/
const val JUMP_TO_SEARCH_COURSE = 0
const val ENABLE_INPUT = 1
}
constructor(context: Context) : super(context) {
initView()
}
constructor(context: Context, attributeSet: AttributeSet) : super(context, attributeSet) {
initView()
}
/**
* 跳转初始化
*/
private fun initView() {
orientation = HORIZONTAL
gravity = Gravity.CENTER
setBackgroundColor(Color.WHITE)
setPadding(0, RxImageTool.dp2px(5f), 0, RxImageTool.dp2px(5f))
View.inflate(context, R.layout.common_search_bar, this)
setOnClickListener {
when (barType) {
JUMP_TO_SEARCH_COURSE -> {//搜索课程页面
ActionCountUtils.count(BIConstants.CourseHomeEvent.POSITION_COURSE_HOME_SEACH_CLICK)
YDLRouterManager.router(IYDLRouterConstant.ROUTER_COURSE_SEARCH)
}
}
}
}
/**
* 使用该View组件时必须调用
* type 一种为点击跳转,一种为点击之后输入文本进行搜索用java代码设置View宽度
* mSearchCallBack 回调
*/
fun initBarType(type: Int, mSearchCallback: SearchCallBack?) {
barType = type
common_search_bar_edit_text.clearFocus()
when (barType) {
//跳转时,设置输入框无法获取焦点
JUMP_TO_SEARCH_COURSE -> {
}
//设置输入框能获取焦点且设置回调
ENABLE_INPUT -> {
setSearchCallBack(mSearchCallback)
toggleKeyBoard(true)
setEditTextVisibility(true)
}
}
}
fun setTextVisibility() {
common_search_bar_btn.visibility = View.VISIBLE
}
private fun setEditTextVisibility(boolean: Boolean) {
if (boolean) {
common_search_bar_text.visibility = View.GONE
common_search_bar_edit_text.visibility = View.VISIBLE
common_search_bar_btn.visibility = View.VISIBLE
common_search_bar_edit_text.setOnEditorActionListener { v, actionId, event ->
searchCallBack?.clickSearchBtn(common_search_bar_edit_text.text.toString())
toggleKeyBoard(false)
true
}
common_search_bar_btn.setOnClickListener {
toggleKeyBoard(false)
searchCallBack?.cloase()
}
iv_delete_icon.setOnClickListener {
common_search_bar_edit_text.setText("")
}
common_search_bar_edit_text.addTextChangedListener(object : TextWatcher {
override fun afterTextChanged(s: Editable?) {
if (!TextUtils.isEmpty(s)) {
iv_delete_icon.visibility = View.VISIBLE
} else {
iv_delete_icon.visibility = View.GONE
}
}
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
}
})
}
}
fun setText(content: String) {
common_search_bar_edit_text.setText(content, TextView.BufferType.EDITABLE)
if (!TextUtils.isEmpty(content)) {
iv_delete_icon.visibility = View.VISIBLE
}
}
fun toggleKeyBoard(type: Boolean) {
if (common_search_bar_edit_text.requestFocus()) {
val imm = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
if (type) {
imm.showSoftInput(common_search_bar_edit_text, InputMethodManager.SHOW_IMPLICIT)
} else imm.hideSoftInputFromWindow(common_search_bar_edit_text.windowToken, 0)
}
}
fun setSearchCallBack(mSearchCallback: SearchCallBack?) {
searchCallBack = mSearchCallback
}
interface SearchCallBack {
fun clickSearchBtn(str: String) //设置监听(跳转逻辑已在组件内部实现,该方法主要用于回调点击键盘搜索按钮事件)
fun cloase()
}
}
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="false" android:drawable="@color/white"/>
<item android:state_pressed="true" android:drawable="@color/color_f0f0f0"/>
</selector>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners
android:radius="20dp"/>
<solid
android:color="@color/color_F7F7F7"/>
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal">
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/title_bar"
android:layout_width="0dp"
android:layout_height="@dimen/title_bar_height"
android:layout_weight="1"
android:background="@color/white">
<ImageView
android:id="@+id/iv_back"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:paddingLeft="15dp"
android:paddingRight="10dp"
android:src="@drawable/toolbar_back"/>
<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:text="心理课程"
android:textColor="@color/color_333333"
android:textSize="18sp"/>
<TextView
android:id="@+id/tv_left_menu"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginRight="15dp"
android:src="@drawable/toolbar_back"
android:text="我的课程"
android:textColor="@color/right_text_color"/>
</RelativeLayout>
</LinearLayout>
<com.yidianling.course.widget.SearchBarView
android:id="@+id/activity_course_search_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<FrameLayout
android:id="@+id/content"
android:layout_width="match_parent"
android:layout_height="0px"
android:layout_weight="1"/>
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:background="@color/main_theme"
tools:parentTag="android.widget.LinearLayout">
<LinearLayout
android:layout_width="0dp"
android:layout_height="30dp"
android:layout_marginLeft="15dp"
android:layout_marginRight="15dp"
android:layout_weight="1"
android:background="@drawable/common_search_bar_back"
android:gravity="center"
android:paddingLeft="15dp"
android:paddingRight="15dp">
<ImageView
android:id="@+id/common_search_bar_img"
android:layout_width="@dimen/dp_12"
android:layout_height="@dimen/dp_12"
android:src="@drawable/ico_search"/>
<TextView
android:id="@+id/common_search_bar_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:text="搜索课程标题或专家姓名"
android:textColor="@color/color_999999"
android:textSize="12dp"/>
<EditText
android:id="@+id/common_search_bar_edit_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:background="@null"
android:layout_weight="1"
android:focusable="true"
android:focusableInTouchMode="true"
android:hint="搜索课程标题或专家姓名"
android:imeOptions="actionSearch"
android:singleLine="true"
android:textColor="@color/color_242424"
android:textColorHint="@color/color_999999"
android:textSize="12dp"
android:visibility="gone"
/>
<ImageView
android:id="@+id/iv_delete_icon"
android:layout_width="14dp"
android:layout_height="14dp"
android:scaleType="centerCrop"
android:src="@drawable/delete"
android:visibility="gone"/>
</LinearLayout>
<TextView
android:id="@+id/common_search_bar_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="15dp"
android:text="取消"
android:textColor="@color/color_242424"
android:visibility="gone"/>
</merge>
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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:background="@drawable/bg_item_course_list"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/iv_head"
android:layout_width="145dp"
android:layout_height="80dp"
android:contentDescription="@null"
android:scaleType="fitXY"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0"
android:layout_marginTop="20dp"
android:layout_marginBottom="20dp"
android:layout_marginLeft="15dp"
app:srcCompat="@color/color_EBEBEB"/>
<TextView
android:id="@+id/tv_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="15dp"
android:layout_marginStart="15dp"
android:layout_marginTop="22dp"
android:layout_marginRight="15dp"
android:layout_marginEnd="15dp"
android:ellipsize="end"
android:maxLines="2"
android:text="标题"
android:textColor="@color/color_333333"
android:textSize="16sp"
android:textStyle="bold"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintLeft_toRightOf="@+id/iv_head"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<TextView
android:id="@+id/tv_courseNumContent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="1dp"
android:layout_marginLeft="15dp"
android:layout_marginStart="15dp"
tools:text="共21节课程"
android:textColor="@color/color_666666"
android:textSize="14sp"
app:layout_constraintBottom_toBottomOf="@+id/iv_head"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintLeft_toRightOf="@+id/iv_head"
app:layout_constraintRight_toRightOf="parent"/>
<View
android:id="@+id/divider_line"
android:layout_width="match_parent"
android:layout_height="0.5dp"
android:background="@color/color_f0f0f0"
android:layout_marginLeft="15dp"
android:layout_marginRight="15dp"
app:layout_constraintTop_toBottomOf="parent"/>
</android.support.constraint.ConstraintLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white">
<include
android:id="@+id/v_no_network"
layout="@layout/view_no_network"
android:visibility="gone"/>
<android.support.v4.widget.SwipeRefreshLayout
android:id="@+id/swipelayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<include layout="@layout/layout_title_bar"/>
<android.support.v7.widget.RecyclerView
android:id="@+id/rv_list"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
</android.support.v4.widget.SwipeRefreshLayout>
</FrameLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/title_bar"
android:layout_width="match_parent"
android:layout_height="@dimen/title_bar_height"
android:background="@color/white">
<ImageView
android:id="@+id/iv_back"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:paddingLeft="15dp"
android:paddingRight="10dp"
android:src="@drawable/toolbar_back" />
<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:textColor="@color/color_333333"
android:textSize="18sp" />
<TextView
android:id="@+id/tv_left_menu"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginRight="15dp"
android:textColor="@color/main_theme" />
</RelativeLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/white">
<ImageView
android:id="@+id/iv_network"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/no_net"
android:layout_centerInParent="true"/>
<TextView
android:id="@+id/tv_network_content"
android:layout_below="@+id/iv_network"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="14dp"
android:text="@string/no_network"
android:layout_gravity="center_horizontal"
android:textColor="#b2b2b2"/>
</RelativeLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools">
<color name="color_F7F7F7" tools:ignore="MissingDefaultResource">#F7F7F7</color>
<color name="color_999999">#999999</color>
<color name="color_242424">#242424</color>
<color name="color_333333">#333333</color>
<color name="color_f0f0f0">#f0f0f0</color>
<color name="color_666666">#f666666</color>
<color name="color_EBEBEB">#EBEBEB</color>
</resources>
\ No newline at end of file
<resources>
<string name="app_name">m_course</string>
<string name="no_network">网络不给力哦,下拉刷新重试</string>
<string name="course_special_list_title">专题课程</string>
</resources>
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!--主题色-->
<color name="main_theme">#fdbd00</color>
<!--主题浅色-->
<color name="main_theme_light">#FFEC8C</color>
<!--主题亮色-->
<color name="main_theme_bright">#fffae0</color>
<color name="right_text_color">#34cd65</color>
</resources>
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!--主题色-->
<color name="main_theme">#1da1f2</color>
<!--主题浅色-->
<color name="main_theme_light">#60BDF5</color>
<!--主题亮色-->
<color name="main_theme_bright">#E8F6FF</color>
<color name="right_text_color">#1da1f2</color>
</resources>
include ':app',":router", ':ydl-net', ':ydl-utils', ':ydl-platform', ':ydl-webview', ':ydl-media',":m-user", ':m-consultant'
include ':app', ':m-course',":router", ':ydl-net', ':ydl-utils', ':ydl-platform', ':ydl-webview', ':ydl-media',":m-user", ':m-consultant'
//, ':m-tests'
\ No newline at end of file
package com.yidianling.ydlcommon.flutter.base
import android.content.Context
import android.content.Intent
import android.graphics.PixelFormat
import android.os.Bundle
import android.util.AttributeSet
import android.view.WindowManager
import io.flutter.app.FlutterActivity
import io.flutter.plugins.GeneratedPluginRegistrant
import io.flutter.view.FlutterView
import org.json.JSONObject
/**
* flutter 页面基类
* Created by xj on 2019/9/30.
*/
abstract class BaseFlutterActivity : FlutterActivity() {
companion object {
const val ROUTE_PAGE = "route" //路由
/**
* 路由传递过来的参数
*/
const val ROUTER_PARAMS = "routerParam"
}
override fun createFlutterView(context: Context?): FlutterView {
val matchParent = WindowManager.LayoutParams(-1, -1)
val nativeView = this.createFlutterNativeView()
val flutterView = FlutterView(this, null as AttributeSet?, nativeView)
flutterView.layoutParams = matchParent
this.setContentView(flutterView)
//这个action必加,不然无法在flutter端获取route参数值
intent.action = Intent.ACTION_RUN
/**
* 在这边初始化route
*/
intent.putExtra(ROUTE_PAGE, initialRoute())
//渲染优化(优化一丢丢几乎看不出来)
flutterView.setZOrderOnTop(true)
flutterView.holder.setFormat(PixelFormat.TRANSLUCENT)
return flutterView
}
public override fun onCreate( savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
GeneratedPluginRegistrant.registerWith(this)
/**
* 获取统一路由传递过来的参数并初始化交互通道
*/
val json = intent.getStringExtra(ROUTER_PARAMS)
initChannelPlugin(JSONObject(json))
}
/**
* 路由,例 "/native/muse/home"
*/
abstract fun initialRoute(): String
/**
* 初始化flutter channel插件
*/
abstract fun initChannelPlugin(jsonObject: JSONObject)
}
\ No newline at end of file
package com.yidianling.ydlcommon.flutter.base
import io.flutter.app.FlutterActivity
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
/**
* 公共通道插件类
* Created by xj on 2019/9/30.
*/
class BaseFlutterChannelPlugin: MethodChannel.MethodCallHandler {
companion object {
const val CHANNEL: String = "lib/common/channel"
const val ACTION_GET_APPINFO_INITIAL_DATA = "action_get_initial_app_info_data" //获取主包信息的数据
fun rigister(activity: FlutterActivity) {
MethodChannel(activity.flutterView, CHANNEL).setMethodCallHandler(BaseFlutterChannelPlugin(activity))
}
}
private var mActivity: FlutterActivity? = null
private constructor(activity: FlutterActivity) {
mActivity = activity
}
override fun onMethodCall(methodCall: MethodCall, result: MethodChannel.Result) {
methodCall?.let {
when (methodCall.method) {
// 获取主包信息的数据
//todo xujian 组件化之后完善
// ACTION_GET_APPINFO_INITIAL_DATA -> {
// val mRequestMap = mutableMapOf(
// "isDevelopment" to (BuildConfig.FLUTTER_API != "prod"),
// "uid" to ,
// "accessToken" to LoginHelper.getInstance().user.accessToken,
// "version" to RxAppTool.getAppVersionName(mActivity?.applicationContext),
// "isFromApp" to "1",
// "osBuild" to RxDeviceTool.getBuildBrandModel() + "," + RxDeviceTool.getSDKVersionName() + "," + RxAppTool.getAppVersionName(mActivity?.applicationContext)
// )
// }
}
}
}
}
\ No newline at end of file
package com.yidianling.ydlcommon.flutter.base
import android.os.Bundle
import android.view.LayoutInflater
import android.view.ViewGroup
import com.ydl.ydlcommon.flutter.io.flutter.facade.Flutter
import com.ydl.ydlcommon.flutter.io.flutter.facade.FlutterFragment
import io.flutter.view.FlutterView
/**
* flutter fragment 基类
* Created by xj on 2019/9/30.
*/
abstract class BaseFlutterFragment : FlutterFragment() {
private var mFlutterView: FlutterView? = null
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): FlutterView {
mFlutterView= Flutter.createView(
activity!!,
lifecycle,
initialRoute())
initChannelPlugin(mFlutterView!!)
return mFlutterView!!
}
/**
* 路由,例 "quick_reply"
*/
abstract fun initialRoute(): String
/**
* 初始化flutter channel插件
*/
abstract fun initChannelPlugin(flutterView: FlutterView)
}
package com.ydl.ydlcommon.flutter.io.flutter.facade;
import android.app.Activity;
import android.arch.lifecycle.Lifecycle;
import android.arch.lifecycle.LifecycleObserver;
import android.arch.lifecycle.OnLifecycleEvent;
import android.content.Context;
import android.os.Bundle;
import android.support.annotation.NonNull;
import io.flutter.plugin.common.BasicMessageChannel;
import io.flutter.plugin.common.StringCodec;
import io.flutter.plugins.GeneratedPluginRegistrant;
import io.flutter.view.FlutterMain;
import io.flutter.view.FlutterNativeView;
import io.flutter.view.FlutterRunArguments;
import io.flutter.view.FlutterView;
/**
* Main entry point for using Flutter in Android applications.
*
* <p><strong>Warning:</strong> This file is auto-generated by Flutter tooling.
* DO NOT EDIT.</p>
*/
public final class Flutter {
private Flutter() {
// to prevent instantiation
}
/**
* Initiates the Dart VM. Calling this method at an early point may help decreasing time to first
* frame for a subsequently created {@link FlutterView}.
*
* @param applicationContext the application's {@link Context}
*/
public static void startInitialization(@NonNull Context applicationContext) {
FlutterMain.startInitialization(applicationContext);
}
/**
* Creates a {@link FlutterFragment} managing a {@link FlutterView}. The optional
* initial route string will be made available to the Dart code
* (via {@code window.defaultRouteName}) and may be used to determine which widget
* should be displayed in the view. The default initialRoute is "/".
*
* @param initialRoute an initial route {@link String}, or null
* @return a {@link FlutterFragment}
*/
@NonNull
public static FlutterFragment createFragment(String initialRoute) {
final FlutterFragment fragment = new FlutterFragment();
final Bundle args = new Bundle();
args.putString(FlutterFragment.ARG_ROUTE, initialRoute);
fragment.setArguments(args);
return fragment;
}
/**
* Creates a {@link FlutterView} linked to the specified {@link Activity} and {@link Lifecycle}.
* The optional initial route string will be made available to the Dart code (via
* {@code window.defaultRouteName}) and may be used to determine which widget should be displayed
* in the view. The default initialRoute is "/".
*
* @param activity an {@link Activity}
* @param lifecycle a {@link Lifecycle}
* @param initialRoute an initial route {@link String}, or null
* @return a {@link FlutterView}
*/
@NonNull
public static FlutterView createView(@NonNull final Activity activity, @NonNull final Lifecycle lifecycle, final String initialRoute) {
FlutterMain.startInitialization(activity.getApplicationContext());
FlutterMain.ensureInitializationComplete(activity.getApplicationContext(), null);
final FlutterNativeView nativeView = new FlutterNativeView(activity);
final FlutterView flutterView = new FlutterView(activity, null, nativeView) {
private final BasicMessageChannel<String> lifecycleMessages = new BasicMessageChannel<>(this, "flutter/lifecycle", StringCodec.INSTANCE);
@Override
public void onFirstFrame() {
super.onFirstFrame();
setAlpha(1.0f);
}
@Override
public void onPostResume() {
// Overriding default behavior to avoid dictating system UI via PlatformPlugin.
lifecycleMessages.send("AppLifecycleState.resumed");
}
};
if (initialRoute != null) {
flutterView.setInitialRoute(initialRoute);
}
lifecycle.addObserver(new LifecycleObserver() {
@OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
public void onCreate() {
final FlutterRunArguments arguments = new FlutterRunArguments();
arguments.bundlePath = FlutterMain.findAppBundlePath(activity.getApplicationContext());
arguments.entrypoint = "main";
flutterView.runFromBundle(arguments);
GeneratedPluginRegistrant.registerWith(flutterView.getPluginRegistry());
}
@OnLifecycleEvent(Lifecycle.Event.ON_START)
public void onStart() {
flutterView.onStart();
}
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
public void onResume() {
flutterView.onPostResume();
}
@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
public void onPause() {
flutterView.onPause();
}
@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
public void onStop() {
flutterView.onStop();
}
@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
public void onDestroy() {
flutterView.destroy();
}
});
flutterView.setAlpha(0.0f);
return flutterView;
}
}
package com.ydl.ydlcommon.flutter.io.flutter.facade;
import android.content.Context;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.Fragment;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import io.flutter.view.FlutterView;
/**
* A {@link Fragment} managing a {@link FlutterView}.
*
* <p><strong>Warning:</strong> This file is auto-generated by Flutter tooling.
* DO NOT EDIT.</p>
*/
public class FlutterFragment extends Fragment {
public static final String ARG_ROUTE = "route";
private String mRoute = "/";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mRoute = getArguments().getString(ARG_ROUTE);
}
}
@Override
public void onInflate(Context context, AttributeSet attrs, Bundle savedInstanceState) {
super.onInflate(context, attrs, savedInstanceState);
}
@Override
public FlutterView onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return Flutter.createView(getActivity(), getLifecycle(), mRoute);
}
}
......@@ -7,30 +7,12 @@ import com.ydl.ydlcommon.base.config.YDLConstants
/**
* Created by xj on 2019/7/1.
*/
class BIConstants{
class BIConstants {
companion object {
/**
* 消息端来源
* ydl:ydl-app-android-user
* xlzx:ydl-app-android-xlzx
*/
var APP_ID:String = ""
get() {
return "ydl-app-android-"+ (if (BaseApp.instance.getGlobalConfig().appFrom== YDLConstants.FROM_XLZX)"xlzx" else "user")
}
var APP_NAME:String = ""
get() {
return if (BaseApp.instance.getGlobalConfig().appFrom== YDLConstants.FROM_XLZX)"心理咨询" else "壹点灵心理咨询"
}
var PACKAGE_NAME:String = ""
get() {
return if (BaseApp.instance.getGlobalConfig().appFrom== YDLConstants.FROM_XLZX)"com.cxzapp.xinlizixun" else "com.cxzapp.yidianling"
}
const val APP_ID = "ydl-app-android-user" //这是用户端主包的
/**
* 操作系统
......@@ -47,5 +29,133 @@ class BIConstants{
const val WELCOME_PAGE = "welcome_page"
//百度监测 用户注册行为
const val APP_REGISTER_PAGE = "app_register_page"
/**
* position
* 点击类型
*/
const val POSITION_LOGIN_CLICK = "login_click" //登录点击
const val POSITION_LOGIN_SUCCESS_CLICK = "login_success_click" //登录成功点击
//咨询筛选页
const val POSITION_CONSULT_TYPE_CLICK = "consult_type_click" //咨询方式
const val POSITION_AVERAGE_SERVICE_INPUT = "average_service_input" //服务均价
const val POSITION_AGE_CHOICE_CLICK = "age_choice_click" //年龄选择
const val POSITION_QUALIFICATION_CHOICE_CLICK = "qualification_choice_click" //资质选择
const val POSITION_OTHER_CHOICE_CLICK = "other_choice_click" //其他选择
const val POSITION_CONSULT_FILTER_RESET_CLICK = "consult_filter_reset_click" //重置
const val POSITION_CONSULT_FILTER_CHECKOUT_CLICK = "consult_filter_checkoutallconsultants_click" //查看XXX位咨询师
//百度监测 应用启动
const val POSITION_APP_START_UP_CLICK = "app_start_up_click" //应用启动
//百度监测 用户注册
const val POSITION_WX_REGISTER_CLICK = "wx_register_click" //微信第一次登录
const val POSITION_QQ_REGISTER_CLICK = "qq_register_click" //QQ第一次登录
const val POSITION_PHONE_REGISTER_CLICK = "phone_register_click" //手机号密码第一次登录
const val POSITION_ALIYUN_REGISTER_CLICK = "aliyun_register_click" //阿里云第一次一键登录
const val POSITION_CODE_REGISTER_CLICK = "code_register_click" //短信第一次登录
//随便逛逛点击
const val POSITION_LOOK_AROUND_CLICK = "look_around_click"
//登录主页浏览事件(包含随便逛逛)
const val POSITION_LOGIN_ONE_PAGE_VISIT = "login_main_one_page_visit"
//登录主页浏览事件(不包含随便逛逛)
const val POSITION_LOGIN_TWO_PAGE_VISIT = "login_main_two_page_visit"
/**
* action type
* 行为数据埋点,sign1字段 是对同一key下多种不同行为的描述
*/
const val ACTION_TYPE_CODE_LOGIN: String = "code_login" //验证码登录
const val ACTION_TYPE_RESET_PWD: String = "reset_pwd" //重置密码登录
const val ACTION_TYPE_PWD_LOGIN: String = "pwd_login" //手机号密码登录
const val ACTION_TYPE_DIRECT_LOGIN: String = "direct_login" //一键登录
const val ACTION_TYPE_QQ_THIRD_LOGIN: String = "qq_login" //QQ登录
const val ACTION_TYPE_WX_THIRD_LOGIN: String = "wx_login" //WX登录
}
//====================壹点灵用户版首页(ydl_user_main_page)====================
class UserMainEvent {
companion object {
private const val YDL_USER_MAIN_PAGE: String = "ydl_user_main_page|"//壹点灵用户版首页 partId
const val YDL_USER_SEARCH_CLICK: String = YDL_USER_MAIN_PAGE + "ydl_user_search_click"//搜索栏
const val YDL_USER_TELEPHONE_CUSTOMER_SERVICE_CLICK: String = YDL_USER_MAIN_PAGE + "ydl_user_telephone_customer_service_click"//电话客服
const val YDL_USER_BANNER_CLICK: String = YDL_USER_MAIN_PAGE + "ydl_user_banner_click"//banner
const val YDL_USER_NOTICE_CLICK: String = YDL_USER_MAIN_PAGE + "ydl_user_notice_click"//公告
const val YDL_USER_CONSULT_CLASSIFICATION_CLICK: String = YDL_USER_MAIN_PAGE + "ydl_user_consult_classification_click"//首页咨询分类
const val YDL_USER_CONSULT_CLICK: String = YDL_USER_MAIN_PAGE + "ydl_user_consult_click"//四个大按钮 心理咨询点击人数
const val YDL_USER_TALK_IN_TIME_CLICK: String = YDL_USER_MAIN_PAGE + "ydl_user_talk_in_time_click"//四个大按钮 即时倾诉点击人数
const val YDL_USER_PSYCHOLOGICAL_CLASSROOM_CLICK: String = YDL_USER_MAIN_PAGE + "ydl_user_psychological_classroom_click"//四个大按钮 心理课堂点击人数
const val YDL_USER_PSYCHOLOGICAL_TEST_CLICK: String = YDL_USER_MAIN_PAGE + "ydl_user_psychological_test_click"//四个大按钮 心理测试点击人数
const val YDL_USER_CONSULT_MORE_CLICK: String = YDL_USER_MAIN_PAGE + "ydl_user_consult_more_click"//咨询解惑更多
const val YDL_USER_CONSULT_TYPE_CLICK: String = YDL_USER_MAIN_PAGE + "ydl_user_consult_type_click"//咨询解惑分类标签
const val YDL_USER_EXPERT_INTRODUCTION_CLICK: String = YDL_USER_MAIN_PAGE + "ydl_user_expert_introduction_click"//咨询师介绍模块
const val YDL_USER_PRIVATE_CHAT_CLICK: String = YDL_USER_MAIN_PAGE + "ydl_user_private_chat_click"//咨询师私聊按钮
const val YDL_USER_LISTEN_MORE_CLICK: String = YDL_USER_MAIN_PAGE + "ydl_user_listen_more_click"//倾诉排解更多
const val YDL_USER_LISTEN_TYPE_CLICK: String = YDL_USER_MAIN_PAGE + "ydl_user_listen_type_click"//倾诉排解分类标签
const val YDL_USER_LISTENER_INTRODUCTION_CLICK: String = YDL_USER_MAIN_PAGE + "ydl_user_listener_introduction_click "//倾诉师介绍模块
const val YDL_USER_COURSE_MORE_CLICK: String = YDL_USER_MAIN_PAGE + "ydl_user_course_more_click"//课程成长更多
const val YDL_USER_COURSE_CLICK: String = YDL_USER_MAIN_PAGE + "ydl_user_course_click"//课程标题图区域
const val YDL_USER_ASK_MORE_CLICK: String = YDL_USER_MAIN_PAGE + "ydl_user_ask_more_click"//解忧问答更多
const val YDL_USER_ASK_COMMENT_CLICK: String = YDL_USER_MAIN_PAGE + "ydl_user_ask_comment_click"//问答评论区域
const val YDL_USER_HEART_RADIO_MORE_CLICK: String = YDL_USER_MAIN_PAGE + "ydl_user_heart_radio_more_click"//心灵电台更多
const val YDL_USER_RADIO_CLICK: String = YDL_USER_MAIN_PAGE + "ydl_user_radio_click "//区域内四个标题
const val YDL_USER_RADIO_PLAY_CLICK: String = YDL_USER_MAIN_PAGE + "ydl_user_radio_play_click"//心灵电台play按钮点击
const val YDL_USER_ARTICLE_MORE_CLICK: String = YDL_USER_MAIN_PAGE + "ydl_user_article_more_click"//文章阅读更多
const val YDL_USER_ARTICLE_CLICK: String = YDL_USER_MAIN_PAGE + "ydl_user_article_click"//文章标题图区域
const val YDL_USER_MAIN_PAGE_VISIT: String = YDL_USER_MAIN_PAGE + "ydl_user_main_page_visit "//首页浏览事件
}
}
//====================APP咨询列表页(app_consult_list_page)====================
class ConsultEvent {
companion object {
private const val APP_CONSULT_LIST_PAGE: String = "app_consult_list_page|"//APP咨询列表页 partId
const val APP_CONSULT_LIST_PAGE_VISIT: String = APP_CONSULT_LIST_PAGE + "app_consult_list_page_visit"//列表页浏览事件
const val APP_CONSULT_LIST_CONSULT_GUIDE_CLICK: String = APP_CONSULT_LIST_PAGE + "app_consult_list_consult_guide_click "//咨询指南
const val APP_CONSULT_LIST_ONLINE_CUSTOMER_CLICK: String = APP_CONSULT_LIST_PAGE + "app_consult_list_online_customer_click"//在线客服
const val APP_CONSULT_LIST_THEME_CLICK: String = APP_CONSULT_LIST_PAGE + "app_consult_list_theme_click "//主题全部
const val APP_CONSULT_LIST_AREA_CLICK: String = APP_CONSULT_LIST_PAGE + "app_consult_list_area_click"//地区各个地区
const val APP_CONSULT_LIST_SORT_CLICK: String = APP_CONSULT_LIST_PAGE + "app_consult_list_sort_click"//排序综合排序
const val APP_CONSULT_LIST_DOCTOR_CLICK: String = APP_CONSULT_LIST_PAGE + "app_consult_list_doctor_click"//每个咨询师页面点击
const val APP_CONSULT_LIST_CHAT_CLICK: String = APP_CONSULT_LIST_PAGE + "app_consult_list_chat_click"//每个咨询师私聊
}
}
//====================课程列表页(course_list_page)====================
class CourseListEvent {
companion object {
private const val COURSE_LIST_PAGE: String = "course_list_page|"//课程列表页 partId
const val POSITION_COURSE_LIST_RETURN_CLICK = COURSE_LIST_PAGE + "course_list_return_click" //返回点击
const val POSITION_COURSE_LIST_SORT_CLICK = COURSE_LIST_PAGE + "course_list_sort_click" //综合排序点击
const val POSITION_COURSE_LIST_FILTER_CLICK = COURSE_LIST_PAGE + "course_list_filter_click" //筛选点击
const val POSITION_COURSE_LIST_CLASSIFICATION_CLICK = COURSE_LIST_PAGE + "course_list_classification_click" //分类点击
const val POSITION_COURSE_LIST_AUDITION_CLICK = COURSE_LIST_PAGE + "course_list_audition_click" //试听点击
const val POSITION_COURSE_LIST_PAGE_VISIT = COURSE_LIST_PAGE + "course_list_page_visit" //课程列表页浏览点击
const val POSITION_COURSE_LIST_XXX_CLICK = COURSE_LIST_PAGE + "course_list_" //课程点击
}
}
//====================课程频道页(course_home_page)====================
class CourseHomeEvent {
companion object {
private const val COURSE_HOME_PAGE: String = "course_home_page|"//课程频道页 partId
const val POSITION_COURSE_HOME_PAGE_VISIT = COURSE_HOME_PAGE + "course_home_page_visit" //列表页浏览点击
const val POSITION_COURSE_HOME_MY_COUSE_CLICK = COURSE_HOME_PAGE + "course_home_my_couse_click" //我的课程
const val POSITION_COURSE_HOME_SEACH_CLICK = COURSE_HOME_PAGE + "course_home_seach_click" //搜索
const val POSITION_COURSE_HOME_BANNER_CLICK = COURSE_HOME_PAGE + "course_home_banner_click" //banner-各位置
const val POSITION_COURSE_HOME_CLASSIFICATION_CLICK = COURSE_HOME_PAGE + "course_home_classification_click" //分类点击
const val POSITION_COURSE_HOME_EXCELLENT_COURSES_PAY_XXX_CLICK = COURSE_HOME_PAGE + "course_home_excellent_courses_pay_" //精品课程-付费课程-各课程页面点击
const val POSITION_COURSE_HOME_EXCELLENT_COURSES_FREE_XXX_CLICK = COURSE_HOME_PAGE + "course_home_excellent_courses_free_" //精品课程-免费课程-各课程页面点击
const val POSITION_COURSE_HOME_EXCELLENT_COURSES_MORE_CLICK = COURSE_HOME_PAGE + "course_home_excellent_courses_more_click" //精品课程-更多课程
const val POSITION_COURSE_HOME_CONSULTANT_COURSE_MORE_CLICK = COURSE_HOME_PAGE + "course_home_consultant_course_more_click" //咨询师课程-更多课程
const val POSITION_COURSE_HOME_OFFLINE_CERTIFICATION_TRAINING_XXX_CLICK = COURSE_HOME_PAGE + "course_home_offline_certification_training_" //线下考证培训-各课程页面点击
const val POSITION_COURSE_HOME_OFFLINE_CERTIFICATION_TRAINING_MORE_CLICK = COURSE_HOME_PAGE + "course_home_offline_certification_training_more_click" //线下考证培训-更多课程
const val POSITION_COURSE_HOME_THEMATIC_COURSES_XXX_CLICK = COURSE_HOME_PAGE + "course_home_thematic_courses_" //专题课程-各课程页面点击
const val POSITION_COURSE_HOME_THEMATIC_COURSES_MORE_CLICK = COURSE_HOME_PAGE + "course_home_thematic_courses_more_click" //专题课程-更多
}
}
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment