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.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.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;//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.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.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
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