Commit 878ea97f by konghaorui

补充 PlayerFloatView

parent 6566127c
......@@ -12,10 +12,12 @@ import android.provider.Settings
import android.util.Log
import com.alibaba.android.arouter.launcher.ARouter
import com.tbruyelle.rxpermissions2.RxPermissions
import com.umeng.analytics.MobclickAgent
import com.ydl.component.music.MusicPlayActivity
import com.ydl.component.mvp.DemoContract
import com.ydl.component.mvp.DemoPresenter
import com.ydl.media.music.PlayService
import com.ydl.media.audio.PlayService
import com.ydl.media.view.PlayerFloatHelper
import com.ydl.ydlcommon.mvp.lce.BaseLceActivity
import com.yidianling.common.tools.ToastUtil
import com.yidianling.consultant.ExpertSearchActivity.Companion.HOT_SEARCH_DOCTOR_NAME
......@@ -110,6 +112,12 @@ class MainActivity : BaseLceActivity<DemoContract.View, DemoContract.Presenter>(
bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE)
}
override fun onResume() {
super.onResume()
MobclickAgent.onResume(this)
}
override fun onDestroy() {
if (serviceConnection != null) {
unbindService(serviceConnection)
......
......@@ -5,7 +5,7 @@ import android.app.Application;
import android.content.Context;
import android.content.Intent;
import com.ydl.media.music.PlayService;
import com.ydl.media.audio.PlayService;
import com.ydl.ydlcommon.base.delegate.IAppLifecycles;
import com.ydl.ydlcommon.utils.YdlBuryPointUtil;
......
......@@ -13,13 +13,16 @@ import android.widget.SeekBar;
import android.widget.TextView;
import com.ydl.component.R;
import com.ydl.media.music.AudioPlayer;
import com.ydl.media.music.OnPlayerEventListener;
import com.ydl.media.music.enums.PlayModeEnum;
import com.ydl.media.music.model.Music;
import com.ydl.media.music.utils.CoverImageUtils;
import com.ydl.media.audio.AudioPlayer;
import com.ydl.media.audio.OnPlayerEventListener;
import com.ydl.media.audio.enums.PlayModeEnum;
import com.ydl.media.audio.model.Music;
import com.ydl.media.audio.utils.CoverImageUtils;
import com.ydl.media.view.PlayTypeEnum;
import com.ydl.media.view.PlayerFloatHelper;
import com.yidianling.common.tools.ToastUtil;
import java.util.HashMap;
import java.util.Locale;
import java.util.Objects;
......@@ -151,6 +154,11 @@ public class PlayFragment extends Fragment implements View.OnClickListener,
break;
case R.id.iv_play:
play();
if(PlayerFloatHelper.Companion.isShow(getActivity())) {
PlayerFloatHelper.Companion.show(getActivity(), PlayTypeEnum.PLAY_TYPE_FM,new HashMap<>());
}else {
PlayerFloatHelper.Companion.showIfPlaying(getActivity());
}
break;
case R.id.iv_next:
next();
......@@ -271,6 +279,7 @@ public class PlayFragment extends Fragment implements View.OnClickListener,
@Override
public void onDestroy() {
AudioPlayer.Companion.get().removeOnPlayEventListener(this);
PlayerFloatHelper.Companion.onDestroy();
super.onDestroy();
}
......@@ -279,4 +288,9 @@ public class PlayFragment extends Fragment implements View.OnClickListener,
sbProgress.setMax((int) duration);
tvTotalTime.setText(formatTime(duration));
}
@Override
public void onComplete() {
}
}
......@@ -3,11 +3,10 @@ package com.ydl.component.mvp
import com.google.gson.JsonArray
import com.google.gson.JsonObject
import com.ydl.component.model.HomeFMBean
import com.ydl.media.music.AudioPlayer
import com.ydl.media.music.model.Music
import com.ydl.media.audio.AudioPlayer
import com.ydl.media.audio.model.Music
import com.ydl.ydlcommon.data.http.RxUtils
import com.ydl.ydlcommon.mvp.base.BasePresenter
import com.ydl.ydlcommon.utils.RxLifecycleUtils
import com.ydl.ydlnet.builder.interceptor.YDLTransformer
import com.ydl.ydlnet.client.observer.CommonObserver
/**
......@@ -16,10 +15,10 @@ import com.ydl.ydlnet.client.observer.CommonObserver
*/
class DemoPresenter : BasePresenter<DemoContract.View,DemoContract.Model>(),
DemoContract.Presenter {
override fun loadFmMusic() {
mModel.getFmMusic()
.compose(YDLTransformer.switchSchedulers(mView))
.compose(RxLifecycleUtils.bindToLifecycle(mView))//使用 Rxlifecycle,使 Disposable 和 Activity 一起销毁
.compose(RxUtils.applySchedulers(mView))
.subscribe(object : CommonObserver<HomeFMBean>() {
override fun onError(errorMsg: String) {
}
......@@ -37,8 +36,7 @@ class DemoPresenter : BasePresenter<DemoContract.View,DemoContract.Model>(),
}
override fun loadHome() = mModel!!.getHome()
.compose(YDLTransformer.switchSchedulers(mView))
.compose(RxLifecycleUtils.bindToLifecycle(mView!!))//使用 Rxlifecycle,使 Disposable 和 Activity 一起销毁
.compose(RxUtils.applySchedulers(mView))
.subscribe(object : CommonObserver<JsonObject>() {
override fun onError(errorMsg: String) {
}
......@@ -50,8 +48,7 @@ class DemoPresenter : BasePresenter<DemoContract.View,DemoContract.Model>(),
})
override fun loadUsers() = mModel!!.getUser()
.compose(YDLTransformer.switchSchedulers(mView))
.compose(RxLifecycleUtils.bindToLifecycle(mView!!))//使用 Rxlifecycle,使 Disposable 和 Activity 一起销毁
.compose(RxUtils.applySchedulers(mView))//使用 Rxlifecycle,使 Disposable 和 Activity 一起销毁
.subscribe(object : CommonObserver<JsonArray>() {
override fun onError(errorMsg: String) {
}
......
......@@ -56,6 +56,7 @@ buildscript {
classpath 'com.tencent.mm:AndResGuard-gradle-plugin:1.2.16'
classpath 'com.ydl.plugins:modular:1.0.0'
classpath 'com.ydl:notracepoint-gradle-plugin:0.0.3'
classpath 'com.github.better.restools:ResTools:1.0.1'
}
}
......
modular {
//模块包名
packageName "com.yidianling.consultant"
// 模块发布需要的参数
publish {
modules {
xlzx {
//发布信息 module/api 通用
groupId = "com.ydl"
artifactId = "m-consultant-module-xlzx"
// 上报的业务模块 aar 包的版本号
// 上报的 心理咨询 业务模块 aar 包的版本号
version = "0.0.11"
}
ydl{
//发布信息 module/api 通用
groupId = "com.ydl"
artifactId = "m-consultant-module-ydl"
// 上报的业务模块 aar 包的版本号
// 上报的 壹点灵 业务模块 aar 包的版本号
version = "0.0.11"
}
}
api {
//发布信息 module/api 通用
// 壹点灵/心理咨询 业务模块 API层 jar包的发布信息
groupId = "com.ydl"
artifactId = "m-consultant-api"
// version = "0.0.1"
//开发时注释掉版本号,发布api时打开
//version = "0.0.1"
// API 层打包时需要引入的依赖
apiDependencies {
implementation "com.google.code.gson:gson:2.8.2"
......
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'
//apply plugin: 'plugin.resTools' // 资源重命名插件
// 配置插件dsl
//resConfig {
// new_prefix = 'tests_' // 资源前缀
// old_prefix = '' // 老前缀,可为''空字符串
// // === below use default
// // resFolderPath 资源目录
// // srcFolderPath 源代码目录
// // manifestFilePath 清单文件目录
//}
kapt {
arguments {
arg("AROUTER_MODULE_NAME", project.getName())
}
}
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"
multiDexEnabled true
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
flavorDimensions "versionCode"
}
lintOptions {
abortOnError false
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
//前缀的名字
resourcePrefix "tests_"
//Flavor 信息
publishNonDefault true
productFlavors {
ydl {}
xlzx {}
}
sourceSets {
main {
res.srcDirs = [
'src/main/res/layouts/testhome',
'src/main/res/layouts',
'src/main/res'
]
}
}
}
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.1'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"
implementation 'com.google.code.gson:gson:2.8.2'
implementation "com.alibaba:arouter-api:$arouter_api"
// 注意此处的依赖方式:kotlin中使用和java中使用方式有不同
kapt "com.alibaba:arouter-compiler:$arouter_compiler"
api rootProject.ext.dependencies["ydl-user-router"]
if (rootProject.ext.dev_mode){
//开发时使用
api project(':ydl-webview')
api project(':ydl-platform')
implementation modularPublication('com.ydl:m-test-api')
}else {
//发布时使用
compileOnly rootProject.ext.dependencies["ydl-m-test-api"]
api rootProject.ext.dependencies["ydl-webview"]
api(rootProject.ext.dependencies["ydl-platform"]) {
transitive = true
}
}
}
\ No newline at end of file
modular {
//模块包名
packageName "com.yidianling.tests"
// 模块发布需要的参数
publish {
modules {
xlzx {
groupId = "com.ydl"
artifactId = "m-tests-module-xlzx"
// 上报的 心理咨询 业务模块 aar 包的版本号
version = "0.0.1"
}
ydl{
groupId = "com.ydl"
artifactId = "m-tests-module-ydl"
// 上报的 壹点灵 业务模块 aar 包的版本号
version = "0.0.1"
}
}
api {
//壹点灵/心理咨询 业务模块 API层 jar包的发布信息
groupId = "com.ydl"
artifactId = "m-tests-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'
implementation 'de.greenrobot:eventbus:2.4.0'
}
}
}
}
\ 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
package com.yidianling.tests;
import android.content.Context;
import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.junit.Assert.*;
/**
* Instrumented test, which will execute on an Android device.
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {
@Test
public void useAppContext() throws Exception {
// Context of the app under test.
Context appContext = InstrumentationRegistry.getTargetContext();
assertEquals("com.yidianling.tests.test", appContext.getPackageName());
}
}
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.yidianling.tests">
<application>
<activity
android:name=".list.view.TestListActivity"
android:screenOrientation="portrait" />
<activity
android:name=".list.view.TestCategoryListActivity"
android:screenOrientation="portrait"
android:theme="@style/NoTitleTheme"
/>
<activity
android:name=".answer.TestAnswerActivity"
android:screenOrientation="portrait" />
<activity
android:name=".detail.TestDetailActivity"
android:screenOrientation="portrait" />
<!-- 跳转测评详情 中间页面-->
<activity
android:name=".detail.jump.JumpTestDetailActivity"
android:screenOrientation="portrait"
android:theme="@style/Transparent" />
<activity
android:name=".SelectConversationActivity"
android:screenOrientation="portrait" />
<activity
android:name=".result.TestResultActivity"
android:screenOrientation="portrait" />
<activity
android:name=".search.TestSearchActivity"
android:screenOrientation="portrait"
android:theme="@style/NoTitleTheme"
/>
<!--测评首页-->
<activity
android:name=".home.TestHomeActivity"
android:screenOrientation="portrait" />
<!--跳转测试结果 中间页-->
<activity
android:name=".result.jump.JumpTestResultActivity"
android:screenOrientation="portrait"
android:theme="@style/Transparent" />
</application>
</manifest>
[{
"type": 8,
"body": [{
"bannerId": "139",
"bannerTitle": "职场晋升攻略",
"bannerImageUrl": "https://img.ydlcdn.com/file/2019/05/30/a3b3deb3dd86863543fdeec2c6d5fb27.png",
"bannerLinkUrl": "https://l.yidianling.com/p/q/zhiyeceshi"
}, {
"bannerId": "141",
"bannerTitle": "1",
"bannerImageUrl": "https://img.ydlcdn.com/file/2019/07/06/f58801c8b1eaa24b3ae0240d5fd12207.png",
"bannerLinkUrl": "https://m.ydl.com/fm/detail/621"
}, {
"bannerId": "142",
"bannerTitle": "测试6",
"bannerImageUrl": "https://img.ydlcdn.com/file/2019/01/31/fac496e80260bdcb467f2d977fe33b30.png",
"bannerLinkUrl": "app://ceshi/detail?id=1126"
}],
"diviLine": 0
}, {
"type": 9,
"category": [{
"categoryId": "138",
"categoryName": "付费",
"categoryUrl": "https://img.ydlcdn.com/file/2018/08/07/a469ac45d2192c30bcbc6ac816bcf0ac.png",
"categoryTab": "fufei",
"resource_id": "4"
}, {
"categoryId": "150",
"categoryName": "健康",
"categoryUrl": "https://img.ydlcdn.com/file/2018/08/07/18cbb18c442e19be56d2020fa40a8c6f.png",
"categoryTab": "jiankang",
"resource_id": "5"
}, {
"categoryId": "151",
"categoryName": "人际",
"categoryUrl": "https://img.ydlcdn.com/file/2018/08/07/5797be59bfc3cd4afa96150256a862de.png",
"categoryTab": "renji",
"resource_id": "3"
}, {
"categoryId": "149",
"categoryName": "情感",
"categoryUrl": "https://img.ydlcdn.com/file/2018/08/07/b2674db35ffb3377f3dc50dc306fa8a2.png",
"categoryTab": "aiqing",
"resource_id": "8"
}, {
"categoryId": "152",
"categoryName": "能力",
"categoryUrl": "https://img.ydlcdn.com/file/2018/08/07/5769254ceeccc48ead361145b7bbc12e.png",
"categoryTab": "nengli",
"resource_id": "9"
}, {
"categoryId": "148",
"categoryName": "性格",
"categoryUrl": "https://img.ydlcdn.com/file/2018/08/07/d653613684ad9ad5660f677b00a5f464.png",
"categoryTab": "xingge",
"resource_id": "1"
}, {
"categoryId": "125",
"categoryName": "亲子",
"categoryUrl": "https://img.ydlcdn.com/file/2018/08/07/2eb3a7c55e9425cf6dca4e0156465e56.png",
"categoryTab": "qinzi",
"resource_id": "6"
}, {
"categoryId": "126",
"categoryName": "职业",
"categoryUrl": "https://img.ydlcdn.com/file/2018/08/07/75a72ee813e8dc2aa9a55138926273be.png",
"categoryTab": "zhiye",
"resource_id": "7"
}],
"body": [{
"realTestId": "9",
"realTestName": "爷**",
"realTestTitle": "简易版IQ测试",
"realTestIcon": "",
"realTestLinkUrl": "app://ceshi/detail?id=9"
}, {
"realTestId": "1381",
"realTestName": "妳**",
"realTestTitle": "伯恩斯抑郁症状况自查表",
"realTestIcon": "",
"realTestLinkUrl": "app://ceshi/detail?id=1381"
}, {
"realTestId": "1208",
"realTestName": "y**",
"realTestTitle": "测试你是否喜欢上他了",
"realTestIcon": "",
"realTestLinkUrl": "app://ceshi/detail?id=1208"
}, {
"realTestId": "1401",
"realTestName": "y**",
"realTestTitle": "汉密尔顿抑郁测试量表",
"realTestIcon": "",
"realTestLinkUrl": "app://ceshi/detail?id=1401"
}, {
"realTestId": "54",
"realTestName": "y**",
"realTestTitle": "测你的意志力为何薄弱?",
"realTestIcon": "",
"realTestLinkUrl": "app://ceshi/detail?id=54"
}],
"diviLine": 1
}, {
"type": 10,
"body": [{
"dailyId": 738,
"dailyTitle": "专业心理健康测评",
"dailyImageUrl": "https://img.ydlcdn.com/file/2018/10/12/vzfy4x4ar1t3rc3e.PNG",
"dailyContent": 120211,
"dailyLinkUrl": "app://ceshi/detail?id=738",
"isFree": 1,
"price": "9.90"
}, {
"dailyId": 1008,
"dailyTitle": "出轨倾向评估",
"dailyImageUrl": "https://img.ydlcdn.com/file/2018/10/25/g4pfpw8fczuradd7.jpg",
"dailyContent": 47252,
"dailyLinkUrl": "app://ceshi/detail?id=1008",
"isFree": 1,
"price": "9.90"
}, {
"dailyId": 735,
"dailyTitle": "职场生存力评估",
"dailyImageUrl": "https://img.ydlcdn.com/file/2018/08/28/a6riks8v6ihqpj61.PNG",
"dailyContent": 71551,
"dailyLinkUrl": "app://ceshi/detail?id=735",
"isFree": 1,
"price": "9.90"
}, {
"dailyId": 1119,
"dailyTitle": "产后抑郁症状评估",
"dailyImageUrl": "https://img.ydlcdn.com/file/2019/04/16/wlrnn3rjib55juu1.jpg",
"dailyContent": 89722,
"dailyLinkUrl": "app://ceshi/detail?id=1119",
"isFree": 1,
"price": "17.40"
}, {
"dailyId": 1124,
"dailyTitle": "自尊类型评估",
"dailyImageUrl": "https://img.ydlcdn.com/file/2019/01/11/j7gynij5pzioaofp.jpg",
"dailyContent": 45444,
"dailyLinkUrl": "app://ceshi/detail?id=1124",
"isFree": 1,
"price": "29.40"
}, {
"dailyId": 750,
"dailyTitle": "人生控制模式评估",
"dailyImageUrl": "https://img.ydlcdn.com/file/2019/01/11/7ht4kq9y6gid5pks.jpg",
"dailyContent": 31112,
"dailyLinkUrl": "app://ceshi/detail?id=750",
"isFree": 1,
"price": "16.00"
}],
"head": {
"title": "每日精选"
},
"diviLine": 1
}, {
"type": 11,
"body": [{
"recommendedId": "2237",
"recommendedTitle": "反社会人格倾向评估",
"recommendedContent": "弗洛伊德的冰山理论认为,人格系统由本我、自我和超我组成。其中具决定意义的绝大部分都淹没在意识水平之下,处于无意...",
"recommendedUrl": "https://img.ydlcdn.com/file/2019/06/22/cbztbhaus6bci2c9.jpg",
"recommendedPrice": "1.99元",
"recommendedNum": "353225",
"recommendedHits": "1706",
"recommendedLinkUrl": "app://ceshi/detail?id=2237",
"isFree": 1,
"price": "1.99"
}, {
"recommendedId": "1126",
"recommendedTitle": "国际标准抑郁症测试",
"recommendedContent": "抑郁,是精神世界的感冒。一种虚无、迟滞、想哭又哭不出来的绝望的状态、带着能量被掏空的疲惫感。全世界大概1/3到...",
"recommendedUrl": "https://img.ydlcdn.com/file/2019/06/13/am2saizvjfbej6kk.jpg",
"recommendedPrice": "17.40元",
"recommendedNum": "128379",
"recommendedHits": "211251",
"recommendedLinkUrl": "app://ceshi/detail?id=1126",
"isFree": 1,
"price": "17.40"
}, {
"recommendedId": "2243",
"recommendedTitle": "亲密关系质量评估",
"recommendedContent": "彼此相爱,但不要铸成爱的镣铐,让他在你们灵魂的海岸中间成为一个流动的海。要站在一起,却不要彼此太近,因为圣殿里...",
"recommendedUrl": "https://img.ydlcdn.com/file/2019/07/30/2crf3zjc3gdqzsfp.jpg",
"recommendedPrice": "8.80元",
"recommendedNum": "123237",
"recommendedHits": "6",
"recommendedLinkUrl": "app://ceshi/detail?id=2243",
"isFree": 1,
"price": "8.80"
}, {
"recommendedId": "738",
"recommendedTitle": "专业心理健康测评",
"recommendedContent": "工作生活节奏越来越快,气候变化莫测、工作变动调整、来自各方面的压力接踵而来。你是否出现了:睡眠障碍提不起精神上...",
"recommendedUrl": "https://img.ydlcdn.com/file/2018/10/12/vzfy4x4ar1t3rc3e.PNG",
"recommendedPrice": "9.90元",
"recommendedNum": "120211",
"recommendedHits": "271697",
"recommendedLinkUrl": "app://ceshi/detail?id=738",
"isFree": 1,
"price": "9.90"
}, {
"recommendedId": "2230",
"recommendedTitle": "气质类型评估",
"recommendedContent": "每个人身上都有一些与生俱来的特性,它是通过遗传而来的,相对稳定并且难以改变的。这些特性我们称之为“气质”。我们...",
"recommendedUrl": "https://img.ydlcdn.com/file/2019/07/04/xyt278l901qxqybd.jpg",
"recommendedPrice": "19.00元",
"recommendedNum": "118699",
"recommendedHits": "281",
"recommendedLinkUrl": "app://ceshi/detail?id=2230",
"isFree": 1,
"price": "19.00"
}, {
"recommendedId": "1130",
"recommendedTitle": "性倾向综合评估",
"recommendedContent": "一个人究竟是男还是女?一个人是喜欢男性还是女性?这是两个简单的问题,但值得严肃去回答。首先中文里的性别,分别对...",
"recommendedUrl": "https://img.ydlcdn.com/file/2019/01/11/sgqpsuve99a0ag8s.jpg",
"recommendedPrice": "28.80元",
"recommendedNum": "104019",
"recommendedHits": "13992",
"recommendedLinkUrl": "app://ceshi/detail?id=1130",
"isFree": 1,
"price": "28.80"
}, {
"recommendedId": "1004",
"recommendedTitle": "专业智商评估",
"recommendedContent": "在旧观念里,智商高=学习好;但不在“学习”上聪明的人,可能在其他方面另有天赋。1983年,哈佛大学教授霍华德·...",
"recommendedUrl": "https://img.ydlcdn.com/file/2018/09/04/tl5pqy7zdad3gpiz.jpg",
"recommendedPrice": "9.90元",
"recommendedNum": "103854",
"recommendedHits": "25805",
"recommendedLinkUrl": "app://ceshi/detail?id=1004",
"isFree": 1,
"price": "9.90"
}, {
"recommendedId": "1014",
"recommendedTitle": "吸引力综合评估",
"recommendedContent": "一个人的魅力是由内而外的体现。有些人说不上绝世容颜,但就是异性缘很好,桃花不断!那是因为两个人之间,有一种看不...",
"recommendedUrl": "https://img.ydlcdn.com/file/2019/04/15/c0g7sfp98q6m0pxw.jpg",
"recommendedPrice": "9.90元",
"recommendedNum": "102159",
"recommendedHits": "7961",
"recommendedLinkUrl": "app://ceshi/detail?id=1014",
"isFree": 1,
"price": "9.90"
}, {
"recommendedId": "745",
"recommendedTitle": "焦虑类型测评",
"recommendedContent": "焦虑,是人们日常容易感知的一种负性情绪,但它并不是一种百无一是的情绪。相关的心理研究已经表明,焦虑水平与一个人...",
"recommendedUrl": "https://img.ydlcdn.com/file/2018/11/27/1jg999duumesye7o.PNG",
"recommendedPrice": "9.90元",
"recommendedNum": "99876",
"recommendedHits": "34964",
"recommendedLinkUrl": "app://ceshi/detail?id=745",
"isFree": 1,
"price": "9.90"
}, {
"recommendedId": "1502",
"recommendedTitle": "恋人出轨风险评估",
"recommendedContent": "比发现恋人出轨更可怕的是你不知道你的恋人出轨了。根据国内外的不完全统计调查,处于亲密关系(婚姻或恋爱关系)中单...",
"recommendedUrl": "https://img.ydlcdn.com/file/2018/12/28/l8trmpx9l0cdvjhg.jpg",
"recommendedPrice": "16.00元",
"recommendedNum": "94571",
"recommendedHits": "2295",
"recommendedLinkUrl": "app://ceshi/detail?id=1502",
"isFree": 1,
"price": "16.00"
}, {
"recommendedId": "2233",
"recommendedTitle": "心理独立性评估",
"recommendedContent": "心理治疗师皮纳曾说:“那些不做决断的人是在等别人替他们做决断,他们因此不用承担任何因选择失误而导致的责任。”&...",
"recommendedUrl": "https://img.ydlcdn.com/file/2019/06/17/kdrehjmowvzj3c5n.jpg",
"recommendedPrice": "0.10元",
"recommendedNum": "94479",
"recommendedHits": "451",
"recommendedLinkUrl": "app://ceshi/detail?id=2233",
"isFree": 1,
"price": "0.10"
}, {
"recommendedId": "1931",
"recommendedTitle": "沟通能力综合评估",
"recommendedContent": "沟通是人与人之间、人与群体之间思想与感情的传递和反馈的过程。人际沟通能力对我们的信息交流、人际往来、职业发展、...",
"recommendedUrl": "https://img.ydlcdn.com/file/2019/04/10/xy2ozcj8hh78n04l.jpg",
"recommendedPrice": "22.80元",
"recommendedNum": "93137",
"recommendedHits": "109",
"recommendedLinkUrl": "app://ceshi/detail?id=1931",
"isFree": 1,
"price": "22.80"
}, {
"recommendedId": "728",
"recommendedTitle": "爱的勇气评估",
"recommendedContent": "爱的勇气是什么?只要你也一样的肯定,我愿意天涯海角都随你去—这就是爱的勇气!但似乎越来越多的人在恋爱面前,都慢...",
"recommendedUrl": "https://img.ydlcdn.com/file/2018/08/28/8rsiujhe5e5rjvpz.PNG",
"recommendedPrice": "23.40元",
"recommendedNum": "93018",
"recommendedHits": "15303",
"recommendedLinkUrl": "app://ceshi/detail?id=728",
"isFree": 1,
"price": "23.40"
}, {
"recommendedId": "730",
"recommendedTitle": "恋爱性格匹配探测器",
"recommendedContent": "在爱情面前,每个人都很小心翼翼,渴望遇到真爱相守一生。就像是当局者迷,旁观者清,陶醉在爱情中的男女们,被荷尔蒙...",
"recommendedUrl": "https://img.ydlcdn.com/file/2019/05/31/mufre8ett9mdceyl.jpg",
"recommendedPrice": "23.40元",
"recommendedNum": "91009",
"recommendedHits": "26081",
"recommendedLinkUrl": "app://ceshi/detail?id=730",
"isFree": 1,
"price": "23.40"
}, {
"recommendedId": "744",
"recommendedTitle": "MBTI职业性格测试",
"recommendedContent": "为什么有些人毕业2年月薪3w,有些人工作10年却月薪5K?都说年薪10万靠的是勤奋,年薪30万比拼的就是谁更快...",
"recommendedUrl": "https://img.ydlcdn.com/file/2018/08/28/zav5ajllazj4c4xz.PNG",
"recommendedPrice": "9.90元",
"recommendedNum": "90574",
"recommendedHits": "13096",
"recommendedLinkUrl": "app://ceshi/detail?id=744",
"isFree": 1,
"price": "9.90"
}, {
"recommendedId": "2200",
"recommendedTitle": "人格倾向测评",
"recommendedContent": "人生的大舞台上,人们会根据社会角色的不同来更换不同的面具。可不管面具如何更换,隐藏在面具背后,有一个不变的你。...",
"recommendedUrl": "https://img.ydlcdn.com/file/2019/05/22/kvqp6se1mvw2zm22.jpg",
"recommendedPrice": "16.00元",
"recommendedNum": "90179",
"recommendedHits": "491",
"recommendedLinkUrl": "app://ceshi/detail?id=2200",
"isFree": 1,
"price": "16.00"
}, {
"recommendedId": "1119",
"recommendedTitle": "产后抑郁症状评估(专业版)",
"recommendedContent": "产后抑郁(Postpartum Depression, PPD)是指产妇在产褥期间出现的抑郁症状。它的诊断标准...",
"recommendedUrl": "https://img.ydlcdn.com/file/2019/04/16/wlrnn3rjib55juu1.jpg",
"recommendedPrice": "17.40元",
"recommendedNum": "89722",
"recommendedHits": "30373",
"recommendedLinkUrl": "app://ceshi/detail?id=1119",
"isFree": 1,
"price": "17.40"
}, {
"recommendedId": "2229",
"recommendedTitle": "童年阴影评估",
"recommendedContent": "你小时候有难以磨灭的伤痛和经历么?你能够勇敢向家人朋友倾诉么?&nbsp;你够坚强一个人就此沉沦抑或选择治愈么...",
"recommendedUrl": "https://img.ydlcdn.com/file/2019/06/11/kh00bylj9687qary.jpg",
"recommendedPrice": "8.80元",
"recommendedNum": "88196",
"recommendedHits": "7042",
"recommendedLinkUrl": "app://ceshi/detail?id=2229",
"isFree": 1,
"price": "8.80"
}, {
"recommendedId": "2227",
"recommendedTitle": "暗黑人格程度评估",
"recommendedContent": "每个人都处在黑与白中间的灰色地带,我们有共情,有自制,有道德,有理性;但也有自利,有贪婪,有手段,有物欲。黑暗...",
"recommendedUrl": "https://img.ydlcdn.com/file/2019/06/15/dnukx5tduk0ch56w.jpg",
"recommendedPrice": "1.99元",
"recommendedNum": "83984",
"recommendedHits": "3378",
"recommendedLinkUrl": "app://ceshi/detail?id=2227",
"isFree": 1,
"price": "1.99"
}, {
"recommendedId": "2236",
"recommendedTitle": "情商综合测评",
"recommendedContent": "成为一个高情商的人并不意味着成为一个善良或温柔的人,成为一个高情商的人意味着成为一个能够高效率地与人往来,并在...",
"recommendedUrl": "https://img.ydlcdn.com/file/2019/07/03/56fmz190zuwv2xhm.jpeg",
"recommendedPrice": "29.40元",
"recommendedNum": "82375",
"recommendedHits": "170",
"recommendedLinkUrl": "app://ceshi/detail?id=2236",
"isFree": 1,
"price": "29.40"
}, {
"recommendedId": "732",
"recommendedTitle": "恋爱风格评估",
"recommendedContent": "大家都渴望理想的爱情,但每个人爱的方式是不一样的。有些人喜欢轰轰烈烈的刻骨铭心,有些人喜欢平平淡淡的细水长流。...",
"recommendedUrl": "https://img.ydlcdn.com/file/2018/11/29/nf1b2t3ug6azuibl.PNG",
"recommendedPrice": "9.90元",
"recommendedNum": "78873",
"recommendedHits": "41921",
"recommendedLinkUrl": "app://ceshi/detail?id=732",
"isFree": 1,
"price": "9.90"
}, {
"recommendedId": "1510",
"recommendedTitle": "认知层次评估",
"recommendedContent": "贝克(著名的心理学家,认知疗法的创立者)认为个体的情感和行为在很大程度上是由自身认识外部世界的方式或方法决定的...",
"recommendedUrl": "https://img.ydlcdn.com/file/2019/01/11/shzdq4e4q90gfymb.jpg",
"recommendedPrice": "23.40元",
"recommendedNum": "78794",
"recommendedHits": "2605",
"recommendedLinkUrl": "app://ceshi/detail?id=1510",
"isFree": 1,
"price": "23.40"
}, {
"recommendedId": "1531",
"recommendedTitle": "职场人际敏锐度评估",
"recommendedContent": "在职场中打拼,难免会遇到很多与职场人际关系有关的问题:如何与上司搞好关系?如何与同事和睦相处?如何找到驱动下属...",
"recommendedUrl": "https://img.ydlcdn.com/file/2018/12/21/96qryd8igakk539t.jpg",
"recommendedPrice": "12.00元",
"recommendedNum": "73409",
"recommendedHits": "1072",
"recommendedLinkUrl": "app://ceshi/detail?id=1531",
"isFree": 1,
"price": "12.00"
}, {
"recommendedId": "735",
"recommendedTitle": "职场生存力评估",
"recommendedContent": "在职场中你有没有遇到过,那个比你后来、比你年纪小、比你经验少的人,升职了;而你,调薪都很困难?或是你每天都很辛...",
"recommendedUrl": "https://img.ydlcdn.com/file/2018/08/28/a6riks8v6ihqpj61.PNG",
"recommendedPrice": "9.90元",
"recommendedNum": "71551",
"recommendedHits": "18905",
"recommendedLinkUrl": "app://ceshi/detail?id=735",
"isFree": 1,
"price": "9.90"
}, {
"recommendedId": "1504",
"recommendedTitle": "情感地位测评",
"recommendedContent": "你也许听到过这句话:在感情中更投入的一方往往更吃亏。- 更投入的一方会更加担心失去伴侣,所以会在相处的过程中更...",
"recommendedUrl": "https://img.ydlcdn.com/file/2019/01/14/aypjl6lhr4y1abw3.jpeg",
"recommendedPrice": "12.90元",
"recommendedNum": "69946",
"recommendedHits": "1128",
"recommendedLinkUrl": "app://ceshi/detail?id=1504",
"isFree": 1,
"price": "12.90"
}, {
"recommendedId": "1007",
"recommendedTitle": "真爱质量评估",
"recommendedContent": "“爱”涉及很多因素,我们很难去评判一段爱情是好是坏,很难预估它是否有未来。我爱TA吗?为TA付出这么多真的值得...",
"recommendedUrl": "https://img.ydlcdn.com/file/2019/01/11/aumcdtc2aadqc4pc.jpg",
"recommendedPrice": "19.90元",
"recommendedNum": "67310",
"recommendedHits": "3644",
"recommendedLinkUrl": "app://ceshi/detail?id=1007",
"isFree": 1,
"price": "19.90"
}, {
"recommendedId": "1129",
"recommendedTitle": "压力源自我筛查表",
"recommendedContent": "无论“好事”“坏事”都有可能成为压力源。这个压力源筛查器能帮助你筛查出对你影响重大的事件,你可以根据报告检测自...",
"recommendedUrl": "https://img.ydlcdn.com/file/2019/05/31/u3n6vc30vsyxu1nd.jpg",
"recommendedPrice": "2.99元",
"recommendedNum": "67163",
"recommendedHits": "9413",
"recommendedLinkUrl": "app://ceshi/detail?id=1129",
"isFree": 1,
"price": "2.99"
}, {
"recommendedId": "749",
"recommendedTitle": "压力应对模式评估",
"recommendedContent": "压力应对的模式具有跨场景性,也就是说,每个人在应对不同的压力的时候都会不自觉地使用同样的应对策略,表现出较高的...",
"recommendedUrl": "https://img.ydlcdn.com/file/2019/01/11/obmi8qadddwm4jzz.jpg",
"recommendedPrice": "9.90元",
"recommendedNum": "65580",
"recommendedHits": "20246",
"recommendedLinkUrl": "app://ceshi/detail?id=749",
"isFree": 1,
"price": "9.90"
}, {
"recommendedId": "1547",
"recommendedTitle": "恋爱误区探测器",
"recommendedContent": "为什么明明相爱,却忍不住互相伤害,逃不过各自走散?想要在建立恋爱关系后维系好一段感情,从来不是件简单的事情。在...",
"recommendedUrl": "http://img.diggme.cn/2018/04/20/bea29621879434e57b8a283bed119d5d.png?x-oss-process=image/auto-orient,1/resize,m_lfit,w_300/quality,q_90",
"recommendedPrice": "19.90元",
"recommendedNum": "64598",
"recommendedHits": "978",
"recommendedLinkUrl": "app://ceshi/detail?id=1547",
"isFree": 1,
"price": "19.90"
}, {
"recommendedId": "1503",
"recommendedTitle": "亲密关系模式评估(双人版)",
"recommendedContent": "当今的恋人、夫妻动辄以“不合”而分手、离婚,总以为世界上总有一个非常适合自己的人。然而,怎样的组合才算“合”?...",
"recommendedUrl": "https://img.ydlcdn.com/file/2019/01/16/1bp0g52uwd4m8if8.jpeg",
"recommendedPrice": "16.00元",
"recommendedNum": "64597",
"recommendedHits": "1884",
"recommendedLinkUrl": "app://ceshi/detail?id=1503",
"isFree": 1,
"price": "16.00"
}],
"head": {
"title": "热门推荐"
},
"footer": {
"title": "查看全部测评",
"linkUrl": "热门推荐"
},
"diviLine": 1
}]
\ No newline at end of file
package com.yidianling.tests;
import android.support.annotation.Keep;
/**
* Created by hgw on 2018/3/8.
*/
//最近聊天专家
@Keep
public class Recent {
public int uid;
public String name;
public String head;
}
\ No newline at end of file
package com.yidianling.tests;
import android.support.annotation.Keep;
/**
* 聊过天的专家列表
* Created by hgw on 2018/3/8.
*/
@Keep
public class RecentExpert {
private String uid;//专家id
private String head;//专家头像
private String name;//专家名
public RecentExpert(String uid, String head, String name) {
this.uid = uid;
this.head = head;
this.name = name;
}
public String getUid() {
return uid;
}
public void setUid(String uid) {
this.uid = uid;
}
public String getHead() {
return head;
}
public void setHead(String head) {
this.head = head;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
\ No newline at end of file
package com.yidianling.tests
import android.annotation.SuppressLint
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.BaseAdapter
import android.widget.ImageView
import android.widget.TextView
import android.widget.Toast
import com.alibaba.android.arouter.facade.annotation.Route
import com.ydl.ydl_image.module.GlideApp
import com.ydl.ydl_image.transform.GlideCircleTransform
import com.yidianling.router.im.IMRequestCallback
import com.yidianling.tests.router.TestsIn
import com.yidianling.ydlcommon.base.BaseActivity
import com.yidianling.ydlcommon.dialog.NormalDialog
import com.yidianling.ydlcommon.http.YdlRetrofitUtils
import com.yidianling.ydlcommon.http.api.Command
import com.yidianling.ydlcommon.router.YdlCommonOut
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import kotlinx.android.synthetic.main.activity_select_conversation.*
import java.util.*
/**
* Created by Wi1ls on 2016/11/10;
*/
@Route(path = "/test/select_conversation")
class SelectConversationActivity : BaseActivity() {
override fun layoutResId(): Int {
return R.layout.activity_select_conversation
}
override fun initDataAndEvent() {
url = getIntent().getStringExtra("url")
head = getIntent().getStringExtra("head")
title = getIntent().getStringExtra("title")
share_url = getIntent().getStringExtra("share_url")
id = getIntent().getIntExtra("id", 0)
flag = getIntent().getIntExtra("flag", 0)
init()
}
// internal var text_empty: TextView? = null
internal var url: String? = null
internal var head: String? = null
internal var title: String? = null
internal var share_url: String? = null
internal var id: Int = 0
internal var flag: Int = 0
private var myData: MutableList<RecentExpert> = ArrayList<RecentExpert>()
internal fun init() {
getData()
}
@SuppressLint("WrongConstant")
private fun handleData() {
text_empty.visibility = View.INVISIBLE
select_lv.visibility = View.VISIBLE
val conversationAdapter = object : BaseAdapter() {
override fun getCount(): Int {
return myData.size
}
override fun getItem(position: Int): Any {
return myData[position]
}
override fun getItemId(position: Int): Long {
return position.toLong()
}
override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View {
val view = LayoutInflater.from(mContext).inflate(R.layout.ui_select_conversation_item, null, false)
val s = view.findViewById<ImageView>(R.id.sdv_head) as ImageView
val n = view.findViewById<TextView>(R.id.name) as TextView
GlideApp.with(mContext)
.load(myData[position].getHead())
.transform(GlideCircleTransform(mContext))
.centerCrop()
.into(s)
n.text = myData[position].name
view.setOnClickListener {
val builder = NormalDialog.Builder(mContext)
builder.setTitle("")
builder.setMessage("确定将测试结果发送给:" + myData[position].name + "?")
builder.setPositiveButton("确定"
) { dialog, which ->
TestsIn.sendTestResultMessage(myData[position].uid, "测试结果", title, head, url, id, share_url,
object : IMRequestCallback<Void> {
override fun onSuccess(t: Void?) {
YdlCommonOut.showToast("发送成功")
finish()
}
override fun onFailed(i: Int) {
YdlCommonOut.showToast("发送失败")
finish()
}
override fun onException(throwable: Throwable?) {
YdlCommonOut.showToast("发送失败")
finish()
}
})
dialog.dismiss()
}
builder.setNegativeButton("取消"
) { dialog, _ -> dialog.dismiss() }
builder.create().show()
}
return view
}
}
select_lv.adapter = conversationAdapter
}
private fun getData() {
val cmd = Command.RecentCmd()
TestRetrofitApi.getTestRetrofitApi().getRecentExpertList(YdlRetrofitUtils.getMaps(cmd))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.doOnSubscribe({showProgressDialog("")})
.doAfterTerminate({dismissProgressDialog()})
.subscribe(
{
if (it.code == 0) {
for (recent in it.data) {
val recentExpert = RecentExpert(""+recent.uid, recent.head, recent.name)
myData.add(recentExpert)
}
handleData()
} else {
Toast.makeText(this@SelectConversationActivity, it.msg, Toast.LENGTH_SHORT).show()
}
},{
YdlRetrofitUtils.handleError(mContext,it)
})
}
companion object {
val FLAG_SEND_TESTRESULT = 1
}
}
package com.yidianling.tests
import com.ydl.ydlcommon.base.config.YDL_DOMAIN
import com.ydl.ydlcommon.base.config.YDL_DOMAIN_JAVA
import com.ydl.ydlcommon.data.http.BaseAPIResponse
import com.ydl.ydlcommon.data.http.BaseResponse
import com.ydl.ydlnet.YDLHttpUtils
import com.yidianling.tests.answer.HandleResultData
import com.yidianling.tests.detail.model.bean.TestAddOrder
import com.yidianling.tests.detail.model.bean.TestDetail
import com.yidianling.tests.list.model.bean.RecommendSearchItemBean
import com.yidianling.tests.list.model.bean.TestCategory
import com.yidianling.tests.list.model.bean.TestListData
import com.yidianling.tests.result.model.TestResult
import io.reactivex.Observable
import retrofit2.http.*
/**
* 测试相关网络接口
* Created by zqk on 17-11-24.
*/
interface TestRetrofitApi {
companion object {
var instance: TestRetrofitApi? = null
fun getTestRetrofitApi(): TestRetrofitApi {
if (instance == null) {
instance = YDLHttpUtils.obtainApi(TestRetrofitApi::class.java)
}
return instance!!
}
fun clearTestRetrofitApi() {
instance = null
}
}
//获取测试分类
@GET("test-tag/cat_all")
@Headers( YDL_DOMAIN+ YDL_DOMAIN_JAVA)
fun fetchTestCategory(): Observable<BaseAPIResponse<MutableList<TestCategory>>>
/**
* 获取测评红包
*/
@GET("auth/test-coupon/max-coupon-money")
@Headers( YDL_DOMAIN + YDL_DOMAIN_JAVA)
fun fetchMaxCoupon(@Query("uid") uid: String = ""): Observable<BaseAPIResponse<String>>
//获取测试列表
@FormUrlEncoded
@POST("ceshi/list")
fun fetchTestList(@FieldMap params: Map<String, String>): Observable<BaseResponse<TestListData>>
@GET("test-item/top-search")
@Headers( YDL_DOMAIN+ YDL_DOMAIN_JAVA)
fun fetchTopSearch(): Observable<BaseAPIResponse<MutableList<RecommendSearchItemBean>>>
//获取测试列表 - NEW
@GET("test-item/list-by-newTag")
@Headers( YDL_DOMAIN+ YDL_DOMAIN_JAVA)
fun fetchTestListByTag(
//测试标签ID
@Query("testTagId") testTagId:String,
//筛选条件免费付费 2免费 3付费
@Query("testPrice") testPrice:String = "",
//筛选条件测试人数 条件4
@Query("testVisitNum") testVisitNum:String = "",
//筛选条件创建时间 条件5
@Query("testCreateTime") testCreateTime:String = "",
//是否仅付费题 0全部 1仅付费
@Query("onlyFee") onlyFee:String = "0",
@Query("page") page: String,
@Query("uid") uid: String = ""
): Observable<BaseAPIResponse<TestListData>>
//获取测试详情
@FormUrlEncoded
@POST("ceshi/detail")
fun fetchTestDetail(@FieldMap params: Map<String, String>): Observable<BaseResponse<TestDetail>>
//测试详情页面跳转
@FormUrlEncoded
@POST("ceshi/is-answer-h5")
fun getTestDetailJumpType(@FieldMap params: Map<String, String>): Observable<BaseResponse<String>>
//测试详情页 下订单接口
@FormUrlEncoded
@POST("ceshi/add-order")
fun fetchTestAddOrder(@FieldMap params: Map<String, String>): Observable<BaseResponse<TestAddOrder>>
//上传测试答案
@FormUrlEncoded
@POST("ceshi/handle-result")
fun handleResult(@FieldMap params: Map<String, String>): Observable<BaseResponse<HandleResultData>>
//获取测试结果
@FormUrlEncoded
@POST("ceshi/result")
fun fetchResult(@FieldMap params: Map<String, String>): Observable<BaseResponse<TestResult>>
//用户最近聊天专家
@FormUrlEncoded
@POST("sms/recent")
fun getRecentExpertList(@FieldMap params: Map<String, String>): Observable<BaseResponse<List<Recent>>>
}
\ No newline at end of file
package com.yidianling.tests
/**
* Created by haorui on 2019-10-30.
* Des:
*/
class TestsBIConstants{
companion object {
val EVENT_TEST_HOME_SEARCH_CLICK = "测评主页搜索"
val EVENT_TEST_HOME_MINE_CLICK = "测评主页个人中心图标点击"
val EVENT_TEST_HOME_BANNER_CLICK = "测评主页banner点击"
val EVENT_TEST_HOME_CATEGORY_CLICK = "测评主页测评分类点击"
val EVENT_TEST_HOME_LOOP_CLICK = "测评主页轮播点击"
val EVENT_TEST_HOME_DAILY_CLICK = "测评主页每日精选点击"
val EVENT_TEST_HOME_DAILY_CHANGE_CLICK = "测评主页每日精选换一换点击"
val EVENT_TEST_HOME_HOT_CLICK = "测评主页热门推荐点击"
val EVENT_TEST_LIST_SEARCH_CLICK = "测评列表页搜索"
val EVENT_TEST_LIST_MORE_CLICK = "测评列表页更多点击"
val EVENT_TEST_LIST_CATEGORY_CLICK = "测评列表页分类点击"
val EVENT_TEST_LIST_TEST_TITLE_CLICK = "测评列表页测评题点击"
val EVENT_TEST_DETAIL_SHARE_CLICK = "测评详情页顶部分享点击"
val EVENT_TEST_DETAIL_START_CLICK = "测评详情页立即测试点击"
val EVENT_TEST_DETAIL_MORE_CLICK = "测评详情页更多点击"
val EVENT_PAY_CLICK = "支付页面底部按钮点击"
val EVENT_TEST_RESULT_BOTTOM_CLICK = "测评结果页底部点击"
val EVENT_TEST_RESULT_MORE_CLICK = "测评结果页更多点击"
val EVENT_TEST_RESULT_SHARE_CLICK = "测评结果页顶部分享点击"
val PROPERTY_TEST_HOME_BANNER_URL = "banner链接"
val PROPERTY_TEST_HOME_BANNER_NAME = "banner标题"
}
}
package com.yidianling.tests.home
import android.support.v4.content.ContextCompat
import android.support.v4.widget.SwipeRefreshLayout
import android.support.v7.widget.LinearLayoutManager
import android.support.v7.widget.RecyclerView
import android.text.TextUtils
import android.view.View
import com.alibaba.android.arouter.facade.annotation.Route
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import com.yidianling.common.tools.RxImageTool
import com.yidianling.common.tools.ToastUtil
import com.yidianling.tests.R
import com.yidianling.tests.home.adapter.AdapterWrapper
import com.yidianling.tests.home.adapter.TestHomeAdapter
import com.yidianling.tests.home.bean.TestHomeDataBean
import com.yidianling.tests.home.config.ITestHomeConfig
import com.yidianling.tests.home.contract.ITestHomeContract
import com.yidianling.tests.home.event.ITestHomeEvent
import com.yidianling.tests.home.event.TestHomeEventImpl
import com.yidianling.tests.home.event.UpdateCouponMoneyEvent
import com.yidianling.tests.home.presenter.TestHomePresenterImpl
import com.yidianling.tests.home.utils.TestHomeUtils
import com.yidianling.tests.home.widget.SwipeToLoadHelper
import com.yidianling.ydlcommon.constant.UMConstants
import com.yidianling.ydlcommon.event.SelectTabCallPhoneEvent
import com.yidianling.ydlcommon.mvp.MVPActivity
import com.yidianling.ydlcommon.remind.ToastHelper
import com.yidianling.ydlcommon.tool.BuryPointUtils
import com.yidianling.ydlcommon.utils.SharedPreferencesEditor
import com.yidianling.ydlcommon.utils.UMEventUtils
import com.yidianling.ydlcommon.utils.YDLAsyncUtils
import com.yidianling.ydlcommon.utils.YDLCacheUtils
import de.greenrobot.event.EventBus
import kotlinx.android.synthetic.main.testhome_activity.*
import kotlinx.android.synthetic.main.testhome_bar.*
import org.json.JSONObject
/**
* @author yuanwai
* @描述:测评首页Activity
* @Copyright Copyright (c) 2018
* @Company 壹点灵
* @date 2018/7/26
*/
@Route(path = "/ceshi/home")
class TestHomeActivity : MVPActivity<ITestHomeContract.Presenter>(), ITestHomeContract.View, SwipeToLoadHelper.LoadMoreListener, SwipeRefreshLayout.OnRefreshListener {
/**
* 适配器包装 处理上拉加载更多
*/
private var mAdapterWrapper: AdapterWrapper? = null
/**
* 测评首页列表适配器
*/
private var mTestHomeAdapter: TestHomeAdapter? = null
/**
* 下拉刷新组件
*/
private var mLoadMoreHelper: SwipeToLoadHelper? = null
/**
* LayoutManager
*/
private var mLayoutManager: RecyclerView.LayoutManager? = null
/**
* 页
*/
private var page: Int = 1
/**
* 测评首页事件处理类
*/
private var testHomeEvent: ITestHomeEvent? = null
private var dp150: Int? = 0
/**
* 来源
*/
private var fromStr: String? = null
override fun createPresenter(): ITestHomeContract.Presenter {
return TestHomePresenterImpl(this)
}
override fun layoutResId(): Int {
return R.layout.testhome_activity
}
override fun initDataAndEvent() {
EventBus.getDefault().register(this)
testHomeEvent = TestHomeEventImpl(this)
getRouterParam()
initAdapter()
loadLocalData()
newHomeRequest()
rl_search.setOnClickListener {
(testHomeEvent as TestHomeEventImpl).jumpSearch()
}
img_back.setOnClickListener {
onBackPressed()
}
img_mine.setOnClickListener {
(testHomeEvent as TestHomeEventImpl).jumpMine()
}
}
//路由传递过来的参数
private fun getRouterParam() {
if (null != intent && intent.hasExtra("routerParam")) {
val params = intent.getStringExtra("routerParam")
val paramsJson = JSONObject(params)
if (paramsJson.has("from")){
fromStr = paramsJson.getString("from");
}
}
}
private fun initAdapter() {
swipe_refresh_layout.setOnRefreshListener(this)
swipe_refresh_layout.setColorSchemeColors(ContextCompat.getColor(this, R.color.main_theme_blue))
mLayoutManager = LinearLayoutManager(mContext, LinearLayoutManager.VERTICAL, false)
recyclerview.layoutManager = mLayoutManager
if (null == mTestHomeAdapter) {
mTestHomeAdapter = TestHomeAdapter(this, ArrayList<TestHomeDataBean>(), testHomeEvent!!, this)
}
if (null == mAdapterWrapper) {
mAdapterWrapper = AdapterWrapper(mTestHomeAdapter!!)
}
mLoadMoreHelper = SwipeToLoadHelper(recyclerview, mAdapterWrapper!!)
mLoadMoreHelper!!.setLoadMoreListener(this)
recyclerview.adapter = mAdapterWrapper
}
override fun onResume() {
super.onResume()
if (null == mTestHomeAdapter) {
return
}
mTestHomeAdapter!!.starBanner()
TestHomeUtils.updateCouponMoney()
}
override fun onStop() {
super.onStop()
if (null == mTestHomeAdapter) {
return
}
mTestHomeAdapter!!.stopBanner()
}
private fun loadLocalData() {
//取上次缓存的优惠券数据
val lastCouponMoney = SharedPreferencesEditor.getString(TestHomeUtils.TEST_MAX_COUPON_MONEY_SP_KEY)
if (!TextUtils.isEmpty(lastCouponMoney)){
mTestHomeAdapter?.couponMoney = lastCouponMoney
}
YDLAsyncUtils.asyncAsResult(object : YDLAsyncUtils.AsyncObjecyerResult {
override fun doAsyncAction(): Any {
//读取缓存数据
var cacheData = YDLCacheUtils.getTestHomeData()
if (cacheData.isEmpty()) {
cacheData = String(TestHomeUtils.getAssertsFile(mContext, "test_home.json")!!)
}
return cacheData
}
override fun asyncResult(`object`: Any?) {
if (`object` is String) {
val list = Gson().fromJson<List<TestHomeDataBean>>(`object`, object : TypeToken<List<TestHomeDataBean>>() {
}.type)
if (null != list && !list.isEmpty()) {
newHomeResponse(list)
}
}
}
})
}
override fun newHomeRequest() {
page = 1
presenter.newHomeRequest()
}
override fun newHomeResponse(datalist: List<TestHomeDataBean>) {
hideError()
recyclerview.visibility = View.VISIBLE
val newDataList = TestHomeUtils.resetData(datalist)
mTestHomeAdapter!!.updataItems(newDataList)
swipe_refresh_layout.isRefreshing = false
// 刷新完成是解禁上拉加载更多
mLoadMoreHelper!!.setSwipeToLoadEnabled(true)
mAdapterWrapper!!.notifyDataSetChanged()
YDLAsyncUtils.async(object : YDLAsyncUtils.AsyncObjecyer {
override fun doAsyncAction() {
YDLCacheUtils.saveTestHomeData(Gson().toJson(datalist))
}
})
}
override fun newHomeRequestFail() {
showError()
}
private fun showError() {
if (null == mTestHomeAdapter
|| null == mTestHomeAdapter!!.getList()
|| mTestHomeAdapter!!.getList().isEmpty()) {
recyclerview.visibility = View.GONE
}
}
private fun hideError() {
recyclerview.visibility = View.VISIBLE
}
override fun loadMoreResponse(datalist: List<TestHomeDataBean>) {
mTestHomeAdapter!!.addItems(datalist)
swipe_refresh_layout.isEnabled = true
if (3 == page) {
mLoadMoreHelper!!.setNoMoreData()
} else {
mLoadMoreHelper!!.setLoadMoreFinish()
mAdapterWrapper!!.notifyDataSetChanged()
}
}
override fun dailyChange() {
UMEventUtils.umEvent(TestsBIConstants.EVENT_TEST_HOME_DAILY_CHANGE_CLICK, "", "")
//埋点
BuryPointUtils.getInstance().createMap()
.burryPoint("ceping_change")
showProgressDialog()
presenter.dailyChange()
}
override fun dailyChangeResponse(dataBean: TestHomeDataBean) {
dismissProgressDialog()
var list = ArrayList<TestHomeDataBean>()
list.addAll(mTestHomeAdapter!!.getList())
for (item in list) {
if (item.type == ITestHomeConfig.TYPE_DAILY) {
(item.body as ArrayList).clear()
item.body.addAll(dataBean.body!!)
}
}
mTestHomeAdapter!!.updataItems(list)
mTestHomeAdapter!!.notifyDataSetChanged()
mAdapterWrapper!!.notifyDataSetChanged()
}
/**
* 下拉刷新
*/
override fun onRefresh() {
mTestHomeAdapter!!.setBannerRefresh()
newHomeRequest()
// 刷新时禁用上拉加载更多
mLoadMoreHelper!!.setSwipeToLoadEnabled(false)
}
/**
* 上拉加载更多
*/
override fun onLoad() {
++page
if (page > 3) {
mLoadMoreHelper!!.setNoMoreData()
return
}
swipe_refresh_layout.isEnabled = false
presenter.onLoadMore(page)
}
/**
* 查看全部测评
*/
override fun selectAll() {
testHomeEvent!!.selectAll()
}
override fun showError(msg: String?) {
ToastHelper.show("网络不给力")
}
/**
* 更新优惠券信息
* 刷新列表
*/
fun onEvent(updateCouponMoneyEvent: UpdateCouponMoneyEvent){
mTestHomeAdapter?.couponMoney = updateCouponMoneyEvent.money
mTestHomeAdapter?.notifyDataSetChanged()
}
override fun onDestroy() {
super.onDestroy()
EventBus.getDefault().unregister(this)
if (null != mTestHomeAdapter) {
mTestHomeAdapter!!.onDestory()
}
}
override fun onBackPressed() {
if (!TextUtils.isEmpty(fromStr) && "h5" == fromStr){
//如果是从H5打开的测评首页,返回时选中首页Tab
EventBus.getDefault().post(SelectTabCallPhoneEvent(0))
}
super.onBackPressed()
}
}
\ No newline at end of file
package com.yidianling.tests.home.adapter
import android.support.v7.widget.RecyclerView
import android.view.View
import android.view.ViewGroup
import com.yidianling.tests.R
import com.yidianling.tests.home.config.ITestHomeConfig
import kotlinx.android.synthetic.main.testhome_item_load_more.view.*
/**
* @author yuanwai
* @描述:上拉加载更多适配器
* @Copyright Copyright (c) 2018
* @Company 壹点灵
* @date 2018/7/26
*/
class AdapterWrapper(private val mAdapter: RecyclerView.Adapter<RecyclerView.ViewHolder>) : RecyclerView.Adapter<RecyclerView.ViewHolder>() ,View.OnClickListener{
private var mShowLoadItem = true
private var mWrapperHolder: WrapperHolder? = null
private var mAdapterType = ADAPTER_TYPE_LINEAR
private var mSpanCount: Int = 0
private var STATUS_FOOTER : Int = 1
/**
* footer回调
*/
private var mFooterCallBack: FooterCallBack? = null
/** 设置Wrapper的类型, 默认是线性的 */
fun setAdapterType(type: Int) {
if (mAdapterType != type) {
mAdapterType = type
}
}
/** 网格布局的网格数量 */
fun setSpanCount(count: Int) {
if (count != mSpanCount) {
mSpanCount = count
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
if (viewType == ITEM_TYPE_LOAD) {
if (mWrapperHolder == null) {
var view = View.inflate(parent.context, R.layout.testhome_item_load_more, null)
view.setOnClickListener(this)
mWrapperHolder = WrapperHolder(view)
}
return mWrapperHolder as WrapperHolder
} else {
return mAdapter.onCreateViewHolder(parent, viewType)
}
}
// 允许显示"加载更多"item, 并且position为末尾时,拦截
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
if (mShowLoadItem && position == itemCount - 1) {
// 最后一项 不需要做什么额外的事
} else if (position < mAdapter.itemCount) {
// 正常情况
holder.itemView.visibility = View.VISIBLE
mAdapter.onBindViewHolder(holder, position)
} else {
// 网格的补空的情况
holder.itemView.visibility = View.INVISIBLE
}
}
override fun getItemCount(): Int {
if (mAdapterType == ADAPTER_TYPE_LINEAR) {
// 线性布局
return if (mShowLoadItem) mAdapter.itemCount + 1 else mAdapter.itemCount
} else {
// 网格布局
if (!mShowLoadItem)
return mAdapter.itemCount// 不显示load more时直接返回真实数量
val remain = mAdapter.itemCount % mSpanCount // 余数
return if (remain == 0) {
mAdapter.itemCount + 1
} else mAdapter.itemCount + 1 + (mSpanCount - remain)
// 余数不为0时,先凑满再加1
}
}
override fun getItemViewType(position: Int): Int {
// 当显示"加载更多"条目, 并且位置是最后一个时, wrapper进行拦截
return if (mShowLoadItem && position == itemCount - 1) {
ITEM_TYPE_LOAD// 注意要避免和原生adapter返回值重复
} else mAdapter.getItemViewType(position)
// 其他情况交给原生adapter处理
}
fun setLoadItemVisibility(isShow: Boolean) {
if (mShowLoadItem != isShow) {
mShowLoadItem = isShow
notifyDataSetChanged()
}
}
fun setLoadItemState(status: Int) {
STATUS_FOOTER = status
when(status){
ITestHomeConfig.STATUS_UP_LOAD -> {
mWrapperHolder!!.setLoadText("上拉加载更多")
mWrapperHolder!!.setNullDrawable()
mWrapperHolder!!.setLoadPbVisibility(false)
}
ITestHomeConfig.STATUS_LOADING -> {
mWrapperHolder!!.setLoadText("正在加载...")
mWrapperHolder!!.setNullDrawable()
mWrapperHolder!!.setLoadPbVisibility(true)
}
ITestHomeConfig.STATUS_SELECT_ALL -> {
mWrapperHolder!!.setLoadText("查看全部测评")
mWrapperHolder!!.setMoreDrawable()
mWrapperHolder!!.setLoadPbVisibility(false)
}
}
}
internal inner class WrapperHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
fun setLoadText(text: CharSequence) {
itemView.item_load_tv!!.text = text
}
fun setMoreDrawable(){
val drawable = itemView.context.resources.getDrawable(R.drawable.testhome_more)
/// 这一步必须要做,否则不会显示.
drawable.setBounds(0, 0, drawable.minimumWidth, drawable.minimumHeight)
itemView.item_load_tv.setCompoundDrawablesWithIntrinsicBounds(null, null, drawable, null)
}
fun setNullDrawable(){
itemView.item_load_tv.setCompoundDrawablesWithIntrinsicBounds(null, null, null, null)
}
fun setLoadPbVisibility(show: Boolean) {
itemView.item_load_pb!!.visibility = if (show) View.VISIBLE else View.GONE
}
}
companion object {
/** 线性 */
val ADAPTER_TYPE_LINEAR = 0x01
/** 网格 */
val ADAPTER_TYPE_GRID = 0x02
/** view type : "上拉加载更多" */
private val ITEM_TYPE_LOAD = Integer.MAX_VALUE / 2
}
override fun onClick(v: View?) {
if (ITestHomeConfig.STATUS_SELECT_ALL == STATUS_FOOTER){
mFooterCallBack!!.selectAll()
}
}
/**
* 设置底部footer点击回调
*/
fun setFooterCallBack(footerCallBack: FooterCallBack){
mFooterCallBack = footerCallBack
}
/**
* 底部footer点击回调
*/
interface FooterCallBack{
/**
* 查看全部测评点击事件
*/
fun selectAll()
}
}
\ No newline at end of file
package com.yidianling.tests.home.adapter
import android.content.Context
import android.support.v7.widget.RecyclerView
import android.view.View
import android.view.ViewGroup
import com.yidianling.tests.R
import com.yidianling.tests.home.bean.TestHomeDataBean
import com.yidianling.tests.home.config.ITestHomeConfig
import com.yidianling.tests.home.contract.ITestHomeContract
import com.yidianling.tests.home.event.ITestHomeEvent
import com.yidianling.tests.home.widget.*
import java.util.*
/**
* @author yuanwai
* @描述:测评首页列表适配器
* @Copyright Copyright (c) 2018
* @Company 壹点灵
* @date 2018/7/27
*/
class TestHomeAdapter(private val mContext: Context,
private var mListData: List<TestHomeDataBean>,
private var testHomeEvent: ITestHomeEvent,
private var testHomeView: ITestHomeContract.View) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
private var categoryViewHolder: CategoryViewHolder? = null
private var bannerViewHolder: BannerViewHolder? = null
var couponMoney = ""
override fun getItemViewType(position: Int): Int {
if (ITestHomeConfig.TYPE_RECOMMENDED == mListData[position].type!!) {
if (mListData[position].body!![0].recommendIsFirst!!) {
return ITestHomeConfig.TYPE_RECOMMENDED_FIRST
}
}
return mListData[position].type!!
}
fun updataItems(list: List<TestHomeDataBean>) {
if (null == mListData || mListData.isEmpty()) {
mListData = ArrayList()
} else {
(mListData as ArrayList).clear()
}
(mListData as ArrayList).addAll(list)
}
fun setBannerRefresh(){
if (null != bannerViewHolder && null != bannerViewHolder!!.bannerView!!) {
bannerViewHolder!!.bannerView!!.setRefresh(false)
}
}
fun addItems(list: List<TestHomeDataBean>) {
if (null == mListData || mListData.isEmpty()) {
mListData = ArrayList()
}
(mListData as ArrayList).addAll(list)
}
fun getList(): List<TestHomeDataBean> {
return mListData
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
when (viewType) {
//banner
ITestHomeConfig.TYPE_BANNER -> {
return BannerViewHolder(TestHomeBannerView(parent.context, testHomeEvent))
}
//分类测评+实时测试状态
ITestHomeConfig.TYPE_CATEGORY -> {
return CategoryViewHolder(TestHomeCategoryView(parent.context, testHomeEvent))
}
//每日精选
ITestHomeConfig.TYPE_DAILY -> {
return DailyViewViewHolder(TestHomeDailyView(parent.context, testHomeEvent, testHomeView))
}
//推荐测评列表
ITestHomeConfig.TYPE_RECOMMENDED -> {
return RecommendedViewHolder(TestHomeRecommendedView(parent.context, testHomeEvent))
}
ITestHomeConfig.TYPE_RECOMMENDED_FIRST -> {
return RecommendedFirstViewHolder(TestHomeRecommendedFirstView(parent.context, testHomeEvent))
}
else -> {
return EmptyViewHolder(View.inflate(parent.context, R.layout.testhome_empty, null))
}
}
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) =
if (holder is BannerViewHolder && null != holder.bannerView) {
bannerViewHolder = holder
holder.bannerView!!.initData(mListData[position])
} else if (holder is CategoryViewHolder && null != holder.categoryView) {
categoryViewHolder = holder
holder.categoryView!!.initData(mListData[position])
} else if (holder is DailyViewViewHolder && null != holder.dailyView) {
holder.dailyView!!.couponMoney = couponMoney
holder.dailyView!!.initData(mListData[position])
} else if (holder is RecommendedFirstViewHolder) {
holder.recommendedFirstView!!.couponMoney = couponMoney
holder.recommendedFirstView!!.initData(mListData[position], position)
} else if (holder is RecommendedViewHolder && null != holder.recommendedView) {
holder.recommendedView!!.couponMoney = couponMoney
holder.recommendedView!!.initData(mListData[position], position)
} else if (holder is EmptyViewHolder) {
} else {
}
override fun getItemCount(): Int {
return mListData.size
}
/**
* Banner viewHolder
*/
inner class BannerViewHolder(itemView: TestHomeBannerView) : RecyclerView.ViewHolder(itemView) {
var bannerView: TestHomeBannerView? = null
init {
bannerView = itemView
}
}
/**
* 测评分类+实时测试状态viewHolder
*/
inner class CategoryViewHolder(itemView: TestHomeCategoryView) : RecyclerView.ViewHolder(itemView) {
var categoryView: TestHomeCategoryView? = null
init {
categoryView = itemView
}
}
/**
* 每日精选 viewHolder
*/
inner class DailyViewViewHolder(itemView: TestHomeDailyView) : RecyclerView.ViewHolder(itemView) {
var dailyView: TestHomeDailyView? = null
init {
dailyView = itemView
}
}
/**
* 热门推荐 第一个view的 viewHolder
*/
inner class RecommendedFirstViewHolder(itemView: TestHomeRecommendedFirstView) : RecyclerView.ViewHolder(itemView) {
var recommendedFirstView: TestHomeRecommendedFirstView? = null
init {
recommendedFirstView = itemView
}
}
/**
* 热门推荐viewHolder
*/
inner class RecommendedViewHolder(itemView: TestHomeRecommendedView) : RecyclerView.ViewHolder(itemView) {
var recommendedView: TestHomeRecommendedView? = null
init {
recommendedView = itemView
}
}
/**
* 空ViewHolder
*/
inner class EmptyViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
var view: View? = null
init {
view = itemView
}
}
fun starBanner() {
if (null != bannerViewHolder && null != bannerViewHolder!!.bannerView) {
bannerViewHolder!!.bannerView!!.startBanner()
}
}
fun stopBanner() {
if (null != bannerViewHolder && null != bannerViewHolder!!.bannerView) {
bannerViewHolder!!.bannerView!!.stopBanner()
}
}
fun onDestory() {
//暂停 实施测评状态轮播
if (null != categoryViewHolder && null != categoryViewHolder!!.categoryView) {
categoryViewHolder!!.categoryView!!.onDestory()
}
//暂停 banner轮播
if (null != bannerViewHolder && null != bannerViewHolder!!.bannerView) {
bannerViewHolder!!.bannerView!!.stopBanner()
}
}
}
\ No newline at end of file
package com.yidianling.tests.home.bean
/**
* @author yuanwai
* @描述: 测评首页数据--body节点
* @Copyright Copyright (c) 2016
* @Company 壹点灵
* @date 2018/7/26
*/
data class TestHomeBodyBean(
/**
* banner
*/
//banner ID
val bannerId : String?,
//banner图片地址
val bannerImageUrl : String?,
//banner 名称
val bannerName : String?,
//跳转地址
val bannerLinkUrl : String?,
/**
* 实时测试状态
*/
//实时测试状态Id
val realTestId : String?,
//实时测试状态用户名+测试了文案
val realTestName : String?,
//实时测试状态测试题标题
val realTestTitle : String?,
//实时测试状态用户头像
val realTestIcon : String?,
//c
val realTestLinkUrl : String?,
/**
* 每日精选
*/
//每日精选Id
val dailyId : String?,
//每日精选标题
val dailyTitle : String?,
//每日精选图片地址
val dailyImageUrl : String?,
//每日精选多人测过的文案
val dailyContent : String?,
//跳转地址
val dailyLinkUrl : String?,
//每日精选价格
val price : String?,
/**
* 推荐测评列表数据
*/
//是否为推荐测评第一个View
var recommendIsFirst : Boolean?,
//推荐测评Id
val recommendedId : String?,
//推荐测评标题
val recommendedTitle : String?,
//推荐测评副标题
val recommendedContent : String?,
//推荐测评图片地址
val recommendedUrl : String?,
//推荐测评费用
val recommendedPrice : String?,
//推荐测评测试人次文案
val recommendedNum : String?,
//跳转地址
val recommendedLinkUrl : String?,
//人气
val recommendedHits : String?)
\ No newline at end of file
package com.yidianling.tests.home.bean
/**
* @author yuanwai
* @描述:测评首页--测评分类数据节点
* @Copyright Copyright (c) 2018
* @Company 壹点灵
* @date 2018/7/26
*/
data class TestHomeCategoryBean(
//测评分类Id
val categoryId : String?,
//测评分类名称
val categoryName : String?,
//测评分类图片地址
val categoryUrl : String?,
//测评分类拼音
val categoryTab : String?)
\ No newline at end of file
package com.yidianling.tests.home.bean
/**
* @author yuanwai
* @描述:测评首页数据bean
* @Copyright Copyright (c) 2018
* @Company 壹点灵
* @date 2018/7/26
*/
data class TestHomeDataBean(
/**
* 数据分类 8.banner+测评分类 9.实时测试状态 10.每日精选 11.推荐测评
*/
val type: Int?,
/**
* 数据集合节点(数据都会放在这个节点,除测评分类数据为单独节点)
*/
val body : List<TestHomeBodyBean>?,
/**
* 测评分类数据节点( 仅type=8时才需要这个字段 )
*/
val category : List<TestHomeCategoryBean>?,
/**
* 头部数据节点
*/
val head : TestHomeHeadBean?,
/**
* 底部数据节点
*/
val footer : TestHomeFooterBean?,
/**
* 是否显示分割线 0.不显示 1.显示( 当type=11时,diviLine对所有推荐测评数据生效,最后一条会不显示 )
*/
val diviLine : Int?)
\ No newline at end of file
package com.yidianling.tests.home.bean
/**
* @author yuanwai
* @描述:
* @Copyright Copyright (c) 2018
* @Company 壹点灵
* @date 2018/7/28
*/
data class TestHomeFooterBean(
/**
* 标题
*/
val title : String,
/**
* 1.http开头的 跳转 H5 2.app开头的 跳转原生界面
*/
val linkUrl : String)
\ No newline at end of file
package com.yidianling.tests.home.bean
import java.io.Serializable
/**
* @author yuanwai
* @描述:
* @Copyright Copyright (c) 2018
* @Company 壹点灵
* @date 2018/7/28
*/
data class TestHomeHeadBean(val title : String?) : Serializable
\ No newline at end of file
package com.yidianling.tests.home.config
/**
* @author yuanwai
* @描述:测评首页配置
* @Copyright Copyright (c) 2018
* @Company 壹点灵
* @date 2018/7/27
*/
interface ITestHomeConfig{
companion object {
/**
* banner
*/
const val TYPE_BANNER = 8
/**
* 测评分类+实时测试状态
*/
const val TYPE_CATEGORY = 9
/**
* 每日精选
*/
const val TYPE_DAILY = 10
/**
* 推荐测评列表
*/
const val TYPE_RECOMMENDED = 11
/**
* 推荐测评列表 第一个View 类型
*/
const val TYPE_RECOMMENDED_FIRST = 999
/**
* 底部view加载类型
* 1.上拉加载 2.加载中 3.查看全部测评
*/
const val STATUS_UP_LOAD = 1
const val STATUS_LOADING = 2
const val STATUS_SELECT_ALL = 3
}
}
\ No newline at end of file
package com.yidianling.tests.home.contract
import com.ydl.ydlcommon.mvp.base.IModel
import com.ydl.ydlcommon.mvp.base.IPresenter
import com.ydl.ydlcommon.mvp.base.IView
import com.yidianling.tests.home.bean.TestHomeDataBean
import io.reactivex.Observable
/**
* @author yuanwai
* @描述:测试首页约束类
* @Copyright Copyright (c) 2018
* @Company 壹点灵
* @date 2018/7/26
*/
interface ITestHomeContract{
//View接口
interface View : IView {
/**
* 测评首页数据请求
*/
fun newHomeRequest()
/**
* 测评首页数据请求结果
*/
fun newHomeResponse(datalist : List<TestHomeDataBean>)
/**
* 测评首页数据请求失败
*/
fun newHomeRequestFail()
/**
* 每日精选 换一批
*/
fun dailyChange()
/**
* 测评首页换一批请求结果
*/
fun dailyChangeResponse(dataBean : TestHomeDataBean)
/**
* 加载更多
*/
fun loadMoreResponse(datalist : List<TestHomeDataBean>)
/**
* 显示错误信息
*/
fun showError(msg : String?)
}
interface Presenter : IPresenter<View> {
/**
* 测评首页数据请求
*/
fun newHomeRequest()
/**
* 上拉加载更多
*/
fun onLoadMore(page : Int)
/**
* 每日精选 换一批
*/
fun dailyChange()
}
interface Model: IModel {
/**
* 测评首页数据请求
*/
fun newHomeRequest() : Observable<List<TestHomeDataBean>>
/**
* 每日精选 换一批
*/
fun dailyChange() : Observable<TestHomeDataBean>
}
}
\ No newline at end of file
package com.yidianling.tests.home.event
/**
* @author yuanwai
* @描述:测评首页点击事件接口类
* @Copyright Copyright (c) 2018
* @Company 壹点灵
* @date 2018/8/3
*/
interface ITestHomeEvent {
/**
* 跳转我的界面
*/
fun jumpMine()
/**
* 跳转搜索界面
*/
fun jumpSearch()
/**
* banner点击事件
*/
fun bannerClick(linkUrl: String?, position: Int, title: String?)
/**
* 测评分类点击事件
* @param tabName 标签名称
*/
fun categoryClick(tabName: String?, position: Int, title: String?,id: String?)
/**
* 实时测评状态点击事件
*/
fun realTestClick(linkUrl: String?, title: String?)
/**
* 每日精选点击事件
*/
fun dailyClick(linkUrl: String?, position: Int, title: String?)
/**
* 热门推荐点击事件
*/
fun recommendedClick(linkUrl: String?, position: Int, title: String?)
/**
* 查看全部测评
*/
fun selectAll()
}
\ No newline at end of file
package com.yidianling.tests.home.event
import android.app.Activity
import android.content.Context
import android.net.Uri
import com.ydl.webview.H5Params
import com.ydl.webview.NewH5Activity
import com.ydl.ydl_router.manager.YDLRouterManager
import com.ydl.ydl_router.manager.YDLRouterParams
import com.ydl.ydlcommon.router.IYDLRouterConstant
import com.ydl.ydlcommon.utils.BuryPointUtils
import com.ydl.ydlcommon.utils.UMEventUtils
import com.yidianling.router.RouterManager
import com.yidianling.tests.TestsBIConstants
import com.yidianling.tests.list.view.TestCategoryListActivity
import com.yidianling.tests.router.TestsIn
import com.yidianling.tests.search.TestSearchActivity
import com.yidianling.ydlcommon.constant.UMConstants
import com.yidianling.ydlcommon.h5.H5Params
import com.yidianling.ydlcommon.h5.NewH5Activity
import com.yidianling.ydlcommon.http.YdlRetrofitUtils
import com.yidianling.ydlcommon.router.IYDLRouterConstant
import com.yidianling.ydlcommon.tool.BuryPointUtils
import com.yidianling.ydlcommon.utils.UMEventUtils
/**
* @author yuanwai
* @描述:测评首页点击事件实现类
* @Copyright Copyright (c) 2018
* @Company 壹点灵
* @date 2018/8/3
*/
class TestHomeEventImpl(mContext: Context) : ITestHomeEvent {
var context: Context? = null
init {
context = mContext
}
/**
* 跳转我的界面
*/
override fun jumpMine() {
UMEventUtils.umEvent(TestsBIConstants.EVENT_TEST_HOME_MINE_CLICK, "", "")
// TestHomeUtils.buildJumpMine(context!!)
if (!TestsIn.isLogin()) {
//如果未登录 走登录逻辑
context!!.startActivity(TestsIn.loginWayIntent(context as Activity))
return
}
val testParam = H5Params(YdlRetrofitUtils.MH5_URL + "ceshi/my-test", "测试记录")
NewH5Activity.start(context, testParam)
}
/**
* 跳转搜索界面
*/
override fun jumpSearch() {
UMEventUtils.umEvent(TestsBIConstants.EVENT_TEST_HOME_SEARCH_CLICK, "", "")
TestSearchActivity.start(context!!)
}
/**
* banner点击事件
*/
override fun bannerClick(linkUrl: String?, position: Int, title: String?) {
UMEventUtils.umEvent(TestsBIConstants.EVENT_TEST_HOME_BANNER_CLICK, TestsBIConstants.PROPERTY_TEST_HOME_BANNER_URL, linkUrl)
UMEventUtils.umEvent(TestsBIConstants.EVENT_TEST_HOME_BANNER_CLICK, TestsBIConstants.PROPERTY_TEST_HOME_BANNER_NAME, title)
//埋点
BuryPointUtils.getInstance().createMap()
.put("position", position)
.put("title", title)
.burryPoint("ceping_banner")
link(linkUrl)
}
/**
* 测评分类点击事件
*/
override fun categoryClick(tabName: String?, position: Int, title: String?, id: String?) {
UMEventUtils.umEvent(TestsBIConstants.EVENT_TEST_HOME_CATEGORY_CLICK, TestsBIConstants.PROPERTY_TEST_HOME_CATEGORY_NAME, title)
UMEventUtils.umEvent(TestsBIConstants.EVENT_TEST_HOME_CATEGORY_CLICK, TestsBIConstants.PROPERTY_TEST_HOME_CATEGORY_ID, id)
//埋点
BuryPointUtils.getInstance().createMap()
.put("position", position)
.put("title", title)
.burryPoint("ceping_icon")
// TestListActivity.start(context!!, tabName)
TestCategoryListActivity.start(context!!, tabName)
}
/**
* 实时测试状态点击事件
*/
override fun realTestClick(linkUrl: String?, title: String?) {
UMEventUtils.umEvent(TestsBIConstants.EVENT_TEST_HOME_LOOP_CLICK, TestsBIConstants.PROPERTY_TEST_HOME_LOOP_NAME, title)
//埋点
BuryPointUtils.getInstance().createMap()
.put("title", title)
.burryPoint("ceping_current")
link(linkUrl)
}
/**
* 每日精选点击事件
*/
override fun dailyClick(linkUrl: String?, position: Int, title: String?) {
UMEventUtils.umEvent(TestsBIConstants.EVENT_TEST_HOME_DAILY_CLICK, TestsBIConstants.PROPERTY_TEST_HOME_DAILY_NAME, title)
UMEventUtils.umEvent(TestsBIConstants.EVENT_TEST_HOME_DAILY_CLICK, TestsBIConstants.PROPERTY_TEST_HOME_DAILY_URL, title)
//埋点
BuryPointUtils.getInstance().createMap()
.put("position", position)
.put("title", title)
.burryPoint("ceping_Featured")
link(linkUrl)
}
/**
* 热门推荐点击事件
*/
override fun recommendedClick(linkUrl: String?, position: Int, title: String?) {
UMEventUtils.umEvent(TestsBIConstants.EVENT_TEST_HOME_HOT_CLICK, TestsBIConstants.PROPERTY_TEST_HOME_HOT_URL, linkUrl)
UMEventUtils.umEvent(TestsBIConstants.EVENT_TEST_HOME_HOT_CLICK, TestsBIConstants.PROPERTY_TEST_HOME_HOT_NAME, title)
//埋点
BuryPointUtils.getInstance().createMap()
.put("position", position)
.put("title", title)
.burryPoint("ceping_recommend")
link(linkUrl)
}
private fun link(linkUrl: String?) {
if (null == linkUrl || linkUrl.isEmpty()) {
return
}
if (linkUrl.startsWith("app")) {
val uri = Uri.parse(linkUrl)
if ("ceshi" == uri.host) {
val id = uri.getQueryParameter("id")
// YDLRouterManager.router(IYDLRouterConstant.ROUTER_TEST_DETAIL, YDLRouterParams().putExtra(IYDLRouterConstant.EXTRA_ID, id))
RouterManager.getTestsRouter()?.testDetailH5(id)
}
} else if (linkUrl.startsWith("http")) {
YDLRouterManager.router(
IYDLRouterConstant.ROUTER_H5_H5,
YDLRouterParams().putExtra(IYDLRouterConstant.EXTRA_URL, linkUrl), "")
} else {
YDLRouterManager.router(linkUrl)
}
}
/**
* 查看全部测评点击事件
*/
override fun selectAll() {
// TestListActivity.start(context!!)
TestCategoryListActivity.start(context!!)
}
}
\ No newline at end of file
package com.yidianling.tests.home.event
/**
* 更新优惠券金额
*/
class UpdateCouponMoneyEvent(val money: String)
package com.yidianling.tests.home.http
import com.yidianling.tests.home.bean.TestHomeDataBean
import com.yidianling.tests.home.param.TestHomeParam
import com.yidianling.ydlcommon.http.BaseResponse
import io.reactivex.Observable
/**
* @author yuanwai
* @描述:
* @Copyright Copyright (c) 2018
* @Company 壹点灵
* @date 2018/7/26
*/
interface ITestHomeHttp{
/**
* 测评首页请求
*/
fun newHomeRequest(testHomeParam: TestHomeParam): Observable<BaseResponse<List<TestHomeDataBean>>>
/**
* 每日精选--换一批
*/
fun dailyChange(testHomeParam: TestHomeParam): Observable<BaseResponse<TestHomeDataBean>>
}
\ No newline at end of file
package com.yidianling.tests.home.http
import com.yidianling.tests.home.bean.TestHomeDataBean
import com.yidianling.ydlcommon.http.BaseResponse
import io.reactivex.Observable
import retrofit2.http.FieldMap
import retrofit2.http.FormUrlEncoded
import retrofit2.http.POST
/**
* @author yuanwai
* @描述:测评首页API
* @Copyright Copyright (c) 2018
* @Company 壹点灵
* @date 2018/7/26
*/
interface TestHomeApi{
//测评首页
@FormUrlEncoded
@POST("ceshi/new-home")
fun newHome(@FieldMap params: Map<String, String>): Observable<BaseResponse<List<TestHomeDataBean>>>
//每日精选 换一批
@FormUrlEncoded
@POST("ceshi/flush-daily-selection")
fun dailySelection(@FieldMap params: Map<String, String>): Observable<BaseResponse<TestHomeDataBean>>
}
\ No newline at end of file
package com.yidianling.tests.home.http
/**
* @author yuanwai
* @描述:
* @Copyright Copyright (c) 2018
* @Company 壹点灵
* @date 2018/7/26
*/
object TestHomeDataManager{
fun getHttp(): ITestHomeHttp = TestHomeHttpImpl.getInstance()
}
\ No newline at end of file
package com.yidianling.tests.home.http
import com.yidianling.tests.home.bean.TestHomeDataBean
import com.yidianling.tests.home.param.TestHomeParam
import com.yidianling.ydlcommon.http.BaseResponse
import com.yidianling.ydlcommon.http.RetrofitProvider
import com.yidianling.ydlcommon.http.RxUtils
import io.reactivex.Observable
/**
* @author yuanwai
* @描述:
* @Copyright Copyright (c) 2018
* @Company 壹点灵
* @date 2018/7/26
*/
class TestHomeHttpImpl private constructor() : ITestHomeHttp {
companion object {
fun getInstance(): TestHomeHttpImpl {
return Holder.INSTANCE
}
fun clearTestHomeApi() {
Holder.INSTANCE.testHomeApi = null
}
}
object Holder {
val INSTANCE = TestHomeHttpImpl()
}
private var testHomeApi: TestHomeApi? = null
private fun getTestHomeApi(): TestHomeApi {
if (testHomeApi == null){
testHomeApi=RetrofitProvider.getRetrofit().create(TestHomeApi::class.java)
}
return testHomeApi!!
}
// private val testHomeApi: TestHomeApi by lazy {
// RetrofitProvider.getRetrofit().create(TestHomeApi::class.java)
// }
override fun newHomeRequest(testHomeParam: TestHomeParam): Observable<BaseResponse<List<TestHomeDataBean>>> {
return RxUtils.mapObservable(testHomeParam)
.flatMap {
getTestHomeApi().newHome(it)
}
}
override fun dailyChange(testHomeParam: TestHomeParam): Observable<BaseResponse<TestHomeDataBean>> {
return RxUtils.mapObservable(testHomeParam)
.flatMap {
getTestHomeApi().dailySelection(it)
}
}
fun fetchMaxCoupon(){
}
}
\ No newline at end of file
package com.yidianling.tests.home.model
import com.ydl.ydlcommon.data.http.RxUtils
import com.yidianling.tests.home.bean.TestHomeDataBean
import com.yidianling.tests.home.contract.ITestHomeContract
import com.yidianling.tests.home.http.TestHomeDataManager
import com.yidianling.tests.home.param.TestHomeParam
import io.reactivex.Observable
/**
* @author yuanwai
* @描述:测评首页数据模型实现类
* @Copyright Copyright (c) 2018
* @Company 壹点灵
* @date 2018/7/26
*/
class TestHomeModelImpl : ITestHomeContract.Model{
/**
* 测评首页
*/
override fun newHomeRequest() : Observable<List<TestHomeDataBean>> {
return TestHomeDataManager.getHttp().newHomeRequest(TestHomeParam( 0))
.compose(RxUtils.resultData())
}
/**
* 每日精选--换一批
*/
override fun dailyChange() : Observable<TestHomeDataBean>{
return TestHomeDataManager.getHttp().dailyChange(TestHomeParam( 1))
.compose(RxUtils.resultData())
}
}
\ No newline at end of file
package com.yidianling.tests.home.param
/**
* @author yuanwai
* @描述:测评首页请求参数bean
* @Copyright Copyright (c) 2018
* @Company 壹点灵
* @date 2018/7/26
*/
data class TestHomeParam(val type : Int)
\ No newline at end of file
package com.yidianling.tests.home.presenter
import com.ydl.ydlcommon.data.http.ThrowableConsumer
import com.ydl.ydlcommon.mvp.base.BasePresenter
import com.ydl.ydlcommon.utils.RxLifecycleUtils
import com.yidianling.tests.home.contract.ITestHomeContract
import com.yidianling.tests.home.model.TestHomeModelImpl
import com.yidianling.tests.home.utils.TestHomeUtils
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.functions.Consumer
/**
* @author yuanwai
* @描述:测评首页逻辑实现类
* @Copyright Copyright (c) 2018
* @Company 壹点灵
* @date 2018/7/26
*/
class TestHomePresenterImpl:
BasePresenter<ITestHomeContract.View, ITestHomeContract.Model>(), ITestHomeContract.Presenter{
/**
* 实例化数据模型
*/
override fun createModel(): ITestHomeContract.Model {
return TestHomeModelImpl()
}
/**
* 测评首页数据请求
*/
override fun newHomeRequest() {
val disposable = mModel.newHomeRequest()
.map { it }
.filter { it != null }
.observeOn(AndroidSchedulers.mainThread())
.compose(RxLifecycleUtils.bindToLifecycle(mView))//使用 Rxlifecycle,使 Disposable 和 Activity 一起销毁
.subscribe(Consumer {
mView.newHomeResponse(it)
}, object : ThrowableConsumer() {
override fun accept(msg: String) {
mView.showError(msg)
}
})
}
/**
* 加载更多
*/
override fun onLoadMore(page : Int) {
mView.loadMoreResponse(TestHomeUtils.getRecommedDataByPage(page))
}
/**
* 每日精选 换一批
*/
override fun dailyChange() {
val disposable = mModel.dailyChange()
.map { it }
.filter { it != null }
.observeOn(AndroidSchedulers.mainThread())
.compose(RxLifecycleUtils.bindToLifecycle(mView))
.subscribe(Consumer {
mView.dailyChangeResponse(it)
}, object : ThrowableConsumer() {
override fun accept(msg: String) {
mView.showError(msg)
}
})
}
}
\ No newline at end of file
package com.yidianling.tests.home.utils
import android.content.Context
import android.content.Intent
import android.text.SpannableString
import android.text.Spanned
import android.text.TextUtils
import android.text.style.TextAppearanceSpan
import android.view.View
import android.widget.TextView
import com.ydl.ydlcommon.data.http.RxUtils
import com.ydl.ydlcommon.router.YdlCommonRouterManager
import com.ydl.ydlcommon.utils.SharedPreferencesEditor
import com.yidianling.common.tools.LogUtil
import com.yidianling.tests.R
import com.yidianling.tests.TestRetrofitApi
import com.yidianling.tests.home.TestHomeActivity
import com.yidianling.tests.home.bean.TestHomeBodyBean
import com.yidianling.tests.home.bean.TestHomeDataBean
import com.yidianling.tests.home.config.ITestHomeConfig
import com.yidianling.tests.home.event.UpdateCouponMoneyEvent
import com.yidianling.ydlcommon.http.RxUtils
import com.yidianling.ydlcommon.http.ThrowableConsumer
import com.yidianling.ydlcommon.router.YdlCommonRouterManager
import com.yidianling.ydlcommon.utils.MainUtils
import com.yidianling.ydlcommon.utils.SharedPreferencesEditor
import de.greenrobot.event.EventBus
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.functions.Consumer
import io.reactivex.schedulers.Schedulers
import java.io.BufferedInputStream
import java.io.IOException
import java.io.InputStream
import java.math.BigDecimal
import java.text.DecimalFormat
import java.text.NumberFormat
/**
* @author yuanwai
* @描述:测评首页工具类
* @Copyright Copyright (c) 2018
* @Company 壹点灵
* @date 2018/7/28
*/
class TestHomeUtils {
companion object {
private var recommendListCache: List<TestHomeDataBean>? = null
val TEST_MAX_COUPON_MONEY_SP_KEY = "TestMaxCouponMoneySpKey"
/**
* 读取Assets下文本文件
*/
fun getAssertsFile(context: Context, fileName: String): ByteArray? {
var inputStream: InputStream? = null
val assetManager = context.assets
try {
inputStream = assetManager.open(fileName)
if (inputStream == null) {
return null
}
var bis: BufferedInputStream? = null
val length: Int
try {
bis = BufferedInputStream(inputStream)
length = bis.available()
val data = ByteArray(length)
bis.read(data)
return data
} catch (e: IOException) {
} finally {
if (bis != null) {
try {
bis.close()
} catch (e: Exception) {
}
}
}
return null
} catch (e: IOException) {
e.printStackTrace()
}
return null
}
/**
* 数据整合 将最后一个热门推荐数据 拆分成集合的形式
*/
fun resetData(list: List<TestHomeDataBean>): List<TestHomeDataBean> {
var dataList = ArrayList<TestHomeDataBean>()
for (item in list) {
if (item.type == ITestHomeConfig.TYPE_RECOMMENDED) {
resetRecommedData(item)
dataList.addAll(getRecommedDataByPage(1))
} else {
dataList.add(item)
}
}
return dataList
}
/**
* 因为热门推荐列表在一个body下
* 这个方法是将一个body拆分成多个body 供Recycleview使用
*/
private fun resetRecommedData(databean: TestHomeDataBean): List<TestHomeDataBean> {
if (null == recommendListCache) {
recommendListCache = ArrayList()
} else {
(recommendListCache as ArrayList<TestHomeDataBean>).clear()
}
var index = 0
for (item in databean.body!!) {
var bodyList = ArrayList<TestHomeBodyBean>()
//用于列表区分是否为第一个view 展示的样式是不同的
item.recommendIsFirst = index == 0
bodyList.add(item)
var testHomeDataBean = TestHomeDataBean(databean.type, bodyList, databean.category, databean.head, databean.footer, databean.diviLine)
(recommendListCache as ArrayList<TestHomeDataBean>).add(testHomeDataBean)
index++
}
return recommendListCache as ArrayList<TestHomeDataBean>
}
/**
* 根据页数返回下一页 热门推荐列表数据
*/
fun getRecommedDataByPage(page: Int): List<TestHomeDataBean> {
var dataList = ArrayList<TestHomeDataBean>()
if (page == 4) {
return dataList
}
for (i in (page - 1) * 10..((page - 1) * 10 + 9)) {
if (i < recommendListCache!!.size) {
dataList.add(recommendListCache!!.get(i))
}
}
return dataList
}
fun jumpTestHomeActivity(context: Context) {
val intent = Intent(context, TestHomeActivity::class.java)
context.startActivity(intent)
}
/**
* 返回拼接好的人气字符串
*/
fun getHits(context: Context, hits: String?): String {
if (TextUtils.isEmpty(hits)) {
return ""
}
var iHits = hits!!.toFloat()
var fnum = DecimalFormat("#.0") as NumberFormat
var hitBuffer = StringBuffer()
if (iHits >= 10000) {
iHits /= 10000
hitBuffer.append(fnum.format(iHits))
hitBuffer.append("万")
} else {
hitBuffer.append(iHits.toInt())
}
hitBuffer.append(context.resources.getString(R.string.testhome_hit))
return hitBuffer.toString()
}
fun getHitsNew(context: Context, hits: String?): String {
if (TextUtils.isEmpty(hits)) {
return ""
}
var iHits = hits!!.toFloat()
var fnum = DecimalFormat("#.0") as NumberFormat
var hitBuffer = StringBuffer()
if (iHits >= 10000) {
iHits /= 10000
hitBuffer.append(fnum.format(iHits))
hitBuffer.append("万")
} else {
hitBuffer.append(iHits.toInt())
}
return hitBuffer.toString()
}
/**
* 返回拼接好的多少人测过的字符串
*/
fun getNum(context: Context, num: String?): String {
var iNum = num!!.toDouble()
var fnum = DecimalFormat("#.0") as NumberFormat
var numBuffer = StringBuffer()
if (iNum >= 10000) {
iNum /= 10000
numBuffer.append(fnum.format(iNum))
numBuffer.append("万")
} else {
numBuffer.append(iNum.toInt())
}
numBuffer.append(context.resources.getString(R.string.testhome_peopletest))
return numBuffer.toString()
}
fun getNumNew(context: Context, num: String?): String {
var iNum = num!!.toDouble()
var fnum = DecimalFormat("#.0") as NumberFormat
var numBuffer = StringBuffer()
if (iNum >= 10000) {
iNum /= 10000
numBuffer.append(fnum.format(iNum))
numBuffer.append("万")
} else {
numBuffer.append(iNum.toInt())
}
return numBuffer.toString()
}
fun buildJumpMine(context: Context) {
val intent = Intent()
intent.putExtra(MainUtils.ACTION_TAG, MainUtils.JUMP_MAIN_TAB_CHANGE)
intent.putExtra(MainUtils.MAIN_TAB_INDEX, 4)
intent.setClassName(context, "com.cxzapp.yidianling.MainActivity")
intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP
context.startActivity(intent)
}
/**
* 根据截取的位置 设置文本大小
*/
fun priceStyle(context: Context, textView: TextView, content: String, subIndex: Int, EndIndex: Int) {
val sp = SpannableString(content)
sp.setSpan(TextAppearanceSpan(context, R.style.style_price_start), 0, subIndex, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
sp.setSpan(TextAppearanceSpan(context, R.style.style_price_end), subIndex, EndIndex, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
textView.text = sp
}
/**
* 根据截取的位置 设置文本大小
*/
fun priceStyleNew(context: Context, textView: TextView, content: String, subIndex: Int, EndIndex: Int) {
val sp = SpannableString(content)
sp.setSpan(TextAppearanceSpan(context, R.style.style_price_end), 0, subIndex, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
sp.setSpan(TextAppearanceSpan(context, R.style.style_price_start), subIndex, EndIndex, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
textView.text = sp
}
/**
* 更新优惠券信息
* 只有当和上一次优惠券金额不一致时才会发事件通知更新
*/
fun updateCouponMoney(){
val loginBean = YdlCommonRouterManager.getYdlCommonRoute().getUserInfo()
var userId = loginBean?.userId ?: "";
TestRetrofitApi.getTestRetrofitApi()
.fetchMaxCoupon(userId)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.compose(RxUtils.resultJavaData())
.subscribe(Consumer {
var lastCouponMoney = SharedPreferencesEditor.getString(TEST_MAX_COUPON_MONEY_SP_KEY)
if (TextUtils.isEmpty(lastCouponMoney)|| lastCouponMoney !== it.toString()){
SharedPreferencesEditor.putString(TEST_MAX_COUPON_MONEY_SP_KEY,it.toString())
EventBus.getDefault().post(UpdateCouponMoneyEvent(it))
}
}, object : ThrowableConsumer() {
override fun accept(msg: String) {
LogUtil.i(msg)
}
})
}
/**
* 获取真实测试题价格
* 减去优惠券价格
* 如果为空则隐藏优惠券提示
*/
fun getOriginalPrice(tv_coupon_money:TextView,price:String?,couponMoney:String):String{
var couponMoney = couponMoney
if (!TextUtils.isEmpty(couponMoney)
&& "0" != couponMoney
&& "0.0" != couponMoney
&& "0.00" != couponMoney){
tv_coupon_money.visibility = View.VISIBLE
tv_coupon_money.text = String.format("券已抵扣%s元",couponMoney)
}else{
tv_coupon_money.visibility = View.GONE
couponMoney = "0.0"
}
var newPrice = price
if ("元" == price?.substring(price.length-1,price.length)){
newPrice = price.substring(0,price.length-1)
}
var numberPrice = BigDecimal(newPrice).toDouble()
if (numberPrice <= BigDecimal(couponMoney).toDouble()){
newPrice = "0.00"
}else{
// newPrice = (numberPrice - couponMoney).toString()
//解决Double相减精度损失
val bd1 = BigDecimal(newPrice)
val bd2 = BigDecimal(couponMoney)
newPrice = bd1.subtract(bd2).toDouble().toString()
}
return newPrice
}
}
}
\ No newline at end of file
package com.yidianling.tests.home.widget
import android.support.v7.widget.RecyclerView
import android.support.v7.widget.LinearLayoutManager
import android.support.v7.widget.GridLayoutManager
import android.widget.AbsListView.OnScrollListener.SCROLL_STATE_IDLE
import com.yidianling.tests.home.adapter.AdapterWrapper
import com.yidianling.tests.home.config.ITestHomeConfig
/**
* @author yuanwai
* @描述:上拉加载更多帮助类
* @Copyright Copyright (c) 2018
* @Company 壹点灵
* @date 2018/7/26
*/
class SwipeToLoadHelper(recyclerView: RecyclerView, private val mAdapterWrapper: AdapterWrapper) : RecyclerView.OnScrollListener() ,AdapterWrapper.FooterCallBack{
private val mRecyclerView: RecyclerView? = null
private val mLayoutManager: RecyclerView.LayoutManager
private var mListener: LoadMoreListener? = null
/** 是否正在加载中 */
private var mLoading = false
/** 上拉刷新功能是否开启 */
private var mIsSwipeToLoadEnabled = true
init {
mLayoutManager = recyclerView.layoutManager
if (mLayoutManager is GridLayoutManager) {
mAdapterWrapper.setAdapterType(AdapterWrapper.ADAPTER_TYPE_GRID)
mAdapterWrapper.setSpanCount(mLayoutManager.spanCount)
} else if (mLayoutManager is LinearLayoutManager) {
mAdapterWrapper.setAdapterType(AdapterWrapper.ADAPTER_TYPE_LINEAR)
}
mAdapterWrapper.setFooterCallBack(this)
// 将OnScrollListener设置RecyclerView
recyclerView.addOnScrollListener(this)
}
override fun onScrollStateChanged(recyclerView: RecyclerView?, newState: Int) {
if (mIsSwipeToLoadEnabled && SCROLL_STATE_IDLE === newState && !mLoading) {
if (mLayoutManager is GridLayoutManager) {
val gridLayoutManager = mLayoutManager
gridLayoutManager.spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() {
override fun getSpanSize(position: Int): Int {
return if (mIsSwipeToLoadEnabled) {
// 功能开启, 根据位置判断, 最后一个item时返回整个宽度, 其他位置返回1
// AdapterWrapper会保证最后一个item会从新的一行开始
if (position == mLayoutManager.getItemCount() - 1) {
gridLayoutManager.spanCount
} else {
1
}
} else {
1
}
}
}
}
if (mLayoutManager is LinearLayoutManager) {
val linearLayoutManager = mLayoutManager
val lastCompletePosition = linearLayoutManager.findLastCompletelyVisibleItemPosition()
// only when the complete visible item is second last
if (lastCompletePosition == mLayoutManager.getItemCount() - 2) {
val firstCompletePosition = linearLayoutManager.findFirstCompletelyVisibleItemPosition()
val child = linearLayoutManager.findViewByPosition(lastCompletePosition)
?: return
val deltaY = recyclerView!!.bottom - recyclerView.paddingBottom - child.bottom
if (deltaY > 0 && firstCompletePosition != 0) {
recyclerView.smoothScrollBy(0, -deltaY)
}
} else if (lastCompletePosition == mLayoutManager.getItemCount() - 1) {
// 最后一项完全显示, 触发操作, 执行加载更多操作 禁用回弹判断
mLoading = true
mAdapterWrapper.setLoadItemState(ITestHomeConfig.STATUS_LOADING)
if (mListener != null) {
mListener!!.onLoad()
}
}
}
}
}
override fun onScrolled(recyclerView: RecyclerView?, dx: Int, dy: Int) {
super.onScrolled(recyclerView, dx, dy)
}
/** 设置下拉刷新功能是否开启 */
fun setSwipeToLoadEnabled(isSwipeToLoadEnabled: Boolean) {
if (mIsSwipeToLoadEnabled != isSwipeToLoadEnabled) {
mIsSwipeToLoadEnabled = isSwipeToLoadEnabled
mAdapterWrapper.setLoadItemVisibility(isSwipeToLoadEnabled)
}
}
/** 设置LoadMore Item为加载完成状态, 上拉加载更多完成时调用 */
fun setLoadMoreFinish() {
mLoading = false
mAdapterWrapper.setLoadItemState(ITestHomeConfig.STATUS_UP_LOAD)
}
/**
* 设置LoadMore Item为没有更多数据状态 显示查看全部测评
*/
fun setNoMoreData(){
mLoading = false
mAdapterWrapper.setLoadItemState(ITestHomeConfig.STATUS_SELECT_ALL)
}
override fun selectAll() {
mListener!!.selectAll()
}
/** 上拉操作触发时调用的接口 */
fun setLoadMoreListener(loadMoreListener: LoadMoreListener) {
mListener = loadMoreListener
}
interface LoadMoreListener {
/**
* 加载更多
*/
fun onLoad()
/**
* 查看全部测评
*/
fun selectAll()
}
}
\ No newline at end of file
package com.yidianling.tests.home.widget
import android.content.Context
import android.support.v4.view.PagerAdapter
import android.support.v4.view.ViewPager
import android.view.View
import android.widget.ImageView
import com.ydl.ydl_image.module.GlideApp
import com.yidianling.tests.R
import com.yidianling.tests.home.bean.TestHomeBodyBean
import com.yidianling.tests.home.event.ITestHomeEvent
import java.util.*
/**
* @author yuanwai
* @描述:测评首页banner viewpager适配器
* @Copyright Copyright (c) 2018
* @Company 壹点灵
* @date 2018/7/27
*/
class TestHomeBannerAdapter(
/**
* 数据集合
*/
var mDataList: List<TestHomeBodyBean>,
var mContext: Context,
var testHomeEvent: ITestHomeEvent) : PagerAdapter() {
private var mImageViews: List<ImageView>? = null
/**
* 初始化
*/
init {
updataImage()
}
/**
* 更新图片集合 todo 待优化 yuanwai 2018/07/27
*/
private fun updataImage() {
if (null == mImageViews || mImageViews!!.isEmpty()) {
mImageViews = ArrayList()
} else {
(mImageViews as ArrayList).clear()
}
var count = mDataList.size - 1
for (index in 0..count) {
var item = mDataList[index]
val imageView = ImageView(mContext)
imageView.scaleType = ImageView.ScaleType.FIT_XY
GlideApp.with(mContext)
.load(item.bannerImageUrl)
.placeholder(R.drawable.testhome_banner_nor)
.centerCrop()
.into(imageView)
(mImageViews as ArrayList<ImageView>).add(imageView)
imageView.setOnClickListener {
testHomeEvent.bannerClick(item.bannerLinkUrl, index, item.bannerName)
}
}
}
override fun getCount(): Int {
return mDataList.size
}
/**
* 数据更新
*/
fun updataItems(items: List<TestHomeBodyBean>) {
if (items.isEmpty()) {
return
}
if (null == mDataList) {
mDataList = ArrayList()
} else {
(mDataList as ArrayList).clear()
}
(mDataList as ArrayList<TestHomeBodyBean>).addAll(items)
updataImage()
notifyDataSetChanged()
}
override fun isViewFromObject(view: View, `object`: Any): Boolean {
return view === `object`
}
override fun destroyItem(container: View?, position: Int, `object`: Any?) {
}
override fun instantiateItem(container: View?, position: Int): Any {
try {
(container as ViewPager).addView(mImageViews!!.get(position % mDataList.size), 0)
} catch (e: Exception) {
}
return mImageViews!!.get(position % mDataList.size)
}
}
\ No newline at end of file
package com.yidianling.tests.home.widget
import android.content.Context
import android.view.View
import android.view.ViewGroup
import android.widget.FrameLayout
import com.yidianling.common.tools.RxImageTool
import com.yidianling.tests.R
import com.yidianling.tests.home.bean.TestHomeBodyBean
import com.yidianling.tests.home.bean.TestHomeDataBean
import com.yidianling.tests.home.event.ITestHomeEvent
import com.yidianling.ydlcommon.view.banner.GlideImageLoader
import kotlinx.android.synthetic.main.testhome_banner_view.view.*
/**
* @author yuanwai
* @描述:测评首页banner
* @Copyright Copyright (c) 2018
* @Company 壹点灵
* @date 2018/7/27
*/
class TestHomeBannerView(context: Context?, testHomeEvent: ITestHomeEvent) : FrameLayout(context) {
/**
* banner数据缓存
*/
private var mDataList: List<TestHomeBodyBean>? = null
/**
* 数据缓存
*/
private var mDataBean: TestHomeDataBean? = null
private var testHomeEvent: ITestHomeEvent? = null
private var dp14 = 0
private var dp4 = 0
private var margin = 0
private var isRefresh: Boolean? = false
init {
this.testHomeEvent = testHomeEvent
initView()
}
private fun initView() {
val params = FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
View.inflate(context, R.layout.testhome_banner_view, this)
layoutParams = params
dp14 = RxImageTool.dip2px(14f)
dp4 = RxImageTool.dip2px(4f)
margin = RxImageTool.dip2px(2.5f)
}
fun setRefresh(isRefresh: Boolean) {
this.isRefresh = isRefresh
}
fun initData(dataBean: TestHomeDataBean) {
if (isRefresh!!) {
return
}
isRefresh = true
if (null == dataBean ||
(dataBean.body == null && null == dataBean.category) ||
(dataBean.body!!.isEmpty() && dataBean.category!!.isEmpty())) {
visibility = View.GONE
return
}
mDataBean = dataBean
visibility = View.VISIBLE
if (null == mDataList) {
mDataList = ArrayList()
} else {
(mDataList as ArrayList).clear()
}
(mDataList as ArrayList<TestHomeBodyBean>).addAll(mDataBean!!.body!!)
var urlLists = ArrayList<String>()
var count = (mDataList as ArrayList<TestHomeBodyBean>).size - 1
for (index in 0..count) {
urlLists.add((mDataList as ArrayList<TestHomeBodyBean>)[index].bannerImageUrl!!)
}
banner.setImageLoader(GlideImageLoader(R.drawable.testhome_banner_nor)).setImages(urlLists).start()
banner.setOnBannerListener {
testHomeEvent!!.bannerClick((mDataList as ArrayList<TestHomeBodyBean>)[it].bannerLinkUrl, it, (mDataList as ArrayList<TestHomeBodyBean>)[it].bannerName)
}
// initAdapter()
// initTimer()
}
// /**
// * 更新适配器
// */
// private fun initAdapter() {
// isInitFinish = false
//
// if (null == bannerAdapter) {
// bannerAdapter = TestHomeBannerAdapter(mDataList as ArrayList<TestHomeBodyBean>, context, testHomeEvent!!)
// viewPager.adapter = bannerAdapter
// } else {
// bannerAdapter!!.updataItems(mDataList as ArrayList<TestHomeBodyBean>)
// }
// viewPager.addOnPageChangeListener(object : ViewPager.OnPageChangeListener {
// override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {
// }
//
// override fun onPageSelected(position: Int) {
// countImg = position
// setImageBackground(position % tips!!.size)
// }
//
// override fun onPageScrollStateChanged(state: Int) {
// }
//
// })
// updataPoint()
// isInitFinish = true
// countImg = 0
// }
//
// /**
// * 更新viewpager 指示器原点
// */
// private fun updataPoint() {
// if (null == tips) {
// tips = ArrayList()
// } else {
// (tips as ArrayList).clear()
// }
// ll_tips!!.removeAllViews()
// var index = 0
// var imageWidth = 0
// for (item in mDataList!!) {
// val imageView = ImageView(context)
//
// if (index == 0) {
// imageWidth = dp14
// imageView.setBackgroundResource(R.drawable.testhome_tip_select)
// } else {
// imageWidth = dp4
// imageView.setBackgroundResource(R.drawable.testhome_tip_unselect)
// }
// var layoutParams = LinearLayout.LayoutParams(imageWidth, dp4)
// imageView.scaleType = ImageView.ScaleType.FIT_XY
// layoutParams.leftMargin = margin
// layoutParams.rightMargin = margin
// imageView.layoutParams = layoutParams
// index++
// (tips as ArrayList<ImageView>).add(imageView)
// ll_tips!!.addView(imageView)
// }
// }
//
// /**
// * 改变图片
// */
// private fun setImageBackground(selectItems: Int) {
// var count = tips!!.size
// var imageWidth = 0
// for (i in 0..count) {
// var imageView = ll_tips!!.getChildAt(i)
// if (null == imageView) {
// return
// }
// if (imageView !is ImageView) {
// return
// }
// if (i == selectItems) {
// imageWidth = dp14
// imageView.setBackgroundResource(R.drawable.testhome_tip_select)
// } else {
// imageWidth = dp4
// imageView.setBackgroundResource(R.drawable.testhome_tip_unselect)
// }
// var params = LinearLayout.LayoutParams(imageWidth, dp4)
// params.leftMargin = margin
// params.rightMargin = margin
// imageView.layoutParams = params
// }
// }
//
// override fun dispatchTouchEvent(ev: MotionEvent): Boolean {
// val action = ev.action
// if (action == MotionEvent.ACTION_DOWN) {
// timeDown = System.currentTimeMillis()
// viewPager.isClick = true
// } else if (action == MotionEvent.ACTION_UP) {
// timeUp = System.currentTimeMillis()
// viewPager.isClick = false
// }
// return super.dispatchTouchEvent(ev)
// }
// private var dcTime = 0
//
// private fun initTimer() {
// //计时,如果没有用户干预,每5秒进行vp操作,
// if (null != mTimer) {
// dcTime = 0
// mTimer!!.cancel()
// }
// mTimer = Timer(true)
// mTimer!!.schedule(object : TimerTask() {
// override fun run() {
// if (isNeedStop) {
// return
// }
// dcTime++
// if (dcTime % 5 == 0) {
// updateUI()
// }
// }
// }, 0, 1000)
// }
// internal fun updateUI() {
// if (!isInitFinish)
// return
//
// Observable.just(0)
// .observeOn(AndroidSchedulers.mainThread())
// .subscribe { integer ->
//
// countImg++
// countImg %= if (bannerAdapter!!.count == 0) 1 else bannerAdapter!!.count
// viewPager.currentItem = countImg
// }
// }
fun startBanner() {
if (banner != null) {
banner.startAutoPlay()
}
}
fun stopBanner() {
if (banner != null) {
banner.stopAutoPlay()
}
}
}
\ No newline at end of file
package com.yidianling.tests.home.widget
import android.content.Context
import android.util.TypedValue
import android.view.Gravity
import android.view.View
import android.view.ViewGroup
import android.widget.FrameLayout
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.TextView
import com.ydl.ydl_image.module.GlideApp
import com.yidianling.common.tools.RxImageTool
import com.yidianling.tests.R
import com.yidianling.tests.home.bean.TestHomeBodyBean
import com.yidianling.tests.home.bean.TestHomeCategoryBean
import com.yidianling.tests.home.bean.TestHomeDataBean
import com.yidianling.tests.home.event.ITestHomeEvent
import com.yidianling.ydlcommon.utils.ScreenUtil
import kotlinx.android.synthetic.main.testhome_category_view.view.*
import java.util.*
/**
* @author yuanwai
* @描述:测评首页测评分类View
* @Copyright Copyright (c) 2018
* @Company 壹点灵
* @date 2018/7/27
*/
class TestHomeCategoryView(mContext: Context, testHomeEvent: ITestHomeEvent) : LinearLayout(mContext) {
/**
* 数据缓存
*/
var mDataList: List<TestHomeCategoryBean>? = null
/**
* 分类view宽度
*/
var categoryWidth: Int = 0
/**
* 图片宽高
*/
var imageViewWidth: Int = 0
/**
* 文本宽度
*/
var textViewWidth: Int = 0
/**
* 文本高度
*/
var textViewHeight: Int = 0
/**
* 间隔
*/
var margin: Int = 0
var dp8: Int = 0
/**
* 是否添加了实时测试状态View
*/
var hasRealTestView: Boolean = false
private var realTestView: TestHomeRealTestView? = null
/**
* 线
*/
private var lineView: View? = null
/**
* 图片View缓存
*/
private var imageViewCache: List<ImageView>? = null
/**
* 文本View缓存
*/
private var textViewCache: List<TextView>? = null
/**
* 倍数
*/
private var multiple: Int = 0
/**
* 测评首页事件处理类
*/
private var testHomeEvent: ITestHomeEvent? = null
init {
initView()
this.testHomeEvent = testHomeEvent
}
/**
* 界面初始化
*/
private fun initView() {
orientation = VERTICAL
View.inflate(context, R.layout.testhome_category_view, this)
val params = ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
layoutParams = params
initArgs()
}
/**
* 初始化变量
*/
private fun initArgs() {
categoryWidth = ScreenUtil.screenWidth - RxImageTool.dp2px(30f)
textViewWidth = categoryWidth / 4
imageViewWidth = RxImageTool.dip2px(38f)
margin = (categoryWidth - 4 * imageViewWidth) / 8
dp8 = RxImageTool.dip2px(8f)
//高度=文字12dp+16dp间距
textViewHeight = RxImageTool.dip2px(28f)
}
fun initData(bean: TestHomeDataBean) {
if (null == bean ||
(bean.body == null && bean.category == null) ||
(bean.body!!.isEmpty() && bean.category!!.isEmpty())) {
visibility = View.GONE
return
}
visibility = View.VISIBLE
if (null == mDataList) {
mDataList = ArrayList<TestHomeCategoryBean>()
} else {
(mDataList as ArrayList).clear()
}
(mDataList as ArrayList<TestHomeCategoryBean>).addAll(bean.category!!)
refreshView()
setRealTextView(bean.body)
}
/**
* 刷新View
*/
private fun refreshView() {
var i = 0
if (null == imageViewCache) {
imageViewCache = ArrayList()
}
if (null == textViewCache) {
textViewCache = ArrayList()
}
var imageCount = imageViewCache!!.size
for (item in this!!.mDataList!!) {
if (i > 7) {
break
}
if (i >= imageCount) {
val imageView = createIcon(i)
val textView = createText(i)
(imageViewCache as ArrayList).add(imageView)
(textViewCache as ArrayList).add(textView)
fl_root.addView(imageView)
fl_root.addView(textView)
imageView.setOnClickListener {
testHomeEvent!!.categoryClick(item.categoryTab, i, item.categoryName, item.categoryId)
}
textView.setOnClickListener {
testHomeEvent!!.categoryClick(item.categoryTab, i, item.categoryName, item.categoryId)
}
}
bindIconData(imageViewCache!!.get(i), item)
bindTextData(textViewCache!!.get(i), item)
i++
}
}
/**
* 创建图标
*/
private fun createIcon(i: Int): ImageView {
val imageParams = FrameLayout.LayoutParams(imageViewWidth, imageViewWidth)
val imageView = ImageView(context)
imageView.scaleType = ImageView.ScaleType.CENTER_CROP
if (i > 3) {
multiple = 2
imageParams.topMargin = imageViewWidth + dp8 + textViewHeight
imageParams.leftMargin = margin * (i - 3) + (i - 4) * (imageViewWidth + margin)
} else {
multiple = 1
imageParams.leftMargin = margin * (i + 1) + i * (imageViewWidth + margin)
}
imageView.layoutParams = imageParams
return imageView
}
/**
* 加载图片
*/
private fun bindIconData(imageView: ImageView, categoryBean: TestHomeCategoryBean) {
GlideApp.with(context).load(categoryBean.categoryUrl).placeholder(R.drawable.testhome_type_nor)
.centerCrop().into(imageView)
}
/**
* 创建文本
*/
private fun createText(index: Int): TextView {
val textParams = FrameLayout.LayoutParams(textViewWidth, textViewHeight)
val textView = TextView(context)
textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 12f)
textView.gravity = Gravity.CENTER_HORIZONTAL
if (index > 3) {
textParams.topMargin = 2 * (imageViewWidth + dp8) + textViewHeight
textParams.leftMargin = textViewWidth * (index - 4)
} else {
textParams.topMargin = imageViewWidth + dp8
textParams.leftMargin = textViewWidth * (index)
}
textView.layoutParams = textParams
return textView
}
/**
* 设置文本
*/
private fun bindTextData(textView: TextView, categoryBean: TestHomeCategoryBean) {
textView.text = categoryBean.categoryName
}
/**
* 初始化实时测评状态View
*/
private fun initRealTextView() {
var realTestParam = FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
realTestParam.topMargin = multiple * (imageViewWidth + dp8 + textViewHeight) + dp8 + RxImageTool.dip2px(10f)
realTestView = TestHomeRealTestView(context, testHomeEvent!!)
realTestView!!.layoutParams = realTestParam
}
private fun initLineView() {
var lineParam = FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, RxImageTool.dip2px(0.5f))
var dp15 = RxImageTool.dip2px(15f)
lineParam.leftMargin = dp15
lineParam.rightMargin = dp15
lineParam.topMargin = multiple * (imageViewWidth + dp8 + textViewHeight) + dp8
lineView = View(context)
lineView!!.setBackgroundColor(resources.getColor(R.color.testhome_line))
lineView!!.layoutParams = lineParam
}
/**
* 实时测评状态赋值
*/
private fun setRealTextView(list: List<TestHomeBodyBean>) {
if (!hasRealTestView) {
initLineView()
fl_root.addView(lineView)
initRealTextView()
fl_root.addView(realTestView)
hasRealTestView = true
}
realTestView!!.initData(list)
}
fun onDestory() {
if (null == realTestView) {
return
}
realTestView!!.onDestory()
}
}
\ No newline at end of file
package com.yidianling.tests.home.widget
import android.content.Context
import android.graphics.Color
import android.support.v7.widget.CardView
import android.text.TextUtils
import android.view.View
import android.view.ViewGroup
import android.widget.LinearLayout
import com.ydl.ydl_image.module.GlideApp
import com.yidianling.common.tools.RxImageTool
import com.yidianling.tests.R
import com.yidianling.tests.home.bean.TestHomeBodyBean
import com.yidianling.tests.home.event.ITestHomeEvent
import com.yidianling.tests.home.utils.TestHomeUtils
import kotlinx.android.synthetic.main.testhome_dailyitem_view.view.*
/**
* @author yuanwai
* @描述:每日精选itemView
* @Copyright Copyright (c) 2018
* @Company 壹点灵
* @date 2018/8/1
*/
class TestHomeDailyHorizoItemView(mContext: Context, testHomeEvent: ITestHomeEvent, isRight: Boolean) : CardView(mContext) {
/**
* 测评首页事件处理类
*/
private var testHomeEvent: ITestHomeEvent? = null
private var isRight: Boolean? = false
var couponMoney = ""
init {
this.testHomeEvent = testHomeEvent
this.isRight = isRight
initView()
}
/**
* 界面初始化
*/
private fun initView() {
var params = LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)
View.inflate(context, R.layout.testhome_dailyitem_view, this)
var dp6 = RxImageTool.dip2px(6f)
if (isRight!!) {
params.setMargins(dp6, RxImageTool.dip2px(5f), RxImageTool.dip2px(15f), RxImageTool.dip2px(5f))
} else {
params.setMargins(dp6, RxImageTool.dip2px(5f), dp6, RxImageTool.dip2px(5f))
}
layoutParams = params
radius = RxImageTool.dip2px(6f).toFloat()
cardElevation = RxImageTool.dip2px(2f).toFloat()
}
/**
* 设置数据
*/
fun initData(bodyBean: TestHomeBodyBean, position: Int) {
GlideApp.with(context).load(bodyBean.dailyImageUrl)
.placeholder(R.drawable.testhome_list_nor)
.centerCrop().into(img_icon)
tv_title.text = bodyBean.dailyTitle
tv_content.text = TestHomeUtils.getNum(context, bodyBean.dailyContent)
setPrice(bodyBean.price)
setOnClickListener {
testHomeEvent!!.dailyClick(bodyBean.dailyLinkUrl, position, bodyBean.dailyTitle)
}
}
private fun setPrice(price : String?){
if (TextUtils.isEmpty(price)){
tv_price.visibility = View.INVISIBLE
return
}
tv_price.visibility = View.VISIBLE
if (price.equals("免费")
||TextUtils.isEmpty(price)
|| "0" == price
|| "0.0" == price
|| "0.00" == price){
tv_price.text = "免费"
tv_price.setBackgroundResource(R.drawable.testhome_recom_price_bg)
tv_price.setTextColor(Color.parseColor("#34CD65"))
} else {
var newPrice = TestHomeUtils.getOriginalPrice(tv_coupon_money,price,couponMoney)
var priceContent = "¥$newPrice"
TestHomeUtils.priceStyleNew(context, tv_price, priceContent, 1, priceContent.length)
tv_price.setBackgroundResource(R.drawable.testhome_null)
}
}
}
\ No newline at end of file
package com.yidianling.tests.home.widget
import android.content.Context
import android.view.View
import android.widget.HorizontalScrollView
import com.yidianling.tests.R
import com.yidianling.tests.home.bean.TestHomeBodyBean
import com.yidianling.tests.home.event.ITestHomeEvent
import kotlinx.android.synthetic.main.testhome_dailyhorizo_view.view.*
/**
* @author yuanwai
* @描述:测评首页--每日精选横向滚动父View
* @Copyright Copyright (c) 2018
* @Company 壹点灵
* @date 2018/8/1
*/
class TestHomeDailyHorizoView(mContext: Context, testHomeEvent: ITestHomeEvent) : HorizontalScrollView(mContext) {
private var testHomeEvent: ITestHomeEvent? = null
var couponMoney = ""
init {
this.testHomeEvent = testHomeEvent
initView()
}
/**
* 界面初始化
*/
private fun initView() {
View.inflate(context, R.layout.testhome_dailyhorizo_view, this)
isVerticalScrollBarEnabled = false
isHorizontalScrollBarEnabled = false
}
/**
* 设置数据
*/
fun initData(list: List<TestHomeBodyBean>) {
var index = 0
for (item in list) {
if (index >= ll_root.childCount) {
if (index == list.size - 1) {
//如果没创建 就创建view并赋值
ll_root.addView(TestHomeDailyHorizoItemView(context, testHomeEvent!!, true))
} else {
//如果没创建 就创建view并赋值
ll_root.addView(TestHomeDailyHorizoItemView(context, testHomeEvent!!, false))
}
}
//如果view已创建 那就重新赋值
var childView = ll_root.getChildAt(index)
if (childView is TestHomeDailyHorizoItemView) {
childView.couponMoney = this.couponMoney
childView.initData(item, index)
}
index++
}
//如果本次数据小于上一次的数据 那就将多余的View 隐藏掉
if (index < childCount) {
for (i in index..childCount) {
getChildAt(i).visibility = View.GONE
}
}
}
}
\ No newline at end of file
package com.yidianling.tests.home.widget
import android.content.Context
import android.view.View
import android.view.ViewGroup
import android.widget.RelativeLayout
import com.yidianling.common.tools.RxImageTool
import com.yidianling.tests.R
import com.yidianling.tests.home.bean.TestHomeDataBean
import com.yidianling.tests.home.contract.ITestHomeContract
import com.yidianling.tests.home.event.ITestHomeEvent
import kotlinx.android.synthetic.main.testhome_daily_view.view.*
/**
* @author yuanwai
* @描述:测评首页--每日精选View
* @Copyright Copyright (c) 2018
* @Company 壹点灵
* @date 2018/7/27
*/
class TestHomeDailyView(mContext: Context,
testHomeEvent: ITestHomeEvent,
testHomeView: ITestHomeContract.View
)
: RelativeLayout(mContext) {
/**
* 数据缓存
*/
private var mDataBean: TestHomeDataBean? = null
private var mView: View? = null
private var testHomeEvent: ITestHomeEvent? = null
private var testHomeView: ITestHomeContract.View? = null
/**
* 底部线是否添加
*/
private var hasLine: Boolean = false
var couponMoney = ""
init {
this.testHomeView = testHomeView
this.testHomeEvent = testHomeEvent
initView()
}
/**
* 界面初始化
*/
private fun initView() {
var params = RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
layoutParams = params
mView = View.inflate(context, R.layout.testhome_daily_view, this)
testhome_dailyRight.setOnClickListener {
testHomeView!!.dailyChange()
}
}
/**
* 设置数据
*/
fun initData(dataBean: TestHomeDataBean) {
//如果数据为空 隐藏当前View
if (null == dataBean || null == dataBean.body || dataBean.body.isEmpty()) {
visibility = View.GONE
return
}
visibility = View.VISIBLE
mDataBean = dataBean
refreshView()
}
/**
* 界面刷新
*/
fun refreshView() {
//标题赋值
createTitle()
//列表赋值
createDailyHorizo()
addBottomLine()
}
/**
* 创建标题
*/
private fun createTitle() {
if (null == mDataBean) {
tv_title.text = ""
return
}
tv_title.text = mDataBean!!.head!!.title
}
/**
* 创建每日精选横向滚动View
*/
private fun createDailyHorizo() {
var dailyHorizoView = getChildAt(childCount - 2)
if (dailyHorizoView is TestHomeDailyHorizoView) {
dailyHorizoView.couponMoney = this.couponMoney
dailyHorizoView.initData(mDataBean!!.body!!)
} else {
var params = RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
dailyHorizoView = TestHomeDailyHorizoView(context, testHomeEvent!!)
dailyHorizoView.id = R.id.testhome_daily
dailyHorizoView.couponMoney = this.couponMoney
dailyHorizoView.initData(mDataBean!!.body!!)
params.addRule(BELOW, R.id.tv_title)
params.leftMargin = RxImageTool.dip2px(9f)
dailyHorizoView.layoutParams = params
addView(dailyHorizoView)
}
}
/**
* 添加底部灰色线
*/
private fun addBottomLine() {
if (!hasLine) {
hasLine = true
var param = RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, RxImageTool.dip2px(9f))
var bottomLine = View(context)
bottomLine.setBackgroundColor(resources.getColor(R.color.testhome_line))
param.addRule(BELOW, R.id.testhome_daily)
bottomLine.layoutParams = param
addView(bottomLine)
}
}
}
\ No newline at end of file
package com.yidianling.tests.home.widget
import android.content.Context
import android.os.Handler
import android.os.Looper
import android.os.Message
import android.view.View
import android.view.ViewGroup
import android.view.animation.Animation
import android.view.animation.DecelerateInterpolator
import android.view.animation.TranslateAnimation
import android.widget.FrameLayout
import com.yidianling.tests.R
import com.yidianling.tests.home.bean.TestHomeBodyBean
import com.yidianling.tests.home.event.ITestHomeEvent
import kotlinx.android.synthetic.main.testhome_realtest_view_in.view.*
import kotlinx.android.synthetic.main.testhome_realtest_view_out.view.*
/**
* @author yuanwai
* @描述:测评首页--实时测试状态View
* @Copyright Copyright (c) 2018
* @Company 壹点灵
* @date 2018/7/28
*/
class TestHomeRealTestView(mContext : Context,testHomeEvent : ITestHomeEvent) : FrameLayout(mContext){
private val STATUS_IN = 0
private val STATUS_OUT = 1
private var curTipIndex = 0
private var lastTimeMillis: Long = 0
private val ANIM_DELAYED_MILLIONS = 2 * 1000
/**
* 动画持续时长
*/
private val ANIM_DURATION = 500
/**
* 进、出 两个view (主要用于做动画,其实是两个相同的布局文件)
*/
private var view_out: View? = null
private var view_in:View? = null
/**
* 进、出 两个View 的动画
*/
private var anim_out: Animation? = null
private var anim_in:Animation? = null
/**
* 数据缓存
*/
private var mDataList : List<TestHomeBodyBean>? = null
private var testHomeEvent : ITestHomeEvent? = null
private val mHandler: Handler = object : Handler(Looper.getMainLooper()) {
override fun handleMessage(msg: Message?) {
super.handleMessage(msg)
updateTipAndPlayAnimation()
sendMessageDelayed(Message(), ANIM_DELAYED_MILLIONS.toLong())
}
}
init {
this.testHomeEvent = testHomeEvent
initView()
initAnimation()
}
/**
* 界面初始化
*/
private fun initView() {
var params = ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.WRAP_CONTENT)
view_out = View.inflate(context, R.layout.testhome_realtest_view_out,null)
view_in = View.inflate(context, R.layout.testhome_realtest_view_in,null)
addView(view_out)
addView(view_in)
layoutParams = params
}
private fun initAnimation() {
anim_out = newAnimation(0f, -1f)
anim_in = newAnimation(1f, 0f)
anim_in!!.setAnimationListener(object : Animation.AnimationListener {
override fun onAnimationStart(animation: Animation) {
}
override fun onAnimationRepeat(animation: Animation) {
}
override fun onAnimationEnd(animation: Animation) {
updateViewVisibility()
}
})
}
/**
* 设置数据
*/
fun initData(list: List<TestHomeBodyBean>){
mHandler.removeCallbacksAndMessages(null)
if (null == list || list.isEmpty()){
visibility = View.GONE
return
}
visibility = View.VISIBLE
if (null == mDataList){
mDataList = ArrayList()
}else{
(mDataList as ArrayList).clear()
}
(mDataList as ArrayList).addAll(list)
curTipIndex = 0
updateTip(STATUS_OUT)
updateTipAndPlayAnimation()
mHandler.sendMessageDelayed(Message(), ANIM_DELAYED_MILLIONS.toLong())
}
private fun updateViewVisibility() {
if (curTipIndex % 2 == 0) {
view_out!!.visibility = View.INVISIBLE
} else {
view_in!!.visibility = View.INVISIBLE
}
}
private fun newAnimation(fromYValue: Float, toYValue: Float): Animation {
val anim = TranslateAnimation(Animation.RELATIVE_TO_SELF, 0f, Animation.RELATIVE_TO_SELF, 0f,
Animation.RELATIVE_TO_SELF, fromYValue, Animation.RELATIVE_TO_SELF, toYValue)
anim.duration = ANIM_DURATION.toLong()
anim.interpolator = DecelerateInterpolator()
return anim
}
private fun updateTipAndPlayAnimation() {
view_in!!.visibility = View.VISIBLE
view_out!!.visibility = View.VISIBLE
if (curTipIndex % 2 == 0) {
updateTip(STATUS_OUT)
view_in!!.startAnimation(anim_out)
view_out!!.startAnimation(anim_in)
this.bringChildToFront(view_in)
} else {
updateTip(STATUS_IN)
view_out!!.startAnimation(anim_out)
view_in!!.startAnimation(anim_in)
this.bringChildToFront(view_out)
}
}
private fun updateTip(status : Int){
val bodyBean = getNextTip() ?: return
when(status){
STATUS_IN -> {
tv_title_in.text = bodyBean.realTestTitle
tv_name_in.text = getName(bodyBean.realTestName)
view_in!!.setOnClickListener{
testHomeEvent!!.realTestClick(bodyBean.realTestLinkUrl,bodyBean.realTestTitle)
}
}
STATUS_OUT -> {
tv_title_out.text = bodyBean.realTestTitle
tv_name_out.text = getName(bodyBean.realTestName)
view_out!!.setOnClickListener{
testHomeEvent!!.realTestClick(bodyBean.realTestLinkUrl,bodyBean.realTestTitle)
}
}
}
}
private fun getName(name : String?) : String{
var nameBuffer = StringBuffer()
nameBuffer.append(resources.getString(R.string.testhome_just))
nameBuffer.append(" ")
nameBuffer.append(name)
nameBuffer.append(" ")
nameBuffer.append(resources.getString(R.string.testhome_test))
return nameBuffer.toString()
}
private fun getNextTip() : TestHomeBodyBean? {
if (null == mDataList || mDataList!!.isEmpty()){
return null
}
return mDataList!!.get(curTipIndex++ % mDataList!!.size)
}
fun onDestory(){
mHandler.removeCallbacksAndMessages(null)
}
}
\ No newline at end of file
package com.yidianling.tests.home.widget
import android.content.Context
import android.graphics.Color
import android.text.TextUtils
import android.util.TypedValue
import android.view.View
import android.view.ViewGroup
import android.widget.FrameLayout
import android.widget.LinearLayout
import android.widget.TextView
import com.ydl.ydl_image.module.GlideApp
import com.yidianling.common.tools.LogUtil
import com.yidianling.common.tools.RxImageTool
import com.yidianling.tests.R
import com.yidianling.tests.home.bean.TestHomeBodyBean
import com.yidianling.tests.home.bean.TestHomeDataBean
import com.yidianling.tests.home.event.ITestHomeEvent
import com.yidianling.tests.home.utils.TestHomeUtils
import com.yidianling.ydlcommon.utils.ScreenUtil
import kotlinx.android.synthetic.main.testhome_recommend_first_view.view.*
/**
* @author yuanwai
* @描述:热门推荐列表第一个显示的View
* @Copyright Copyright (c) 2018
* @Company 壹点灵
* @date 2018/8/3
*/
class TestHomeRecommendedFirstView(mContext: Context, testHomeEvent: ITestHomeEvent) : FrameLayout(mContext) {
/**
* 图片宽度
*/
private var imgWidth = 0
private var isAddTitle = false
private var testHomeEvent: ITestHomeEvent? = null
var couponMoney = ""
init {
this.testHomeEvent = testHomeEvent
initView()
}
/**
* 界面初始化
*/
private fun initView() {
View.inflate(context, R.layout.testhome_recommend_first_view, this)
imgWidth = ScreenUtil.screenWidth - RxImageTool.dip2px(30f)
initImageParam()
addTitle()
}
private fun addTitle() {
if (isAddTitle) {
return
}
isAddTitle = true
val params = FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)
params.leftMargin = RxImageTool.dip2px(15f)
params.topMargin = RxImageTool.dip2px(30f)
val titleView = TextView(context)
titleView.id = R.id.testhome_recommenTitle
titleView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 18f)
titleView.setTextColor(resources.getColor(R.color.testhome_title))
val drawable = resources.getDrawable(R.drawable.testhome_hot)
/// 这一步必须要做,否则不会显示.
drawable.setBounds(0, 0, drawable.minimumWidth, drawable.minimumHeight)
titleView.setCompoundDrawablesWithIntrinsicBounds(drawable, null, null, null)
titleView.compoundDrawablePadding = RxImageTool.dip2px(5f)
titleView.layoutParams = params
addView(titleView)
}
fun initData(dataBean: TestHomeDataBean, position: Int) {
if (null == dataBean || null == dataBean.body || dataBean.body.isEmpty()) {
visibility = View.GONE
return
}
//设置标题
findViewById<TextView>(R.id.testhome_recommenTitle).text = dataBean.head!!.title
//设置推荐列表数据
initRecommeded(dataBean.body!![0], position)
}
private fun initImageParam() {
val params = LinearLayout.LayoutParams(imgWidth, imgWidth/2)
img_recom.layoutParams = params
}
/**
* 设置推荐列表数据
*/
private fun initRecommeded(bodyBean: TestHomeBodyBean, position: Int) {
tv_recomTitle.text = bodyBean.recommendedTitle
tv_recomContent.text = bodyBean.recommendedContent
setPrice(bodyBean.recommendedPrice)
tv_recomNum.text = TestHomeUtils.getNum(context, bodyBean.recommendedNum)
GlideApp.with(context).load(bodyBean.recommendedUrl).placeholder(R.drawable.testhome_banner_nor)
.into(img_recom)
LogUtil.e("宽:${img_recom.measuredWidth};高${img_recom.measuredHeight}")
tv_Hits.text = TestHomeUtils.getHits(context, bodyBean.recommendedHits)
setOnClickListener {
testHomeEvent!!.recommendedClick(bodyBean.recommendedLinkUrl, position, bodyBean.recommendedTitle)
}
}
private fun setPrice(price: String?) {
if (TextUtils.isEmpty(price)) {
tv_recomPrice.visibility = View.INVISIBLE
return
}
tv_recomPrice.visibility = View.VISIBLE
if ("免费" == price) {
tv_recomPrice.text = price
tv_recomPrice.setBackgroundResource(R.drawable.testhome_recom_price_bg)
tv_recomPrice.setTextColor(Color.parseColor("#34CD65"))
} else {
var newPrice = TestHomeUtils.getOriginalPrice(tv_coupon_money,price,couponMoney)
var priceContent = "¥$newPrice"
TestHomeUtils.priceStyleNew(context, tv_recomPrice, priceContent, 1, priceContent.length)
tv_recomPrice.setBackgroundResource(R.drawable.testhome_null)
}
}
/**
* 释放
*/
fun onDestory() {
isAddTitle = false
}
}
\ No newline at end of file
package com.yidianling.tests.home.widget
import android.content.Context
import android.graphics.Color
import android.text.Html
import android.text.TextUtils
import android.view.View
import android.widget.RelativeLayout
import com.ydl.ydl_image.module.GlideApp
import com.yidianling.common.tools.RxImageTool
import com.yidianling.tests.R
import com.yidianling.tests.home.bean.TestHomeBodyBean
import com.yidianling.tests.home.bean.TestHomeDataBean
import com.yidianling.tests.home.event.ITestHomeEvent
import com.yidianling.tests.home.utils.TestHomeUtils
import kotlinx.android.synthetic.main.testhome_recommended_view.view.*
/**
* @author yuanwai
* @描述:测评首页--热门推荐View
* @Copyright Copyright (c) 2018
* @Company 壹点灵
* @date 2018/7/28
*/
class TestHomeRecommendedView(mContext: Context, testHomeEvent: ITestHomeEvent) : RelativeLayout(mContext) {
private var testHomeEvent: ITestHomeEvent? = null
var couponMoney = ""
private var dp2 : Int? = 0
private var dp5 : Int? = 0
init {
this.testHomeEvent = testHomeEvent
initView()
}
/**
* 界面初始化
*/
private fun initView() {
View.inflate(context, R.layout.testhome_recommended_view, this)
dp2 = RxImageTool.dip2px(2f)
dp5 = RxImageTool.dip2px(5f)
}
/**
* 设置数据
*/
fun initData(dataBean: TestHomeDataBean, position: Int) {
if (null == dataBean || null == dataBean.body || dataBean.body.isEmpty()) {
visibility = View.GONE
return
}
//设置推荐列表数据
initRecommeded(dataBean.body!!.get(0), position)
}
/**
* 设置推荐列表数据
*/
private fun initRecommeded(bodyBean: TestHomeBodyBean, position: Int) {
tv_recomTitle.text = bodyBean.recommendedTitle
tv_recomContent.text = Html.fromHtml(bodyBean.recommendedContent)
setPrice(bodyBean.recommendedPrice)
tv_recomNum.text = TestHomeUtils.getNum(context, bodyBean.recommendedNum)
GlideApp.with(context).load(bodyBean.recommendedUrl)
.placeholder(R.drawable.testhome_list_nor)
.centerCrop().into(img_recom)
tv_Hits.text = TestHomeUtils.getHits(context, bodyBean.recommendedHits)
setOnClickListener {
testHomeEvent!!.recommendedClick(bodyBean.recommendedLinkUrl, position, bodyBean.recommendedTitle)
}
}
private fun setPrice(price : String?){
if (TextUtils.isEmpty(price)){
tv_recomPrice.visibility = View.INVISIBLE
return
}
tv_recomPrice.visibility = View.VISIBLE
if ("免费" == price){
tv_recomPrice.setPadding(dp5!!,dp2!!,dp5!!,dp2!!)
tv_recomPrice.text = price
tv_recomPrice.setBackgroundResource(R.drawable.testhome_recom_price_bg)
tv_recomPrice.setTextColor(Color.parseColor("#34CD65"))
tv_coupon_money.visibility = View.GONE
}else{
var newPrice = TestHomeUtils.getOriginalPrice(tv_coupon_money,price,couponMoney)
tv_recomPrice.setPadding(0,dp2!!,dp5!!,dp2!!)
var priceContent = "¥$newPrice"
TestHomeUtils.priceStyleNew(context,tv_recomPrice,priceContent, 1, priceContent.length)
tv_recomPrice.setBackgroundResource(R.drawable.testhome_null)
}
}
}
\ No newline at end of file
package com.yidianling.tests.list.model
import com.yidianling.ydlcommon.http.BaseCommand
/**
* 测试列表接口参数
* Created by zqk on 17-11-25.
*/
class TestListCommand : BaseCommand() {
@JvmField
var page: Int = 1
@JvmField
var tab: String? = null
@JvmField
var keyword: String? = null
}
\ No newline at end of file
package com.yidianling.tests.list.model.bean
import com.google.gson.annotations.SerializedName
data class CategotyPopItem(
@field:SerializedName("value")
val value: String? = null,
@field:SerializedName("key")
val key: String? = null
)
\ No newline at end of file
package com.yidianling.tests.list.model.bean
/**
* 测试列表数据
* Created by zqk on 17-11-24.
*/
data class RecommendSearchItemBean(
val id:Int,
val keyWord:String
)
package com.yidianling.tests.list.model.bean
import com.google.gson.annotations.SerializedName
/**
* 测试Model
* Created by zqk on 17-11-22.
*/
data class Test(
//测试项目id
@SerializedName(value = "id", alternate = ["recommendedId"])
val id: Int,
//封面url
@SerializedName(value = "cover", alternate = ["recommendedUrl","shareImage"])
val cover: String?,
//测试标题
@SerializedName(value = "name", alternate = ["recommendedTitle"])
val name: String?,
//测试数量
@SerializedName(value = "test_num", alternate = ["recommendedNum","visitNum"])
val count: String,
@SerializedName("test_result_id")
val testResultId: Int,
//价格
@SerializedName(value = "price", alternate = ["recommendedPrice"])
val price : String,
//人气(点击数)
@SerializedName(value = "hits", alternate = ["recommendedHits"])
val hits : String,
//是否免费 1.付费 2.免费
val isFree : Int,
//内容
@SerializedName(value = "desc", alternate = ["recommendedContent"])
val desc : String,
//支付ID
val pay_id : String?,
//红包金额
@SerializedName(value = "coupon_money", alternate = ["couponMoney"])
val coupon_money : Float?)
\ No newline at end of file
package com.yidianling.tests.list.model.bean
import com.google.gson.annotations.SerializedName
/**
* 测试类型Model
* Created by zqk on 17-11-22.
*/
data class TestCategory(
@SerializedName(value = "tab", alternate = ["pinyin"])
val tab: String?,
@SerializedName(value = "name", alternate = ["alias"])
val name: String?,
val icon: String?,
val sort: Int?,
val catName: String?,
val id: String?
)
\ No newline at end of file
package com.yidianling.tests.list.model.bean
/**
* Created by haorui on 2019/4/11.
* Des:
*/
class TestListContainer {
/**
* pageNum : 1
* pageSize : 10
* size : 10
* startRow : 1
* endRow : 10
* pages : 3
* prePage : 0
* nextPage : 2
* isFirstPage : true
* isLastPage : false
* hasPreviousPage : false
* hasNextPage : true
* navigatePages : 8
* navigatepageNums : [1,2,3]
* navigateFirstPage : 1
* navigateLastPage : 3
* total : 23
* list : [{"id":948,"testCatId":1,"name":"幼儿基础智力测验","price":1,"visitNum":124,"shareImage":"http://img.diggme.cn/2017/09/14/cbecb4544190dabe06e13f12152727be.png@150x150","commentNum":0,"desc":"智力发展是幼儿发展最重要的领域,也是其他领域发展的重要基础。有些孩子的发展可能会落后于他们的年龄阶段,而有些孩子可能会超前。你想知道你孩子的发展水平吗?可以通过这个专业的评估具体了解。这个评估是一个纯图片的测评,3-10岁的孩子都适用。报告以幼儿的智能发展阶段来表示,从辨别能力、类比能力、推理能力三个角度出发,可以用来判断幼儿的智力发展水平是否与生理发展阶段相符。从而判断幼儿智力发展水平属于滞后、正常还是超前,然后针对智力发展滞后的儿童提供相应的参考建议。家长还需要注意孩子的智力发展是一个动态的过程,本次测评结果无法预测孩子将来的成功或失败。① 综合评估孩子的智力水平② 分析孩子在三项能力的表现③ 为孩子提供发展建议▲ 报告部分截图 ▲◆ 温馨提示 ◆1. 本测试评估的是3-10岁儿童的一般智能,请尽量让儿童独立完成。2. 本测评为付费测试,体验价9.9元。3. 测试可重复购买,每次付费仅允许测试一次。4. 如在测试过程中遇到任何问题,欢迎来敲宠物喵(ID:digger1618)","tipsTitle":"","couponNumb":0,"testTagName":"亲子","couponMoney":0,"hits":878},{"id":781,"testCatId":6,"name":"分手挽回:挽回姿态评估","price":0,"visitNum":12,"shareImage":"https://img.ydlcdn.com/file/2018/04/18/kbg8mf4mq8w9c0qk.png","commentNum":0,"desc":"评估你的挽回姿态类型。你在求助专业婚恋情感师之前,在挽回TA的过程之中,曾有过哪些行为?根据自己的实际情况进行选择。","tipsTitle":"","couponNumb":0,"testTagName":"亲子","couponMoney":0,"hits":12},{"id":720,"testCatId":6,"name":"学生学校适应自评量表","price":0,"visitNum":2,"shareImage":"https://img.ydlcdn.com/file/2017/12/12/ms9fc6x64g0d2hci.jpg","commentNum":0,"desc":"亲爱的同学,你好! 此问卷的主要目的是想了解你对学校适应情况。请逐条阅读问卷中的句子,看懂后根据你自己真实的情况或看法填写。这不是考试,只要你依据自己的真实情况,诚实地回答,就是正确的答案","tipsTitle":"","couponNumb":0,"testTagName":"亲子","couponMoney":0,"hits":17},{"id":954,"testCatId":11,"name":"1","price":0,"visitNum":0,"shareImage":"http://img.diggme.cn/2017/09/14/cbecb4544190dabe06e13f12152727be.png@150x150","commentNum":0,"desc":"测试测试","tipsTitle":"1","couponNumb":0,"testTagName":"亲子","couponMoney":0,"hits":27},{"id":955,"testCatId":11,"name":"跳转题","price":0,"visitNum":2,"shareImage":"http://img.diggme.cn/2017/09/14/cbecb4544190dabe06e13f12152727be.png@150x150","commentNum":0,"desc":"测试","tipsTitle":"跳转题","couponNumb":0,"testTagName":"亲子","couponMoney":0,"hits":24},{"id":1023,"testCatId":4,"name":"测测你\u201c中年油腻\u201d了吗?","price":1,"visitNum":3,"shareImage":"","commentNum":0,"desc":"","tipsTitle":"","couponNumb":0,"testTagName":"亲子","couponMoney":0,"hits":21},{"id":1005,"testCatId":4,"name":"抑郁风险评估","price":1,"visitNum":1,"shareImage":"http://img.diggme.cn/2017/09/13/06ac4ad1374c1baba9327ae7c8a0bf43.jpg?x-oss-process=image/auto-orient,1/resize,m_lfit,w_300/quality,q_90","commentNum":0,"desc":"写在最前:本测评并非诊断评估,即使被检出是高风险的状态,也不能依此说明该个体当下已是抑郁障碍人群,进一步的确诊需要前往医院由医生进行诊断。▸ 研究背景 (Theoretical Background)抑郁(Depression),是精神世界的感冒。一种虚无、迟滞、想哭又哭不出来的绝望的状态、带着能量被掏空的疲惫感。全世界大概1/3到一半的人会在一生的某个时刻遭遇抑郁的袭击,而罹患抑郁症的患者人数至少达到了3.2亿。在美国,抑郁障碍的发生率大约在12.5%-14.2%之间。但鉴于医生的漏诊和误诊,这个数字还比较乐观。在我国,抑郁障碍的患病率据报道在5%左右,但近数十年来报告的患病率一直在上升。作为世界第四大疾病,抑郁症的影响还在上升,但我国对于抑郁症的防治还处在识别率较低的局面。因此,我们必须及早重视起来对抑郁风险的预防。那么,一个人究竟为什么患上抑郁障碍?当下的心理研究多认为,抑郁障碍的形成是多个因素综合作用的结果。一部分因素,让有些人存在发生抑郁障碍的风险性;另一部分因素,则让这部分的风险人群更易真正陷入抑郁障碍。▸ 测评内容 (Assessment Content)本次测评,我们针对心理认知方面的易感因素,基于大量的国内外相关文献,以及对抑郁障碍发生的心理机制进行研究,构建了抑郁障碍发生的风险思维模型。&nbsp;大家可以通过该测评,评估自己近期的情绪状态,以及日常思维习惯,依此判断自己是否存在抑郁障碍发生的风险。▸ 你将获得 (What You&#39;ll Gain)✎ 了解你的抑郁风险水平。✎ 了解当前生理情绪方面的抑郁状态程度。✎ 掌握对自身三种主要抑郁思维的分析与评价。 ✎ 得到抗击抑郁的针对性建议。","tipsTitle":"","couponNumb":0,"testTagName":"亲子","couponMoney":0,"hits":52},{"id":990,"testCatId":4,"name":"基础智力测验(图片版)","price":0.01,"visitNum":26,"shareImage":"http://img.diggme.cn/2017/09/14/cbecb4544190dabe06e13f12152727be.png@150x150","commentNum":0,"desc":"智力发展是幼儿发展最重要的领域,也是其他领域发展的重要基础。有些孩子的发展可能会落后于他们的年龄阶段,而有些孩子可能会超前。你想知道你孩子的发展水平吗?可以通过这个专业的评估具体了解。这个评估是一个纯图片的测评,3-10岁的孩子都适用。报告以幼儿的智能发展阶段来表示,从辨别能力、类比能力、推理能力三个角度出发,可以用来判断幼儿的智力发展水平是否与生理发展阶段相符。从而判断幼儿智力发展水平属于滞后、正常还是超前,然后针对智力发展滞后的儿童提供相应的参考建议。家长还需要注意孩子的智力发展是一个动态的过程,本次测评结果无法预测孩子将来的成功或失败。① 综合评估孩子的智力水平② 分析孩子在三项能力的表现③ 为孩子提供发展建议▲ 报告部分截图 ▲◆ 温馨提示 ◆1. 本测试评估的是3-10岁儿童的一般智能,请尽量让儿童独立完成。2. 本测评为付费测试,体验价9.9元。3. 测试可重复购买,每次付费仅允许测试一次。4. 如在测试过程中遇到任何问题,欢迎来敲宠物喵(ID:digger1618)","tipsTitle":"","couponNumb":0,"testTagName":"亲子","couponMoney":0,"hits":53},{"id":935,"testCatId":9,"name":"高级题测试2","price":0.1,"visitNum":116,"shareImage":"http://img.diggme.cn/2017/11/09/65120e66ade331a166d8d8b55bd9a713.png@150x150","commentNum":0,"desc":"财商(Finacial Quotient),全称为财富商数,指认识、创造和管理财富的能力。对于财产的认识、创造和管理能力是能够伴随我们一生的能力。高财商的人能够凭借其管理财富的能力比低财商的人更早一步实现经济自由。在本测评中,我们将会探讨你的财商指数和财商影响因素,评估你在管理财产过程中的风险承受能力和风险偏好,分析你的财富价值观和财富情绪体验。① 综合评估你的财商水平② 剖析影响你的财商因素③ 你的风险能力&amp;财富态度▲ 报告部分截图 ▲◆ 温馨提示 ◆1. 本测评为付费测试,体验价9.9元。2. 测试可重复购买,每次付费仅允许测试一次。3. 如在测试过程中遇到任何问题,欢迎来敲宠物喵(ID:digger1618)","tipsTitle":"","couponNumb":0,"testTagName":"亲子","couponMoney":0,"hits":707},{"id":933,"testCatId":12,"name":"测试啦啦啦","price":0,"visitNum":16,"shareImage":"https://img.yidianling.com/file/2018/09/06/2wtmng827njanj0n.jpg","commentNum":0,"desc":"啦啦啦啦啦","tipsTitle":"啦啦啦啦","couponNumb":0,"testTagName":"亲子","couponMoney":0,"hits":18}]
*/
var pageNum: Int = 0
var pageSize: Int = 0
var size: Int = 0
var startRow: Int = 0
var endRow: Int = 0
var pages: Int = 0
var prePage: Int = 0
var nextPage: Int = 0
var isIsFirstPage: Boolean = false
var isIsLastPage: Boolean = false
var isHasPreviousPage: Boolean = false
var isHasNextPage: Boolean = false
var navigatePages: Int = 0
var navigateFirstPage: Int = 0
var navigateLastPage: Int = 0
var total: Int = 0
var navigatepageNums: List<Int>? = null
var list: MutableList<Test>? = null
}
package com.yidianling.tests.list.model.bean
import com.google.gson.annotations.SerializedName
import com.yidianling.ydlcommon.data.ShareData
/**
* 测试列表数据
* Created by zqk on 17-11-24.
*/
data class TestListData(
@SerializedName("test_items")
val testList: MutableList<Test>?,
//兼容php老接口和java新接口
@SerializedName("testItemListList")
val testListContainer: TestListContainer,
@SerializedName("list_type")
val listType: Int,//列表类型 1测试项目类型,2测试结果类型
val share: ShareData,
val couponMoney: String
)
package com.yidianling.tests.list.presenter
import com.hannesdorfmann.mosby3.mvp.MvpNullObjectBasePresenter
import com.ydl.ydlcommon.data.http.RxUtils
import com.ydl.ydlcommon.data.http.ThrowableConsumer
import com.yidianling.tests.TestRetrofitApi
import com.yidianling.tests.list.view.TestListActivityView
import com.yidianling.ydlcommon.data.YdlDataManager
import com.yidianling.ydlcommon.http.RxUtils
import com.yidianling.ydlcommon.http.ThrowableConsumer
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.functions.Consumer
import io.reactivex.schedulers.Schedulers
/**
* TestListActivityPresenter
* Created by zqk on 17-11-22.
*/
class TestListActivityPresenter : MvpNullObjectBasePresenter<TestListActivityView>() {
fun fetchTestTypeList() {
TestRetrofitApi.getTestRetrofitApi().fetchTestCategory()
.compose(RxUtils.resultJavaData())
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ resp ->
view.onTestCategoryListFetched(resp)
}, { t ->
view.onFailed(t.message)
})
}
/**
* 请求红包列表
*/
fun requestCoupon() {
YdlDataManager.getHttp().getCoupon()
.subscribeOn(Schedulers.io())
.compose(RxUtils.resultData())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(Consumer {
view.couponResponse(it)
}, object : ThrowableConsumer() {
override fun accept(msg: String) {
view.onFailed(msg)
}
})
}
}
\ No newline at end of file
package com.yidianling.tests.list.presenter
import com.yidianling.tests.list.model.TestListCommand
import com.yidianling.tests.TestRetrofitApi
import com.yidianling.tests.list.view.TestListFragmentView
import com.hannesdorfmann.mosby3.mvp.MvpNullObjectBasePresenter
import com.yidianling.ydlcommon.http.YdlRetrofitUtils
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
/**
* TestListFragmentPresenter
* Created by zqk on 17-11-22.
*/
class TestListFragmentPresenter : MvpNullObjectBasePresenter<TestListFragmentView>() {
fun fetchTestList(type: String?, currentPage: Int) {
val cmd = TestListCommand()
cmd.tab = type
cmd.page = currentPage
TestRetrofitApi.getTestRetrofitApi()
.fetchTestList(YdlRetrofitUtils.getMaps(cmd))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ resp ->
view.dismissLoading()
if (resp.code == 0) {
view.onTestListFetched(resp.data, currentPage)
} else {
view.onFailed(resp.msg)
}
}, { t ->
view.onError(t)
})
}
}
\ No newline at end of file
package com.yidianling.tests.list.view
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.support.v4.content.ContextCompat
import android.support.v4.view.ViewPager
import android.view.View
import android.widget.PopupWindow
import android.widget.TextView
import com.alibaba.android.arouter.facade.annotation.Route
import com.yidianling.common.tools.LogUtil
import com.yidianling.common.tools.ToastUtil
import com.yidianling.tests.R
import com.yidianling.tests.base.BaseMvpActivity
import com.yidianling.tests.home.utils.TestHomeUtils
import com.yidianling.tests.list.model.bean.CategotyPopItem
import com.yidianling.tests.list.model.bean.TestCategory
import com.yidianling.tests.list.presenter.TestListActivityPresenter
import com.yidianling.tests.list.view.adapter.CategoryConditionRecyclerViewAdapter
import com.yidianling.tests.list.view.adapter.TestListPagerAdapter
import com.yidianling.tests.list.view.widget.CategoryPopupWindow
import com.yidianling.tests.router.TestsIn
import com.yidianling.tests.search.TestSearchActivity
import com.yidianling.ydlcommon.constant.UMConstants
import com.yidianling.ydlcommon.http.YdlRetrofitUtils
import com.yidianling.ydlcommon.log.LogHelper
import com.yidianling.ydlcommon.pay.redpacket.RedPacketBean
import com.yidianling.ydlcommon.tool.BuryPointUtils
import com.yidianling.ydlcommon.tool.StatusBarUtils
import com.yidianling.ydlcommon.utils.DisplayUtils
import com.yidianling.ydlcommon.utils.UMEventUtils
import kotlinx.android.synthetic.main.activity_test_category_list.*
@Route(path = "/ceshi/category_list")
class TestCategoryListActivity : BaseMvpActivity<TestListActivityView, TestListActivityPresenter>(), TestListActivityView, PopupWindow.OnDismissListener {
private var isMine: Boolean = false
private var tabName: String? = null
private var popMarginLeft: Int = 0
private var testCategory: MutableList<TestCategory> = ArrayList()
private var sortList: MutableList<CategotyPopItem> = ArrayList()
private var filterList: MutableList<CategotyPopItem> = ArrayList()
var sortConditionDefaultKey: String = "1"
var filterConditionDefaultKey: String = "1"
var selectSortItem: CategotyPopItem = CategotyPopItem("综合排序", sortConditionDefaultKey);
var selectFilterItem: CategotyPopItem = CategotyPopItem("全部", filterConditionDefaultKey);
var selectedConditionList: HashMap<Int, HashMap<String, CategotyPopItem>> = HashMap()
var sortPopup: CategoryPopupWindow? = null;
var filterPopup: CategoryPopupWindow? = null;
var currentPageIndex: Int = 0
val SELECT_SORT: String = "SELECT_SORT"
val SELECT_FILTER: String = "SELECT_FILTER"
private var testCategoryAdapter: TestListPagerAdapter? = null
companion object {
private const val EXTRA_IS_MINE = "is_mine"
private const val EXTRA_TABNAME = "tab"
private const val payRequestCode = 33
fun start(context: Context) {
LogHelper.getInstance().writeLogSync("跳转到测试题")
val intent = Intent(context, TestCategoryListActivity::class.java)
context.startActivity(intent)
}
fun start(context: Context, isMine: Boolean) {
LogHelper.getInstance().writeLogSync("跳转到测试题")
val intent = Intent(context, TestCategoryListActivity::class.java)
intent.putExtra(EXTRA_IS_MINE, isMine)
context.startActivity(intent)
}
/**
* 根据所传的tab标签 定位到指定标签下
*/
fun start(context: Context, tab: String?) {
LogHelper.getInstance().writeLogSync("跳转到测试题")
val intent = Intent(context, TestCategoryListActivity::class.java)
intent.putExtra(EXTRA_TABNAME, tab)
context.startActivity(intent)
}
}
override fun isAddStatusView(): Boolean {
return true
}
override fun layoutResId(): Int {
return R.layout.activity_test_category_list
}
override fun initDataAndEvent() {
initConditionView()
popMarginLeft = DisplayUtils.dip2px(this, 72F)
if (null != intent && intent.hasExtra(EXTRA_IS_MINE)) {
isMine = intent.getBooleanExtra(EXTRA_IS_MINE, false)
}
if (null != intent && intent.hasExtra(EXTRA_TABNAME)) {
tabName = intent.getStringExtra(EXTRA_TABNAME)
}
tv_test_search.setOnClickListener {
UMEventUtils.umEvent(TestsBIConstants.EVENT_TEST_LIST_SEARCH_CLICK, "", "")
TestSearchActivity.start(this)
}
iv_test_list_back.setOnClickListener {
this.finish()
}
dr_sort.setOnClickListener {
showSortPopupWindow()
}
dr_filter.setOnClickListener {
showFilterPopupWindow()
}
presenter.fetchTestTypeList()
vvp_test.addOnPageChangeListener(object : ViewPager.OnPageChangeListener {
override fun onPageScrollStateChanged(state: Int) {}
override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {}
override fun onPageSelected(position: Int) {
currentPageIndex = position
setConditionContent();
UMEventUtils.umEvent(TestsBIConstants.EVENT_TEST_LIST_CATEGORY_CLICK, TestsBIConstants.PROPERTY_TEST_LIST_CATEGORY_NAME, testCategory?.get(position)?.name)
click_category()
LogUtil.d("page selected: " + testCategory?.get(position)?.name)
BuryPointUtils.getInstance().createMap()
.put("test_type_click", testCategory?.get(position)?.name + "")
.burryPoint("Testtype_click")
if (("my" == testCategory?.get(position)?.tab || "unpay" == testCategory?.get(position)?.tab) && !TestsIn.isLogin()) {
startActivity(TestsIn.loginWayIntent(this@TestCategoryListActivity))
}
}
})
StatusBarUtils.statusBarLightMode(this)
}
private fun initConditionView() {
sortList.add(selectSortItem)
sortList.add(CategotyPopItem("人气优选", "4"))
sortList.add(CategotyPopItem("最新上新", "5"))
filterList.add(selectFilterItem)
filterList.add(CategotyPopItem("付费", "3"))
filterList.add(CategotyPopItem("免费", "2"))
sortPopup = CategoryPopupWindow(this,
sortList.toList() as ArrayList<CategotyPopItem>, object : CategoryConditionRecyclerViewAdapter.OnItemSelectedListener {
override fun onSortItemSelected(sortItem: CategotyPopItem) {
selectSortItem = sortItem
if (selectSortItem.key == sortConditionDefaultKey) {
updateFilterTextViewStatus(dr_sort, sortItem.value!!, true)
} else {
updateFilterTextViewStatus(dr_sort, sortItem.value!!, false)
}
sortPopup?.dismiss()
}
})
filterPopup = CategoryPopupWindow(this,
filterList.toList() as ArrayList<CategotyPopItem>, object : CategoryConditionRecyclerViewAdapter.OnItemSelectedListener {
override fun onSortItemSelected(sortItem: CategotyPopItem) {
selectFilterItem = sortItem
if (selectFilterItem.key == filterConditionDefaultKey) {
updateFilterTextViewStatus(dr_filter, sortItem.value!!, true)
} else {
updateFilterTextViewStatus(dr_filter, sortItem.value!!, false)
}
filterPopup?.dismiss()
}
})
sortPopup?.setOnDismissListener(this)
filterPopup?.setOnDismissListener(this)
}
override fun onDismiss() {
view_mask.visibility = View.GONE
updateConditionList()
}
private fun setConditionContent() {
var conditionList = selectedConditionList[currentPageIndex];
if (conditionList != null && conditionList[SELECT_SORT] != null && conditionList[SELECT_FILTER] != null) {
selectSortItem = conditionList[SELECT_SORT]!!
selectFilterItem = conditionList[SELECT_FILTER]!!
if (selectSortItem.key == sortConditionDefaultKey) {
updateFilterTextViewStatus(dr_sort, selectSortItem.value!!, true)
} else {
updateFilterTextViewStatus(dr_sort, selectSortItem.value!!, false)
}
if (selectFilterItem.key == filterConditionDefaultKey) {
updateFilterTextViewStatus(dr_filter, selectFilterItem.value!!, true)
} else {
updateFilterTextViewStatus(dr_filter, selectFilterItem.value!!, false)
}
}else{
selectSortItem = CategotyPopItem("综合排序", sortConditionDefaultKey)
selectFilterItem= CategotyPopItem("全部", filterConditionDefaultKey)
updateFilterTextViewStatus(dr_sort, selectSortItem.value!!, true)
updateFilterTextViewStatus(dr_filter, selectFilterItem.value!!, true)
}
sortPopup?.adapter?.lastSelectText = selectSortItem.value
filterPopup?.adapter?.lastSelectText = selectFilterItem.value
sortPopup?.adapter?.notifyDataSetChanged()
filterPopup?.adapter?.notifyDataSetChanged()
}
private fun updateConditionList() {
var conditionList = selectedConditionList[currentPageIndex];
if (conditionList == null) {
conditionList = HashMap();
}
conditionList[SELECT_SORT] = selectSortItem
conditionList[SELECT_FILTER] = selectFilterItem
selectedConditionList[currentPageIndex] = conditionList
refreshFragmentPageData(selectSortItem.key!!,selectFilterItem.key!!)
}
private fun refreshFragmentPageData(sort:String,filter:String) {
testCategoryAdapter?.getFragmentByPosition(currentPageIndex)?.refreshListData(sort,filter)
}
private fun click_category() {
}
override fun onError(t: Throwable) {
YdlRetrofitUtils.handleError(mContext, t)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == payRequestCode && resultCode == Activity.RESULT_OK) {
//如果 是待付款列表 则需要刷新界面
if (null != presenter) {
presenter.fetchTestTypeList()
}
}
}
override fun onTestCategoryListFetched(testCategoryList: MutableList<TestCategory>) {
testCategory = testCategoryList
testCategoryAdapter = TestListPagerAdapter(supportFragmentManager, this, testCategoryList);
vvp_test.adapter = testCategoryAdapter
vt_test_search.setupWithViewPager(vvp_test)
if (isMine) {
var myTab = 0
for ((index, cat) in testCategoryList.withIndex()) {
if (cat.tab == "my") {
myTab = index
break
}
}
currentPageIndex = myTab
} else if (null != tabName && !tabName!!.isEmpty()) {
var myTab = 0
for ((index, cat) in testCategoryList.withIndex()) {
if (cat.tab == tabName) {
myTab = index
break
}
}
currentPageIndex = myTab
}
if (currentPageIndex != 0) {
vvp_test.currentItem = currentPageIndex
}
}
//显示排序弹窗
private fun showSortPopupWindow() {
sortPopup?.showAsDropDown(ll_sort)
view_mask.visibility = View.VISIBLE
}
//显示筛选弹窗
private fun showFilterPopupWindow() {
filterPopup?.showAsDropDown(ll_sort)
view_mask.visibility = View.VISIBLE
}
private fun updateFilterTextViewStatus(tv: TextView, text: String, isNormal: Boolean) {
tv.text = text
if (isNormal) {
tv.setTextColor(ContextCompat.getColor(this, R.color.colorTextDefault))
tv.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_arrow_drop_down_grey_500_18dp, 0)
} else {
tv.setTextColor(ContextCompat.getColor(this, R.color.google_green))
tv.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_arrow_drop_down_green_18dp, 0)
}
}
override fun onFailed(msg: String?) {
ToastUtil.toastShort(msg ?: "")
}
override fun createPresenter(): TestListActivityPresenter = TestListActivityPresenter()
override fun couponResponse(list: ArrayList<RedPacketBean>) {}
override fun onResume() {
super.onResume()
TestHomeUtils.updateCouponMoney()
}
}
package com.yidianling.tests.list.view
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.support.v4.view.ViewPager
import android.view.View
import android.widget.PopupWindow
import com.alibaba.android.arouter.facade.annotation.Route
import com.yidianling.common.tools.LogUtil
import com.yidianling.common.tools.ToastUtil
import com.yidianling.tests.R
import com.yidianling.tests.base.BaseMvpActivity
import com.yidianling.tests.list.model.bean.TestCategory
import com.yidianling.tests.list.presenter.TestListActivityPresenter
import com.yidianling.tests.list.view.adapter.TestListPagerAdapter
import com.yidianling.tests.router.TestsIn
import com.yidianling.tests.search.TestSearchActivity
import com.yidianling.ydlcommon.constant.UMConstants
import com.yidianling.ydlcommon.http.YdlRetrofitUtils
import com.yidianling.ydlcommon.log.LogHelper
import com.yidianling.ydlcommon.pay.redpacket.RedPacketBean
import com.yidianling.ydlcommon.tool.BuryPointUtils
import com.yidianling.ydlcommon.tool.PopUtils
import com.yidianling.ydlcommon.utils.UMEventUtils
import kotlinx.android.synthetic.main.activity_test_list.*
@Route(path = "/ceshi/list")
class TestListActivity : BaseMvpActivity<TestListActivityView, TestListActivityPresenter>(), TestListActivityView {
override fun layoutResId(): Int {
return R.layout.activity_test_list
}
override fun initDataAndEvent() {
if (null != intent && intent.hasExtra(EXTRA_IS_MINE)) {
isMine = intent.getBooleanExtra(EXTRA_IS_MINE, false)
}
if (null != intent && intent.hasExtra(EXTRA_TABNAME)) {
tabName = intent.getStringExtra(EXTRA_TABNAME)
}
titleBar.setOnRightTextClick { _, _ ->
UMEventUtils.umEvent(TestsBIConstants.EVENT_TEST_LIST_SEARCH_CLICK, "", "")
TestSearchActivity.start(this)
}
titleBar.setRightImageListener {
UMEventUtils.umEvent(TestsBIConstants.EVENT_TEST_LIST_MORE_CLICK, "", "")
popupWindow = PopUtils.showMoreItem(mContext,
titleBar.rootView,
0,
0)
}
presenter.fetchTestTypeList()
viewPager.addOnPageChangeListener(object : ViewPager.OnPageChangeListener {
override fun onPageScrollStateChanged(state: Int) {}
override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {}
override fun onPageSelected(position: Int) {
UMEventUtils.umEvent(TestsBIConstants.EVENT_TEST_LIST_CATEGORY_CLICK, TestsBIConstants.PROPERTY_TEST_LIST_CATEGORY_NAME, testCategorys?.get(position)?.name)
click_category()
LogUtil.d("page selected: " + testCategorys?.get(position)?.name)
BuryPointUtils.getInstance().createMap()
.put("test_type_click", testCategorys?.get(position)?.name + "")
.burryPoint("Testtype_click")
if (("my" == testCategorys?.get(position)?.tab || "unpay" == testCategorys?.get(position)?.tab) && !TestsIn.isLogin()) {
// RouterManager.startActivity(this@TestListActivity,RouterEnum.USER,null,ClassNameEnum.ChooseLoginWayActivity)
startActivity(TestsIn.loginWayIntent(this@TestListActivity))
}
}
})
}
private fun click_category() {
}
override fun onResume() {
super.onResume()
//获取红包列表
if (TestsIn.isLogin()){
presenter.requestCoupon()
}
}
companion object {
private const val EXTRA_IS_MINE = "is_mine"
private const val EXTRA_TABNAME = "tab"
private const val payRequestCode = 33
fun start(context: Context) {
LogHelper.getInstance().writeLogSync("跳转到测试题")
val intent = Intent(context, TestListActivity::class.java)
context.startActivity(intent)
}
fun start(context: Context, isMine: Boolean) {
LogHelper.getInstance().writeLogSync("跳转到测试题")
val intent = Intent(context, TestListActivity::class.java)
intent.putExtra(EXTRA_IS_MINE, isMine)
context.startActivity(intent)
}
/**
* 根据所传的tab标签 定位到指定标签下
*/
fun start(context: Context, tab: String?) {
LogHelper.getInstance().writeLogSync("跳转到测试题")
val intent = Intent(context, TestListActivity::class.java)
intent.putExtra(EXTRA_TABNAME, tab)
context.startActivity(intent)
}
}
override fun onError(t: Throwable) {
YdlRetrofitUtils.handleError(mContext, t)
}
private var isMine: Boolean = false
private var tabName: String? = null
private var testCategorys: MutableList<TestCategory>? = null
override fun couponResponse(list: ArrayList<RedPacketBean>) {
if (null == list || list.isEmpty()){
llTestRedPacketTips.visibility = View.GONE
}else{
llTestRedPacketTips.visibility = View.VISIBLE
val sb = StringBuffer()
sb.append("还有").append(list.size).append("个心理测试红包等你使用")
tvTestRedPacketTips.text = sb.toString()
llTestRedPacketTips.setOnClickListener {
TestsIn.myRedPockIntent(TestListActivity@this)
}
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == payRequestCode && resultCode == Activity.RESULT_OK) {
//如果 是待付款列表 则需要刷新界面
if (null != presenter){
presenter.fetchTestTypeList()
}
}
}
override fun onTestCategoryListFetched(testCategoryList: MutableList<TestCategory>) {
testCategorys = testCategoryList
viewPager.adapter = TestListPagerAdapter(supportFragmentManager,this, testCategoryList)
tabLayout.setupWithViewPager(viewPager)
if (isMine) {
var myTab = 0
for ((index, cat) in testCategoryList.withIndex()) {
if (cat.tab == "my") {
myTab = index
break
}
}
viewPager.currentItem = myTab
} else if (null != tabName && !tabName!!.isEmpty()) {
var myTab = 0
for ((index, cat) in testCategoryList.withIndex()) {
if (cat.tab == tabName) {
myTab = index
break
}
}
viewPager.currentItem = myTab
}
}
override fun onFailed(msg: String?) {
ToastUtil.toastShort(msg ?: "")
}
override fun createPresenter(): TestListActivityPresenter = TestListActivityPresenter()
private var popupWindow: PopupWindow? = null
override fun onBackPressed() {
if (popupWindow != null && popupWindow!!.isShowing) {
popupWindow!!.dismiss()
} else {
super.onBackPressed()
}
}
}
package com.yidianling.tests.list.view
import com.hannesdorfmann.mosby3.mvp.MvpView
import com.yidianling.tests.list.model.bean.TestCategory
import com.yidianling.ydlcommon.pay.redpacket.RedPacketBean
/**
* TestListActivityView
* Created by zqk on 17-11-22.
*/
interface TestListActivityView : MvpView {
fun onTestCategoryListFetched(testCategoryList: MutableList<TestCategory>)
fun couponResponse(list : ArrayList<RedPacketBean>)
fun onFailed(msg: String?)
fun onError(t: Throwable)
}
\ No newline at end of file
package com.yidianling.tests.list.view
import android.net.Uri
import android.os.Bundle
import android.support.v7.widget.LinearLayoutManager
import android.support.v7.widget.RecyclerView
import android.text.TextUtils
import android.view.View
import com.ydl.ydl_router.manager.YDLRouterManager
import com.ydl.ydl_router.manager.YDLRouterParams
import com.ydl.ydlcommon.data.http.RxUtils
import com.ydl.ydlcommon.router.YdlCommonOut
import com.ydl.ydlcommon.router.YdlCommonRouterManager
import com.ydl.ydlcommon.utils.UMEventUtils
import com.yidianling.common.tools.ToastUtil
import com.yidianling.router.RouterManager
import com.yidianling.tests.R
import com.yidianling.tests.TestRetrofitApi
import com.yidianling.tests.base.MyBaseAdapter
import com.yidianling.tests.home.event.UpdateCouponMoneyEvent
import com.yidianling.tests.home.utils.TestHomeUtils
import com.yidianling.tests.list.model.bean.Test
import com.yidianling.tests.list.model.bean.TestListData
import com.yidianling.tests.list.view.adapter.TestListRecyclerAdapter
import com.yidianling.tests.router.TestsIn
import com.yidianling.ydlcommon.BuildConfig
import com.yidianling.ydlcommon.base.BaseFragment
import com.yidianling.ydlcommon.constant.UMConstants
import com.yidianling.ydlcommon.data.ShareData
import com.yidianling.ydlcommon.http.RxUtils
import com.yidianling.ydlcommon.http.ThrowableConsumer
import com.yidianling.ydlcommon.listener.EndlessRecyclerViewScrollListener
import com.yidianling.ydlcommon.router.IYDLRouterConstant
import com.yidianling.ydlcommon.router.YdlCommonOut
import com.yidianling.ydlcommon.router.YdlCommonRouterManager
import com.yidianling.ydlcommon.tool.BuryPointUtils
import com.yidianling.ydlcommon.utils.SharedPreferencesEditor
import com.yidianling.ydlcommon.utils.UMEventUtils
import de.greenrobot.event.EventBus
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
import io.reactivex.functions.Consumer
import io.reactivex.schedulers.Schedulers
import kotlinx.android.synthetic.main.fragment_test_list.*
import java.util.*
class TestListFragment : BaseFragment(), MyBaseAdapter.OnItemClickListener<Test> {
override fun initDataAndEvent() {
initUiAndListener()
}
override fun onResume() {
super.onResume()
initData()
}
override fun layoutResId(): Int {
return R.layout.fragment_test_list
}
private var category: String? = null //测试类型id
private var categoryName: String? = null
private var categoryId: String? = null
private var currentPage = 1 //当前页
private val testList: MutableList<Test> = ArrayList()
private var share: ShareData? = null
private var listType = 1 //1测试项目列表,2测试结果列表
private lateinit var adapter: TestListRecyclerAdapter
private lateinit var onScrollListener: EndlessRecyclerViewScrollListener
fun initUiAndListener() {
if (arguments != null) {
category = arguments.getString(ARG_CATEGORY)
categoryName = arguments.getString(ARG_NAME)
categoryId = arguments.getString(ARG_ID)
}
EventBus.getDefault().register(this)
adapter = TestListRecyclerAdapter(activity, testList, TestListRecyclerAdapter.PAGE_TYPE_CATEGORY)
adapter.onItemClickListener = this
rvTestList.adapter = adapter
val layoutManager = LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false)
rvTestList.layoutManager = layoutManager
onScrollListener = object : EndlessRecyclerViewScrollListener(layoutManager) {
override fun onLoadMore(page: Int, totalItemsCount: Int, view: RecyclerView?) {
fetchTestList()
}
}
rvTestList.addOnScrollListener(onScrollListener)
var lastCouponMoney = SharedPreferencesEditor.getString(TestHomeUtils.TEST_MAX_COUPON_MONEY_SP_KEY)
if (!TextUtils.isEmpty(lastCouponMoney)){
adapter?.couponMoney = lastCouponMoney
}
}
override fun initDataAndEventLazy() {
}
private var disposable: Disposable? = null
private var sort:String ="";
private var filter:String ="";
fun refreshListData(sort:String , filter:String){
if (!this.sort.equals(sort)||!this.filter.equals(filter)){
currentPage = 1
this.sort = sort
this.filter = filter
fetchTestList()
}
}
fun fetchTestList() {
val loginBean = YdlCommonRouterManager.getYdlCommonRoute().getUserInfo()
var userId = loginBean?.userId ?: "";
disposable = TestRetrofitApi.getTestRetrofitApi()
.fetchTestListByTag(
testTagId = categoryId.toString(),
page = currentPage.toString(),
uid = userId,
testPrice = if(filter=="2"||filter=="3") filter else "",
testCreateTime = if (sort=="5") sort else "",
testVisitNum = if (sort=="4") sort else ""
)
.subscribeOn(Schedulers.io())
.compose(RxUtils.resultJavaData())
.observeOn(AndroidSchedulers.mainThread())
.doAfterTerminate { dismissLoading() }
.subscribe(Consumer {
onTestListFetched(it, currentPage)
}, object : ThrowableConsumer() {
override fun accept(msg: String) {
dismissLoading()
YdlCommonOut.showToast(msg)
}
})
}
private fun dismissLoading() {
//其实不应该这么改 只所以为空 应该是页面被销毁了 应该判断当前页面是否被销毁
if (null != flLoading){
flLoading.visibility = View.GONE
}
}
override fun onItemClickListener(v: View?, position: Int, data: Test?) {
UMEventUtils.umEvent(TestsBIConstants.EVENT_TEST_LIST_TEST_TITLE_CLICK, TestsBIConstants.PROPERTY_TEST_LIST_TEST_NAME, data?.name)
BuryPointUtils.getInstance().createMap()
.put("test_id", data?.id.toString())
.put("test_title", data?.name ?: "")
.put("test_type", categoryName ?: "")
.burryPoint("testClick")
if (v == null || data == null) {
ToastUtil.toastShort(getString(R.string.wrong_args))
return
}
//如果列表是待支付 的话 则跳转 支付界面
if ("unpay" == category){
val url = StringBuffer(BuildConfig.MH5_URL)
url.append("ceshi/")
url.append(data.id)
url.append("?payId=")
url.append(data.pay_id)
url.append("&couponMoney=")
url.append(data.coupon_money)
url.append("&orderId=")
url.append(data.id)
//跳转测试详情页
YDLRouterManager.router(IYDLRouterConstant.ROUTER_H5_H5,
YDLRouterParams().putExtra(IYDLRouterConstant.EXTRA_URL, Uri.encode(url.toString())),"")
}else{
when (listType) {
1 -> {
RouterManager.getTestsRouter()?.testDetailH5(data.id.toString())
}
2 -> {
RouterManager.getTestsRouter()?.testH5Result(data.testResultId.toString());
}
else -> RouterManager.getTestsRouter()?.testDetailH5(data.id.toString())
}
}
}
private fun onTestListFetched(testListData: TestListData, page: Int) {
var newTestList = testListData.testList
if ((newTestList==null||newTestList.size==0)
&&(testListData.testListContainer.list!=null
&& testListData.testListContainer.list!!.isNotEmpty())){
newTestList = testListData.testListContainer.list
}
if (page == 1) {
share = testListData.share
listType = testListData.listType
onScrollListener.resetState()
testList.clear()
if (testListData.testList?.size == 0 && listType == 2) {
llNoTest.visibility = View.VISIBLE
} else {
llNoTest.visibility = View.GONE
}
}
if (newTestList != null && newTestList.size > 0) {
testList.addAll(newTestList)
adapter.notifyDataSetChanged()
} else {
adapter.hasMore = false
adapter.notifyDataSetChanged()
}
currentPage++
}
private fun initData() {
currentPage = 1
if (category == "my" || category == "unpay") {
if (TestsIn.isLogin()) {
fetchTestList()
} else {
llNoTest.visibility = View.VISIBLE
}
} else {
fetchTestList()
}
}
override fun onStop() {
super.onStop()
if (disposable != null && !disposable!!.isDisposed) {
disposable?.dispose()
}
}
override fun onDestroy() {
super.onDestroy()
if (disposable != null && !disposable!!.isDisposed) {
disposable?.dispose()
}
}
companion object {
private const val ARG_CATEGORY = "category"
private const val ARG_NAME = "category_name"
private const val ARG_ID = "category_id"
fun newInstance(category: String?, categoryId: String?,categoryName: String?): TestListFragment {
val fragment = TestListFragment()
val args = Bundle()
args.putString(ARG_CATEGORY, category)
args.putString(ARG_NAME, categoryName)
args.putString(ARG_ID, categoryId)
fragment.arguments = args
return fragment
}
}
/**
* 更新优惠券信息
* 刷新列表
*/
fun onEvent(updateCouponMoneyEvent: UpdateCouponMoneyEvent){
adapter?.couponMoney = updateCouponMoneyEvent.money
adapter?.notifyDataSetChanged()
}
override fun onDestroyView() {
super.onDestroyView()
EventBus.getDefault().unregister(this)
}
}
package com.yidianling.tests.list.view
import com.yidianling.tests.list.model.bean.TestListData
import com.hannesdorfmann.mosby3.mvp.MvpView
/**
* TestListFragmentView
* Created by zqk on 17-11-22.
*/
interface TestListFragmentView : MvpView {
fun onTestListFetched(testListData: TestListData, page: Int)
fun onFailed(msg: String?)
fun dismissLoading()
fun onError(t: Throwable)
}
\ No newline at end of file
package com.yidianling.tests.list.view.adapter
import android.content.Context
import android.support.v4.content.ContextCompat
import android.support.v7.widget.RecyclerView
import android.text.TextUtils
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import com.yidianling.tests.R
import com.yidianling.tests.list.model.bean.CategotyPopItem
import kotlinx.android.synthetic.main.item_tab_pop_sort.view.*
/**
* Created by zqk on 17-9-20.
*/
class CategoryConditionRecyclerViewAdapter(private val context: Context,
private val sortItems: ArrayList<CategotyPopItem>,
private val onItemSelectedListener: OnItemSelectedListener) : RecyclerView.Adapter<CategoryConditionRecyclerViewAdapter.ViewHolder>() {
override fun getItemCount(): Int = sortItems.size
var lastSelectView : TextView ?= null
var lastSelectText : String ?= null
override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): ViewHolder {
val itemView = LayoutInflater.from(context).inflate(R.layout.item_tab_pop_sort, parent, false)
return ViewHolder(itemView)
}
override fun onBindViewHolder(holder: ViewHolder?, position: Int) {
val item = sortItems[position]
if (holder != null) {
holder.tvSort.text = item.value
holder.tvSort.setTextColor(ContextCompat.getColor(context, R.color.color_242424))
if (!TextUtils.isEmpty(lastSelectText) && item.value.equals(lastSelectText) && position!=0){
holder.tvSort.setTextColor(ContextCompat.getColor(context, R.color.google_green))
lastSelectView = holder.tvSort
}
}
}
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val tvSort = itemView.tvSort!!
init {
itemView.setOnClickListener {
lastSelectView?.setTextColor(ContextCompat.getColor(context, R.color.color_242424))
if (adapterPosition != 0){
tvSort.setTextColor(ContextCompat.getColor(context, R.color.google_green))
}
if (adapterPosition != RecyclerView.NO_POSITION){
onItemSelectedListener.onSortItemSelected(sortItems[adapterPosition])
}
lastSelectView = tvSort
}
}
}
interface OnItemSelectedListener {
fun onSortItemSelected(sortItem: CategotyPopItem)
}
}
\ No newline at end of file
package com.yidianling.tests.list.view.adapter
import android.content.Context
import android.graphics.Color
import android.graphics.Typeface
import android.support.v4.app.FragmentManager
import android.support.v4.app.FragmentPagerAdapter
import com.yidianling.tests.list.model.bean.TestCategory
import com.yidianling.tests.list.view.TestListFragment
import com.yidianling.ydlcommon.view.verticaltablayout.TabAdapter
import com.yidianling.ydlcommon.view.verticaltablayout.TabView
/**
* 测试列表ViewPager适配器
* Created by zqk on 17-11-22.
*/
class TestListPagerAdapter(fm: FragmentManager,
private val context: Context ,
private val testCategoryList: MutableList<TestCategory>
) : FragmentPagerAdapter(fm), TabAdapter {
private var fragments:HashMap<Int,TestListFragment> = HashMap();
override fun getIcon(position: Int): TabView.TabIcon? {
return null
}
override fun getTitle(position: Int): TabView.TabTitle {
return TabView.TabTitle.Builder()
.setContent(testCategoryList[position].name)
.setTextColor(Color.parseColor("#333333"), Color.parseColor("#666666"))
.setBgColor(Color.parseColor("#FFFFFF"), Color.parseColor("#F7F7F7"))
.setFontFamily(Typeface.defaultFromStyle(Typeface.BOLD), Typeface.defaultFromStyle(Typeface.NORMAL))
.setTextSize(14)
.build();
}
override fun getBackground(position: Int): Int {
return 0
}
override fun getPageTitle(position: Int): CharSequence = testCategoryList[position].name ?: ""
override fun getItem(position: Int): TestListFragment {
var fragment = TestListFragment.newInstance(testCategoryList[position].tab, testCategoryList[position].id,testCategoryList[position].name);
fragments[position] = fragment
return fragment
}
fun getFragmentByPosition(position: Int): TestListFragment? {
return fragments[position]
}
override fun getCount(): Int = testCategoryList.size
}
\ No newline at end of file
package com.yidianling.tests.list.view.adapter
import android.content.Context
import android.graphics.Color
import android.support.v7.widget.RecyclerView
import android.text.TextUtils
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import com.ydl.ydl_image.module.GlideApp
import com.yidianling.common.tools.RxImageTool
import com.yidianling.tests.R
import com.yidianling.tests.base.MyBaseAdapter
import com.yidianling.tests.home.utils.TestHomeUtils
import com.yidianling.tests.list.model.bean.Test
import kotlinx.android.synthetic.main.testlist_item_view.view.*
import kotlinx.android.synthetic.main.view_footview_loadmore.view.*
/**
* 测试列表适配器
* Created by zqk on 17-11-22.
*/
class TestListRecyclerAdapter(private val context: Context,
private val testList: MutableList<Test>,
private val pageType : Int
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
companion object {
private val TYPE_HEADER= 1
private val TYPE_FOOTER = 2
private val TYPE_NORMAL = 0
const val PAGE_TYPE_CATEGORY = 1
const val PAGE_TYPE_SEARCH = 2
}
var onItemClickListener: MyBaseAdapter.OnItemClickListener<Test>? = null
var hasMore = true
var couponMoney =""
private var dp2 : Int? = 0
private var dp5 : Int? = 0
private var headerView: View? = null
init {
dp2 = RxImageTool.dip2px(2f)
dp5 = RxImageTool.dip2px(5f)
}
fun setHeaderView(view: View) {
headerView = view
notifyDataSetChanged()
}
fun removeHeaderView() {
headerView = null
notifyDataSetChanged()
}
private fun hasHeader(): Boolean {
return headerView != null
}
override fun getItemCount(): Int = if (testList.size > 0) testList.size + 1 + (if (hasHeader()) 1 else 0) else 0
override fun onBindViewHolder(holder: RecyclerView.ViewHolder?, position: Int) {
if (holder is NormalViewHolder) {
var newPosition = position - if (hasHeader()) 1 else 0
val test = testList[newPosition]
GlideApp.with(context)
.load(test.cover)
.dontAnimate()
.dontTransform()
// .diskCacheStrategy(DiskCacheStrategy.ALL)
.placeholder(R.drawable.default_img)
.into(holder.ivCover)
holder.tvTitle.text = test.name
holder.tvTestCount.text =TestHomeUtils.getNumNew(context, test.count)
holder.tvTestContent.text = test.desc
holder.tvHit.text = TestHomeUtils.getHitsNew(context, test.hits)
setPrice(holder.tvPrice,holder.tvCoupon,test.price,test.isFree)
} else if (holder is FootViewHolder) {
if (hasMore) {
holder.pbLoading.visibility = View.VISIBLE
holder.ivNoMoreLeft.visibility = View.GONE
holder.ivNoMoreRight.visibility = View.GONE
holder.tvContent.text = context.getString(R.string.loading)
} else {
holder.pbLoading.visibility = View.GONE
holder.tvContent.text = context.getString(R.string.load_end)
holder.ivNoMoreLeft.visibility = View.VISIBLE
holder.ivNoMoreRight.visibility = View.VISIBLE
}
}
}
private fun setPrice(textView : TextView,tvCoupon : TextView,price : String?,isFree : Int){
if (TextUtils.isEmpty(price)){
textView.visibility = View.INVISIBLE
return
}
textView.visibility = View.VISIBLE
if (isFree == 2
||price.equals("免费")
||TextUtils.isEmpty(price)
||"0".equals(price)
||"0.0".equals(price)
||"0.00".equals(price)){
tvCoupon.visibility = View.GONE
textView.setPadding(dp5!!,dp2!!,dp5!!,dp2!!)
textView.text = "免费"
textView.setBackgroundResource(R.drawable.testhome_recom_price_bg)
textView.setTextColor(Color.parseColor("#34CD65"))
}else{
var newPrice = TestHomeUtils.getOriginalPrice(tvCoupon,price,couponMoney)
textView.setPadding(0,dp5!!,dp5!!,0)
var priceContent = "¥$newPrice"
TestHomeUtils.priceStyleNew(context,textView,priceContent, 1, priceContent.length)
textView.setBackgroundResource(R.drawable.testhome_null)
}
}
override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): RecyclerView.ViewHolder {
return if (viewType == TYPE_HEADER) {
object : RecyclerView.ViewHolder(headerView) {}
} else if (viewType == TYPE_NORMAL) {
var view :View ?=null
if (pageType== PAGE_TYPE_CATEGORY){
view = LayoutInflater.from(parent?.context).inflate(R.layout.item_category_testlist_view, parent, false)
}else {
view = LayoutInflater.from(parent?.context).inflate(R.layout.testlist_item_view, parent, false)
}
NormalViewHolder(view!!)
} else {
val view = LayoutInflater.from(parent?.context).inflate(R.layout.view_footview_loadmore, parent, false)
FootViewHolder(view)
}
}
override fun getItemViewType(position: Int): Int {
return if (hasHeader() && position == 0) {
return TYPE_HEADER
}else if (position == testList.size + (if (hasHeader()) 1 else 0)) {
TYPE_FOOTER
} else {
TYPE_NORMAL
}
}
inner class NormalViewHolder(val view: View) : RecyclerView.ViewHolder(view) {
var ivCover = view.ivCover
var tvTitle = view.tv_title
var tvTestCount = view.tv_num
var tvTestContent = view.tvContent
var tvHit = view.tv_hits
var tvPrice = view.tv_price
var tvCoupon = view.tv_coupon_money
init {
view.setOnClickListener {
if (adapterPosition != RecyclerView.NO_POSITION) {
onItemClickListener?.onItemClickListener(view, adapterPosition- (if (hasHeader()) 1 else 0), testList[adapterPosition- (if (hasHeader()) 1 else 0)])
}
}
}
}
inner class FootViewHolder(val view: View) : RecyclerView.ViewHolder(view) {
var pbLoading = view.circle_progress
var tvContent = view.tv_content
var ivNoMoreLeft = view.iv_no_more_left
var ivNoMoreRight = view.iv_no_more_right
}
}
\ No newline at end of file
package com.yidianling.tests.list.view.widget
import android.content.Context
import android.graphics.drawable.BitmapDrawable
import android.support.v7.widget.LinearLayoutManager
import android.view.LayoutInflater
import android.view.ViewGroup
import android.widget.PopupWindow
import com.yidianling.tests.R
import com.yidianling.tests.list.model.bean.CategotyPopItem
import com.yidianling.tests.list.view.adapter.CategoryConditionRecyclerViewAdapter
import kotlinx.android.synthetic.main.ui_category_sort_popup_window.view.*
/**
* 排序弹窗
* Created by zqk on 17-9-15.
*/
class CategoryPopupWindow(val context: Context,
private val items: ArrayList<CategotyPopItem>,
private val onItemSelectedListener: CategoryConditionRecyclerViewAdapter.OnItemSelectedListener)
: PopupWindow(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT) {
var adapter: CategoryConditionRecyclerViewAdapter
init {
val view = LayoutInflater.from(context).inflate(R.layout.ui_category_sort_popup_window, null)
this.contentView = view
this.isFocusable = true
@Suppress("DEPRECATION")
this.setBackgroundDrawable(BitmapDrawable())
this.isOutsideTouchable = true
val rvSortItem = view.rvSortItem
adapter = CategoryConditionRecyclerViewAdapter(context, items, onItemSelectedListener)
rvSortItem.adapter = adapter
rvSortItem.layoutManager = LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false)
}
fun notifyDataSetChanged() {
adapter.notifyDataSetChanged()
}
}
\ No newline at end of file
package com.yidianling.tests.router
import android.app.Activity
import android.content.Intent
import com.yidianling.router.RouterManager
import com.yidianling.router.im.IMRequestCallback
/**
* author : Zhangwenchao
* e-mail : zhangwch@yidianling.com
* time : 2018/04/25
*/
object TestsIn {
fun isLogin(): Boolean {
return RouterManager.getUserRouter()?.isLogin()?:false
}
fun loginWayIntent(activity: Activity): Intent? {
return RouterManager.getUserRouter()?.loginWayIntent(activity)
}
fun publishTrendIntent(activity: Activity, url: String, cover: String, title: String): Intent? {
return RouterManager.getDynamicRouter()?.publishTrendIntent(activity, url, cover, title)
}
fun sendTestResultMessage(uid : String,content : String,title: String?,head : String?,url : String?,id : Int,share_url : String?, callback: IMRequestCallback<Void>) {
RouterManager.getImRouter().sendTestResultMessage(uid, content, title, head, url, id, share_url, callback)
}
/**
* 跳转红包
*/
fun myRedPockIntent(activity: Activity){
activity.startActivity(RouterManager.getAppRouter()?.myRedPockIntent(activity))
}
}
\ No newline at end of file
package com.yidianling.tests.router
import android.app.Activity
import android.content.Intent
import com.ydl.ydl_router.manager.YDLRouterManager
import com.ydl.ydl_router.manager.YDLRouterParams
import com.yidianling.router.tests.ITestsRouter
import com.yidianling.tests.answer.TestAnswerActivity
import com.yidianling.tests.detail.TestDetailActivity
import com.yidianling.tests.result.jump.JumpTestResultActivity
import com.yidianling.ydlcommon.BuildConfig
import com.yidianling.ydlcommon.router.IYDLRouterConstant
class TestsRouterImp : ITestsRouter {
override fun testH5Result(testResultId: String) {
YDLRouterManager.router(IYDLRouterConstant.ROUTER_H5_H5,
YDLRouterParams().putExtra(IYDLRouterConstant.EXTRA_URL, BuildConfig.MH5_URL+"ceshi/result/"+testResultId),"")
}
override fun testDetailH5(testId: String) {
YDLRouterManager.router(IYDLRouterConstant.ROUTER_H5_H5,
YDLRouterParams().putExtra(IYDLRouterConstant.EXTRA_URL, BuildConfig.MH5_URL+"ceshi/"+testId),"")
}
override fun testDetailIntent(activity: Activity, testId: Int): Intent {
return TestDetailActivity.newIntent(activity, testId.toString())
}
override fun testResultIntent(activity: Activity, testResultId: Int): Intent {
return JumpTestResultActivity.newIntent(activity, testResultId.toString())
}
override fun testAnswerIntent(activity: Activity): Intent {
return TestAnswerActivity.newIntent(activity)
}
}
\ No newline at end of file
package com.yidianling.tests.search
import android.support.v7.widget.RecyclerView
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.yidianling.tests.list.model.bean.Test
import com.yidianling.tests.R
import com.yidianling.tests.base.MyBaseAdapter
import kotlinx.android.synthetic.main.item_hot_test.view.*
/**
* HotTestListAdapter
* Created by zqk on 17-12-5.
*/
class HotTestListAdapter(val hotTestList: MutableList<Test>) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
companion object {
private val TYPE_NORMAL = 0
private val TYPE_HEADER = 1
}
var onItemClickListener: MyBaseAdapter.OnItemClickListener<Test>? = null
override fun onBindViewHolder(holder: RecyclerView.ViewHolder?, position: Int) {
if (holder is NormalViewHolder) {
holder.tvTestName.text = hotTestList[position - 1].name
}
}
override fun getItemViewType(position: Int): Int {
return if (position == 0) {
TYPE_HEADER
} else {
TYPE_NORMAL
}
}
override fun getItemCount(): Int = hotTestList.size + 1
override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): RecyclerView.ViewHolder {
return if (viewType == TYPE_NORMAL) {
val view = LayoutInflater.from(parent!!.context).inflate(R.layout.item_hot_test, parent, false)
NormalViewHolder(view)
} else {
val view = LayoutInflater.from(parent!!.context).inflate(R.layout.item_hot_test_header, parent, false)
object : RecyclerView.ViewHolder(view) {}
}
}
inner class NormalViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val tvTestName = itemView.tvTestName!!
init {
itemView.setOnClickListener {
if (adapterPosition != RecyclerView.NO_POSITION) {
onItemClickListener?.onItemClickListener(itemView, adapterPosition, hotTestList[adapterPosition - 1])
}
}
}
}
}
\ No newline at end of file
package com.yidianling.tests.search
import android.content.Context
import android.content.Intent
import android.support.v7.widget.LinearLayoutManager
import android.support.v7.widget.RecyclerView
import android.text.Editable
import android.text.TextUtils
import android.text.TextWatcher
import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
import android.view.inputmethod.EditorInfo
import android.view.inputmethod.InputMethodManager
import android.widget.LinearLayout
import android.widget.TextView
import cn.lankton.flowlayout.FlowLayout
import com.yidianling.common.tools.ToastUtil
import com.yidianling.router.RouterManager
import com.yidianling.tests.R
import com.yidianling.tests.base.BaseMvpActivity
import com.yidianling.tests.base.MyBaseAdapter
import com.yidianling.tests.home.event.UpdateCouponMoneyEvent
import com.yidianling.tests.home.utils.TestHomeUtils
import com.yidianling.tests.list.model.bean.RecommendSearchItemBean
import com.yidianling.tests.list.model.bean.Test
import com.yidianling.tests.list.view.adapter.TestListRecyclerAdapter
import com.yidianling.ydlcommon.listener.EndlessRecyclerViewScrollListener
import com.yidianling.ydlcommon.utils.SharedPreferencesEditor
import de.greenrobot.event.EventBus
import kotlinx.android.synthetic.main.activity_test_search.*
import kotlinx.android.synthetic.main.item_hot_search.view.*
class TestSearchActivity : BaseMvpActivity<TestSearchView, TestSearchPresenter>(), TestSearchView, View.OnClickListener {
private var isFirstLoad = true
override fun isAddStatusView(): Boolean {
return true
}
override fun statusBarDarkMode(): Boolean {
return true
}
override fun layoutResId(): Int {
return R.layout.activity_test_search
}
override fun initDataAndEvent() {
init()
}
companion object {
fun start(context: Context) {
context.startActivity(Intent(context, TestSearchActivity::class.java))
}
}
private var keyword: String? = null
private val searchedTestList: MutableList<Test> = ArrayList()
private val hotSearchedTestList: MutableList<Test> = ArrayList()
private var searchAdapter: TestListRecyclerAdapter? = null
private var hotSearchAdapter: TestListRecyclerAdapter? = null
private var isSearch = false
private var searchListCurrentPage = 1
private var onRecommendSearchListResponseFinish = false
private var onHotRecommendResponseFinish = false
private fun init() {
EventBus.getDefault().register(this)
setupListeners()
initRecyclerView()
initData()
}
fun initData() {
var lastCouponMoney = SharedPreferencesEditor.getString(TestHomeUtils.TEST_MAX_COUPON_MONEY_SP_KEY)
if (!TextUtils.isEmpty(lastCouponMoney)) {
searchAdapter?.couponMoney = lastCouponMoney
hotSearchAdapter?.couponMoney = lastCouponMoney
}
presenter.fetchHotTests()
presenter.hotRecommendRequest()
}
private lateinit var onScrollListener: EndlessRecyclerViewScrollListener
private var headerHotSearch: LinearLayout? = null
private var searchHeader: View? = null
private var flHotSearch: FlowLayout? = null
private var tvSearchHint: TextView? = null
private fun initRecyclerView() {
swipe_refresh_layout.isEnabled = false
searchAdapter = TestListRecyclerAdapter(this, searchedTestList, TestListRecyclerAdapter.PAGE_TYPE_SEARCH)
hotSearchAdapter = TestListRecyclerAdapter(this, hotSearchedTestList, TestListRecyclerAdapter.PAGE_TYPE_SEARCH)
searchAdapter?.onItemClickListener = MyBaseAdapter.OnItemClickListener { _, _, data ->
RouterManager.getTestsRouter()?.testDetailH5(data.id.toString())
}
hotSearchAdapter?.onItemClickListener = MyBaseAdapter.OnItemClickListener { _, _, data ->
RouterManager.getTestsRouter()?.testDetailH5(data.id.toString())
}
headerHotSearch = View.inflate(this, R.layout.header_hot_search, null) as LinearLayout?;
searchHeader = View.inflate(this, R.layout.header_search_list, null);
tvSearchHint = searchHeader?.findViewById(R.id.tv_search_hint);
flHotSearch = headerHotSearch?.findViewById(R.id.flHotSearch)
searchHeader?.let { searchAdapter?.setHeaderView(it) }
headerHotSearch?.let { hotSearchAdapter?.setHeaderView(it) }
rv_search_list.adapter = searchAdapter
rv_hot_list.adapter = hotSearchAdapter
val layoutManager = LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)
val hotLayoutManager = LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)
rv_search_list.layoutManager = layoutManager
rv_hot_list.layoutManager = hotLayoutManager
onScrollListener = object : EndlessRecyclerViewScrollListener(layoutManager) {
override fun onLoadMore(page: Int, totalItemsCount: Int, view: RecyclerView?) {
if (isSearch) {
presenter.searchTests(keyword, searchListCurrentPage)
}
}
}
rv_hot_list.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView?, dx: Int, dy: Int) {
if (!isFirstLoad) {
hideSoftInput()
}
}
})
rv_search_list.addOnScrollListener(onScrollListener)
}
private fun setupListeners() {
tvBack.setOnClickListener(this)
etSearch.addTextChangedListener(object : TextWatcher {
override fun afterTextChanged(s: Editable?) {
}
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
if (TextUtils.isEmpty(s.toString())) {
setSearchListVisibility(false)
isSearch = false
hideNoResultView()
}
}
})
etSearch.setOnEditorActionListener { _, actionId, _ ->
if (actionId == EditorInfo.IME_ACTION_SEARCH) {
doSearch()
}
true
}
}
override fun onClick(v: View?) {
when (v?.id) {
R.id.tvBack -> {
finish()
}
}
}
private fun doSearch() {
keyword = etSearch.text.toString()
if (TextUtils.isEmpty(keyword)) {
ToastUtil.toastShort(getString(R.string.no_search_keyword_hint))
return
}
hideSoftInput()
isSearch = true
searchListCurrentPage = 1
onScrollListener.resetState()
presenter.searchTests(keyword, searchListCurrentPage)
}
fun hideSoftInput() {
val view = this.currentFocus
if (view != null) {
val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
imm.hideSoftInputFromWindow(view.windowToken, 0)
}
}
/**
* 热门推荐
*/
override fun onHotRecommendResponse(datalist: List<Test>) {
rv_hot_list.adapter = hotSearchAdapter
hotSearchedTestList.clear()
onHotRecommendResponseFinish = true
hideRefreshView()
setSearchListVisibility(false)
if (datalist.isNotEmpty()) {
hotSearchAdapter?.hasMore = false
hotSearchedTestList.addAll(datalist)
hotSearchAdapter?.notifyDataSetChanged()
}
rv_hot_list.postDelayed({
isFirstLoad = false
}, 500)
}
/**
* 热门搜索
*/
override fun onRecommendSearchListResponse(keywordData: List<RecommendSearchItemBean>) {
if (keywordData.isEmpty()) {
headerHotSearch?.visibility = View.GONE
return
}
onRecommendSearchListResponseFinish = true
hideRefreshView()
setSearchListVisibility(false)
headerHotSearch?.visibility = View.VISIBLE
flHotSearch?.removeAllViews()
for (index in keywordData.indices) {
val view = LayoutInflater.from(this).inflate(R.layout.item_recommend_hot_search, flHotSearch, false)
view.tvHotSearch.text = keywordData[index].keyWord
view.setOnClickListener {
etSearch.setText(keywordData[index].keyWord)
doSearch()
}
flHotSearch?.addView(view)
}
}
/**
* 搜索结果
*/
override fun showSearchResultView(testList: List<Test>?, page: Int) {
if (page == 1) {
rv_search_list.adapter = searchAdapter
onScrollListener.resetState()
searchedTestList.clear()
}
if (testList != null && testList.isNotEmpty()) {
searchedTestList.addAll(testList)
searchAdapter?.notifyDataSetChanged()
} else {
searchAdapter?.hasMore = false
searchAdapter?.notifyDataSetChanged()
}
tvSearchHint?.text = String.format("为您找到以下跟“%s”有关的内容", keyword)
setSearchListVisibility(true)
searchListCurrentPage++
}
fun setSearchListVisibility(visibility: Boolean) {
rv_search_list.visibility = if (visibility) View.VISIBLE else View.GONE
rv_hot_list.visibility = if (visibility) View.GONE else View.VISIBLE
}
override fun createPresenter(): TestSearchPresenter = TestSearchPresenter()
override fun hideLoadingView() {
swipe_refresh_layout.isRefreshing = false
}
override fun hideNoResultView() {
llEmpty.visibility = View.GONE
}
override fun showLoadingView() {
swipe_refresh_layout.isRefreshing = true
}
override fun showError(msg: String) {
ToastUtil.toastShort(msg)
}
override fun showNoResultView() {
llEmpty.visibility = View.VISIBLE
iv_empty.visibility = View.VISIBLE
tv_search_empty.text = "没有搜到相关信息,换个关键词看看吧"
tv_search_empty.gravity = Gravity.CENTER_HORIZONTAL
}
override fun onResume() {
super.onResume()
//每次可见,更新优惠券信息
TestHomeUtils.updateCouponMoney()
}
/**
* 更新优惠券信息
* 刷新列表
*/
fun onEvent(updateCouponMoneyEvent: UpdateCouponMoneyEvent) {
searchAdapter?.couponMoney = updateCouponMoneyEvent.money
searchAdapter?.notifyDataSetChanged()
hotSearchAdapter?.couponMoney = updateCouponMoneyEvent.money
hotSearchAdapter?.notifyDataSetChanged()
}
override fun onDestroy() {
super.onDestroy()
EventBus.getDefault().unregister(this)
}
private fun hideRefreshView() {
if (onRecommendSearchListResponseFinish && onHotRecommendResponseFinish) {
hideLoadingView()
}
}
}
package com.yidianling.tests.search
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import com.hannesdorfmann.mosby3.mvp.MvpNullObjectBasePresenter
import com.ydl.ydlcommon.data.http.RxUtils
import com.ydl.ydlcommon.data.http.ThrowableConsumer
import com.yidianling.common.tools.ToastUtil
import com.yidianling.tests.TestRetrofitApi
import com.yidianling.tests.home.http.TestHomeDataManager
import com.yidianling.tests.home.param.TestHomeParam
import com.yidianling.tests.list.model.TestListCommand
import com.yidianling.tests.list.model.bean.Test
import com.yidianling.ydlcommon.app.YdlCommonApp
import com.yidianling.ydlcommon.http.RxUtils
import com.yidianling.ydlcommon.http.ThrowableConsumer
import com.yidianling.ydlcommon.http.YdlRetrofitUtils
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.functions.Consumer
import io.reactivex.schedulers.Schedulers
/**
* TestSearchPresenter
* Created by zqk on 17-12-5.
*/
class TestSearchPresenter : MvpNullObjectBasePresenter<TestSearchView>() {
fun fetchHotTests() {
view.showLoadingView()
val cmd = TestListCommand()
cmd.tab = "hot_test"
cmd.page = 1
TestRetrofitApi.getTestRetrofitApi()
.fetchTopSearch()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ resp ->
if (resp.code == "200") {
view.hideNoResultView()
view.onRecommendSearchListResponse(resp.data)
} else {
ToastUtil.toastShort(resp.msg)
view.hideLoadingView()
}
}, { throwble ->
YdlRetrofitUtils.handleError(YdlCommonApp.getApp(), throwble)
})
}
/**
* 测评热门推荐
*/
fun hotRecommendRequest() {
view.showLoadingView()
TestHomeDataManager
.getHttp()
.newHomeRequest(TestHomeParam( 0))
.compose(RxUtils.resultData())
.map { it }
.filter { it != null }
.observeOn(AndroidSchedulers.mainThread())
.subscribe(Consumer {
if (it[3].body!=null){
var jsonStr = Gson().toJson(it[3].body)
val list = Gson().fromJson<MutableList<Test>>(jsonStr, object : TypeToken<MutableList<Test>>() {
}.type)
view.hideNoResultView()
view.onHotRecommendResponse(list)
}else{
view.hideLoadingView()
}
}, object : ThrowableConsumer() {
override fun accept(msg: String) {
view.showError(msg)
}
})
}
fun searchTests(keyword: String?, page: Int) {
if (page == 1) {
view.showLoadingView()
}
val cmd = TestListCommand()
cmd.tab = "search"
cmd.page = page
cmd.keyword = keyword
TestRetrofitApi.getTestRetrofitApi()
.fetchTestList(YdlRetrofitUtils.getMaps(cmd))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ resp ->
if (resp.code == 0) {
view.hideLoadingView()
if (page == 1 && (resp.data.testList == null || resp.data.testList?.size == 0)) {
view.showNoResultView()
view.showSearchResultView(resp.data.testList, page)
} else {
view.hideNoResultView()
view.showSearchResultView(resp.data.testList, page)
}
} else {
view.hideLoadingView()
ToastUtil.toastShort(resp.msg)
}
}, { throwble ->
YdlRetrofitUtils.handleError(YdlCommonApp.getApp(), throwble)
})
}
}
\ No newline at end of file
package com.yidianling.tests.search
import com.hannesdorfmann.mosby3.mvp.MvpView
import com.yidianling.tests.list.model.bean.RecommendSearchItemBean
import com.yidianling.tests.list.model.bean.Test
/**
* TestSearchView
* Created by zqk on 17-12-5.
*/
interface TestSearchView : MvpView {
fun showLoadingView()
fun hideLoadingView()
fun showError(msg: String)
fun showNoResultView()
fun hideNoResultView()
fun showSearchResultView(testList: List<Test>?, page: Int)
fun onRecommendSearchListResponse(testList: List<RecommendSearchItemBean>)
fun onHotRecommendResponse(datalist : List<Test>)
}
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_enabled="true" android:state_pressed="true">
<shape android:shape="rectangle">
<stroke android:width="1dp" android:color="@color/google_green" />
<corners android:radius="100dp"/>
<solid android:color="#cacaca"/>
</shape>
</item>
<item android:state_enabled="true" android:state_pressed="false">
<shape android:shape="rectangle">
<stroke android:width="1dp" android:color="@color/google_green" />
<corners android:radius="100dp"/>
<solid android:color="@color/white"/>
</shape>
</item>
</selector>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_enabled="true" android:state_pressed="true">
<shape android:shape="rectangle">
<corners android:radius="100dp"/>
<solid android:color="@color/google_green_dark"/>
</shape>
</item>
<item android:state_enabled="true" android:state_pressed="false">
<shape android:shape="rectangle">
<corners android:radius="100dp"/>
<solid android:color="@color/google_green"/>
</shape>
</item>
</selector>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_enabled="true" android:state_pressed="true">
<color android:color="@color/google_green_dark" />
</item>
<item android:state_enabled="true" android:state_pressed="false">
<color android:color="@color/google_green" />
</item>
</selector>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="true" android:drawable="@drawable/ic_test_checked"/>
<item android:state_checked="false" android:drawable="@drawable/ic_test_unchecked"/>
</selector>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<stroke
android:width="0.5dp"
android:color="#FF5A4C"/>
<corners android:radius="7.5dp"/>
<solid android:color="#17ff5a4c"/>
</shape>
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:ignore="MissingDefaultResource">
<corners android:radius="@dimen/dp_20"/>
<solid android:color="@color/color_F7F7F7"/>
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="20dp"/>
<solid android:color="#F7F7F7" />
<stroke android:width="1px" android:color="#F0F0F0"/>
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<size
android:width="1dp"
android:height="1dp" />
<solid android:color="@color/colorDivider" />
</shape>
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@android:id/background">
<shape>
<solid android:color="#dddddd" />
</shape>
</item>
<item android:id="@android:id/secondaryProgress">
<clip>
<shape>
<solid android:color="@color/google_green" />
</shape>
</clip>
</item>
<item android:id="@android:id/progress">
<clip>
<shape>
<solid android:color="@color/google_green" />
</shape>
</clip>
</item>
</layer-list>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.yidianling.ydlcommon.view.TitleBar
android:layout_width="match_parent"
android:layout_height="@dimen/title_bar_height"
app:left_start_icon="@drawable/toolbar_back"
app:title_text="最新联系人" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:id="@+id/select_lv"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<TextView
android:id="@+id/text_empty"
android:text="暂无同任何专家的联系记录哦"
android:gravity="center"
android:padding="30dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone"/>
</RelativeLayout>
</LinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white"
tools:context=".answer.TestAnswerActivity">
<TextView
android:id="@+id/tvCurrent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/google_green"
android:textSize="18sp"
app:layout_constraintBottom_toBottomOf="@+id/tvTotal"
app:layout_constraintEnd_toStartOf="@+id/tvTotal"
tools:text="2" />
<TextView
android:id="@+id/tvTotal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="24dp"
android:layout_marginRight="24dp"
android:textColor="@color/color_grey_888888"
android:layout_marginTop="24dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/titleBar"
tools:text="/27" />
<ProgressBar
android:id="@+id/progressBar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="0dp"
android:layout_height="2dp"
android:layout_marginEnd="24dp"
android:layout_marginStart="24dp"
android:layout_marginTop="8dp"
android:progressDrawable="@drawable/progressbar_test"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tvTotal"
tools:progress="30" />
<com.ydl.ydlcommon.view.TitleBar
android:id="@+id/titleBar"
android:layout_width="match_parent"
android:layout_height="@dimen/title_bar_height"
app:pa_left_start_icon="@drawable/toolbar_back"
app:pa_right_iv="@drawable/more_green"
app:pa_right_end_icon="@drawable/share"
app:pa_title_text="心理测试" />
<FrameLayout
android:id="@+id/flContainer"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/progressBar">
</FrameLayout>
</android.support.constraint.ConstraintLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".list.view.TestListActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="@dimen/title_bar_height"
android:background="@color/white"
android:gravity="center_vertical"
>
<ImageView
android:id="@+id/iv_test_list_back"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="15dp"
android:src="@drawable/icon_test_back"
/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="32dp"
android:background="@drawable/bg_test_search_input"
android:orientation="horizontal"
android:layout_marginRight="15dp"
>
<ImageView
android:layout_width="13dp"
android:layout_height="13dp"
android:layout_gravity="center_vertical"
android:layout_marginLeft="12dp"
android:src="@drawable/search_gray"/>
<TextView
android:id="@+id/tv_test_search"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginLeft="8dp"
android:layout_weight="1"
android:gravity="center_vertical"
android:text="@string/search"
android:textColor="#BFBFBF"
android:textSize="@dimen/default_text_size_small"
android:textStyle="normal"
android:typeface="sans"/>
</LinearLayout>
</LinearLayout>
<LinearLayout
android:id="@+id/activity_tab_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
tools:context="q.rorbin.verticaltablayoutdemo.TabFragmentActivity">
<com.yidianling.ydlcommon.view.verticaltablayout.VerticalTabLayout
android:id="@+id/vt_test_search"
android:layout_width="72dp"
android:layout_height="match_parent"
android:background="#F7F7F7"
app:tab_height="44dp"
app:tab_indicator_margin="13dp"
app:tab_mode="scrollable"
/>
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="vertical"
>
<LinearLayout
android:id="@+id/ll_sort"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/white"
android:orientation="horizontal"
>
<com.yidianling.ydlcommon.view.DrawableRightTextView
android:id="@+id/dr_sort"
style="@style/FilterTextViewStyle"
android:layout_width="wrap_content"
android:layout_height="44dp"
android:layout_marginLeft="@dimen/dp_16"
android:drawableEnd="@drawable/ic_arrow_drop_down_grey_500_18dp"
android:drawableRight="@drawable/ic_arrow_drop_down_grey_500_18dp"
android:text="综合排序"
android:textColor="@color/color_242424"
/>
<com.yidianling.ydlcommon.view.DrawableRightTextView
android:id="@+id/dr_filter"
style="@style/FilterTextViewStyle"
android:layout_width="wrap_content"
android:layout_height="44dp"
android:drawableEnd="@drawable/ic_arrow_drop_down_grey_500_18dp"
android:drawableRight="@drawable/ic_arrow_drop_down_grey_500_18dp"
android:paddingLeft="15dp"
android:text="全部"
android:textColor="@color/color_242424"
/>
</LinearLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.yidianling.ydlcommon.view.verticaltablayout.VerticalViewPager
android:id="@+id/vvp_test"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
<View
android:id="@+id/view_mask"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#3c000000"
android:visibility="gone"
/>
</RelativeLayout>
</LinearLayout>
</LinearLayout>
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.yidianling.ydlcommon.view.TitleBar
android:id="@+id/title_bar"
android:layout_width="match_parent"
android:layout_height="@dimen/title_bar_height"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:left_start_icon="@drawable/toolbar_back"
app:right_iv="@drawable/more_green"
app:right_start_icon="@drawable/share"
app:title_text="测试介绍" />
<ScrollView
android:id="@+id/scrollView"
android:layout_width="0dp"
android:layout_height="0dp"
android:orientation="vertical"
app:layout_constraintBottom_toTopOf="@+id/btnStartTest"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/title_bar"
tools:visibility="visible">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:paddingBottom="16dp">
<ImageView
android:id="@+id/ivCover"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:contentDescription="@null"
android:scaleType="fitCenter" />
<TextView
android:id="@+id/tvTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/ivCover"
android:layout_marginEnd="24dp"
android:layout_marginStart="24dp"
android:layout_marginTop="16dp"
android:textAlignment="center"
android:textSize="20sp"
android:textStyle="bold"
tools:text="简易工作压力量表" />
<LinearLayout
android:id="@+id/llInfo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/tvTitle"
android:gravity="center_horizontal"
android:orientation="horizontal">
<TextView
android:id="@+id/tvTestCount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:drawableLeft="@drawable/ic_edit"
android:drawablePadding="8dp"
android:drawableStart="@drawable/ic_edit"
android:textColor="@color/color_black_ff999999"
android:textSize="12sp"
tools:text="3796人测过" />
<TextView
android:id="@+id/tvQuestionNum"
android:layout_width="wrap_content"
android:layout_height="16dp"
android:layout_marginLeft="24dp"
android:layout_marginStart="24dp"
android:layout_marginTop="8dp"
android:drawableLeft="@drawable/ic_item"
android:drawablePadding="8dp"
android:drawableStart="@drawable/ic_item"
android:textColor="@color/color_black_ff999999"
android:textSize="12sp"
tools:text="10个问题" />
</LinearLayout>
<TextView
android:id="@+id/tvDesc"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/llInfo"
android:layout_marginEnd="24dp"
android:layout_marginStart="24dp"
android:layout_marginTop="16dp"
android:lineSpacingExtra="8sp"
android:textColor="@color/color_black_333333"
android:textSize="16sp"
tools:text="每个人都会遇到压力,您想知道自己的压力状态吗?赶紧点击测试一下吧!" />
<TextView
android:id="@+id/tvTestTips"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/tvDesc"
android:layout_marginEnd="24dp"
android:layout_marginStart="24dp"
android:layout_marginTop="8dp"
android:text="@string/testdetail_tips"
android:textColor="@color/color_black_ff999999"
android:textSize="12sp" />
<TextView
android:id="@+id/tvDigmenTips"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/tvTestTips"
android:layout_marginEnd="24dp"
android:layout_marginStart="24dp"
android:layout_marginTop="8dp"
android:text="@string/testdetail_tips"
android:textColor="@color/color_black_ff999999"
android:textSize="12sp"
android:visibility="gone"
tools:visibility="visible" />
</RelativeLayout>
</ScrollView>
<Button
android:id="@+id/btnStartTest"
style="?android:attr/borderlessButtonStyle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="@drawable/bg_btn_no_corner_green"
android:text="@string/start_test"
android:textColor="@color/white"
android:textSize="18sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<FrameLayout
android:id="@+id/flLoading"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="@color/white"
android:paddingBottom="60dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/title_bar"
tools:visibility="gone">
<ProgressBar
style="?android:attr/progressBarStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center" />
</FrameLayout>
</android.support.constraint.ConstraintLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".list.view.TestListActivity">
<com.yidianling.ydlcommon.view.TitleBar
android:id="@+id/titleBar"
android:layout_width="match_parent"
android:layout_height="@dimen/title_bar_height"
app:bm_line_color="@color/transparent"
app:left_start_icon="@drawable/toolbar_back"
app:right_iv="@drawable/more12x"
app:right_start_icon="@drawable/icon_navsearch_green"
app:title_text="心理测试" />
<LinearLayout
android:id="@+id/llTestRedPacketTips"
android:layout_width="match_parent"
android:layout_height="@dimen/dp_36"
android:orientation="horizontal"
android:visibility="gone"
android:background="@color/color_FFEBE0">
<ImageView
android:layout_width="@dimen/dp_14"
android:layout_height="@dimen/dp_17"
android:layout_gravity="center_vertical"
android:layout_marginStart="@dimen/dp_15"
android:background="@drawable/test_redpacket" />
<TextView
android:id="@+id/tvTestRedPacketTips"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dp_12"
android:textSize="@dimen/dp_12"
android:textColor="@color/color_FF5B05"
android:layout_gravity="center_vertical"
tools:text="还有5个心理测试红包等你使用"/>
</LinearLayout>
<android.support.design.widget.TabLayout
android:id="@+id/tabLayout"
android:layout_width="match_parent"
android:layout_height="40dp"
app:tabIndicatorColor="@color/google_green"
app:tabMode="scrollable"
app:tabSelectedTextColor="@color/google_green" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@color/divide_color" />
<android.support.v4.view.ViewPager
android:id="@+id/viewPager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white"
tools:context="com.yidianling.tests.result.TestResultActivity">
<com.yidianling.ydlcommon.view.TitleBar
android:id="@+id/titleBar"
android:layout_width="match_parent"
android:layout_height="@dimen/title_bar_height"
app:left_start_icon="@drawable/toolbar_back"
app:right_end_icon="@drawable/share"
app:right_iv="@drawable/more_green"
app:title_text="@string/test_result" />
<LinearLayout
android:id="@+id/llButtons"
android:layout_width="match_parent"
android:layout_height="60dp"
android:gravity="center"
android:orientation="horizontal"
android:background="@drawable/bg_bottom_panel"
android:paddingLeft="24dp"
android:paddingRight="24dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent">
<Button
android:id="@+id/btnTestAgain"
style="?android:attr/borderlessButtonStyle"
android:layout_width="0dp"
android:layout_height="40dp"
android:layout_weight="1"
android:background="@drawable/bg_btn_big_corner_border_green"
android:text="@string/test_again"
android:textColor="@color/google_green"
android:textSize="16sp" />
<Button
android:id="@+id/btnSendToExpert"
style="?android:attr/borderlessButtonStyle"
android:layout_width="0dp"
android:layout_height="40dp"
android:layout_marginLeft="40dp"
android:layout_marginStart="40dp"
android:layout_weight="1"
android:background="@drawable/bg_btn_big_corner_green"
android:text="@string/send_to_expert"
android:textColor="@color/white"
android:textSize="16sp"
android:visibility="gone"
tools:visibility="visible" />
</LinearLayout>
<ScrollView
android:id="@+id/scrollView"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="@id/llButtons"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/titleBar">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingBottom="16dp"
android:paddingLeft="24dp"
android:paddingRight="24dp"
android:paddingTop="16dp">
<TextView
android:id="@+id/tvTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="6dp"
android:gravity="center_horizontal"
android:textSize="20sp"
android:textStyle="bold"
tools:text="你偏向顺从还是独立" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:drawableLeft="@drawable/ic_result"
android:drawablePadding="8dp"
android:drawableStart="@drawable/ic_result"
android:text="@string/test_result"
android:textColor="@color/google_green"
android:textSize="16sp" />
<TextView
android:id="@+id/tvDesc"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:lineSpacingExtra="8dp"
android:textSize="16sp"
tools:text="内内向型性格内向型性格内向型性格内向型性格内向型性格内向型性格内向型性格内向型性格向型性格" />
<LinearLayout
android:id="@+id/llDesc"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:orientation="vertical"
android:visibility="gone" />
<TextView
android:id="@+id/tvAnalyseLabel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="18dp"
android:drawableLeft="@drawable/ic_desc"
android:drawablePadding="8dp"
android:drawableStart="@drawable/ic_desc"
android:text="@string/introduction"
android:textColor="@color/google_green"
android:textSize="16sp"
android:visibility="gone"
tools:visibility="visible" />
<TextView
android:id="@+id/tvAnalyse"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:lineSpacingExtra="8sp"
android:textSize="16sp"
android:visibility="gone"
tools:text="内向型性格 " />
<TextView
android:id="@+id/tvTestAnswer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="18dp"
android:drawableLeft="@drawable/ic_answer"
android:drawablePadding="8dp"
android:drawableStart="@drawable/ic_answer"
android:text="@string/test_answer"
android:textColor="@color/google_green"
android:textSize="16sp"
android:visibility="gone"
tools:visibility="gone" />
<LinearLayout
android:id="@+id/llAnswers"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:orientation="vertical"
android:visibility="gone" />
</LinearLayout>
</ScrollView>
<FrameLayout
android:id="@+id/flLoading"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="@color/white"
android:paddingBottom="60dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/titleBar"
tools:visibility="gone">
<ProgressBar
style="?android:attr/progressBarStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center" />
</FrameLayout>
</android.support.constraint.ConstraintLayout>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/clContainer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white"
android:orientation="vertical"
tools:context=".search.TestSearchActivity">
<LinearLayout
android:id="@+id/ll_title"
android:layout_width="match_parent"
android:layout_height="45dp"
android:gravity="center_vertical"
app:layout_constraintTop_toTopOf="parent">
<com.yidianling.ydlcommon.view.DeleteEditTextView
android:id="@+id/etSearch"
android:layout_width="0dp"
android:layout_height="36dp"
android:layout_marginLeft="15dp"
android:layout_marginRight="5dp"
android:layout_weight="1"
android:background="@drawable/bg_test_search_input"
android:drawableStart="@drawable/search_gray"
android:drawableLeft="@drawable/search_gray"
android:drawablePadding="8dp"
android:ems="10"
android:hint="输入标题与内容"
android:imeOptions="actionSearch"
android:inputType="text|textPersonName"
android:lines="1"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:textCursorDrawable="@color/color_42C1FF"
android:textSize="14sp" />
<TextView
android:id="@+id/tvBack"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="6dp"
android:padding="10dp"
android:text="@string/cancel"
android:textColor="@color/color_999999" />
</LinearLayout>
<android.support.v4.widget.SwipeRefreshLayout
android:id="@+id/swipe_refresh_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="@+id/rv_hot_list"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<android.support.v7.widget.RecyclerView
android:id="@+id/rv_search_list"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<LinearLayout
android:id="@+id/llEmpty"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:visibility="gone"
tools:visibility="visible">
<ImageView
android:id="@+id/iv_empty"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="30dp"
android:src="@drawable/ico_img_zixun_empty"
android:visibility="gone"
tools:visibility="visible" />
<TextView
android:id="@+id/tv_search_empty"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="15dp"
tools:text="为您找到以下跟“付费”有关的内容" />
</LinearLayout>
</RelativeLayout>
</android.support.v4.widget.SwipeRefreshLayout>
</LinearLayout>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".answer.TestAnswerFragment">
<android.support.v7.widget.RecyclerView
android:id="@+id/rvAnswerList"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="24dp"
android:paddingRight="24dp"
android:overScrollMode="never" />
</FrameLayout>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".list.view.TestListFragment">
<android.support.v7.widget.RecyclerView
android:id="@+id/rvTestList"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<FrameLayout
android:id="@+id/flLoading"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white"
android:paddingBottom="60dp"
tools:visibility="visible">
<ProgressBar
style="?android:attr/progressBarStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center" />
</FrameLayout>
<LinearLayout
android:id="@+id/llNoTest"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white"
android:gravity="center"
android:orientation="vertical"
android:paddingBottom="100dp"
android:visibility="gone">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@null"
android:src="@drawable/blank" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:text="@string/no_test_record_hint"
android:textColor="@color/color_grey_888888" />
</LinearLayout>
</FrameLayout>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/llHotSearch"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="15dp"
android:clickable="true"
android:focusable="true"
android:orientation="vertical"
android:paddingLeft="15dp"
android:paddingRight="15dp"
tools:ignore="MissingDefaultResource">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="推荐搜索"
android:textColor="@color/color_999999"
android:textSize="@dimen/dp_12"
/>
<cn.lankton.flowlayout.FlowLayout
android:id="@+id/flHotSearch"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="12dp"
app:lineSpacing="6dp"
/>
<TextView
android:layout_marginTop="20dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="热门推荐"
android:textColor="@color/color_999999"
android:textSize="@dimen/dp_12"
/>
</LinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/tv_search_hint"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="15dp"
tools:text="为您找到以下跟“付费”有关的内容"
/>
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/white"
>
<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="15dp"
android:layout_marginTop="18dp"
android:layout_marginRight="123dp"
android:ellipsize="end"
android:maxLines="1"
android:textColor="@color/color_333333"
android:textSize="@dimen/sp_16"
android:textStyle="bold"
tools:text="你的心理足够成熟么你的心理足够成熟么"
/>
<TextView
android:id="@+id/tvContent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/tv_title"
android:layout_marginLeft="15dp"
android:layout_marginTop="5dp"
android:layout_marginRight="123dp"
android:ellipsize="end"
android:lineSpacingExtra="4dp"
android:maxLines="2"
android:minHeight="24dp"
android:minLines="2"
android:textColor="#666"
android:textSize="12sp"
tools:text="这里是副标题,这里是副标题,这里是副标题,这里是副标题"/>
<TextView
android:id="@+id/tv_price"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/cv_recom"
android:layout_marginTop="14dp"
android:layout_marginLeft="15dp"
android:background="@drawable/testhome_recom_price_bg"
android:gravity="center"
android:paddingLeft="5dp"
android:paddingTop="1dp"
android:paddingRight="5dp"
android:paddingBottom="1dp"
android:textColor="#34CD65"
android:textSize="11dp"
tools:text="免费"/>
<TextView
android:id="@+id/tv_coupon_money"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/bg_corner_border_orange"
android:textColor="#FF5A4C"
tools:text="券已抵扣5元"
android:layout_toRightOf="@id/tv_price"
android:layout_marginLeft="6dp"
android:paddingTop="1dp"
android:paddingBottom="1dp"
android:paddingRight="4dp"
android:paddingLeft="4dp"
android:textSize="10sp"
android:gravity="center"
android:layout_alignBottom="@id/tv_price"
android:layout_marginBottom="2dp"
android:visibility="gone"
tools:visibility="visible"
/>
<android.support.v7.widget.CardView
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/cv_recom"
android:layout_width="96dp"
android:layout_height="68dp"
android:layout_alignParentRight="true"
android:layout_marginTop="20dp"
android:layout_marginRight="15dp"
app:cardCornerRadius="6dp"
app:cardElevation="0px">
<ImageView
android:id="@+id/ivCover"
android:layout_width="96dp"
android:layout_height="68dp"
android:scaleType="centerCrop"/>
</android.support.v7.widget.CardView>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@id/tv_price"
android:layout_alignParentRight="true"
android:layout_marginRight="15dp"
android:gravity="bottom"
android:layout_marginTop="14dp"
>
<TextView
android:id="@+id/tv_hits"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#333333"
android:textSize="10sp"
android:textStyle="bold"
tools:text="16w"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="人气"
android:textColor="#666666"
android:textSize="10sp"/>
<TextView
android:id="@+id/tv_num"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:textColor="#333333"
android:textSize="10sp"
android:textStyle="bold"
tools:text="14000"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="bottom"
android:text="人已测"
android:textColor="#666666"
android:textSize="10sp"/>
</LinearLayout>
<View
android:id="@+id/s_bottom_line"
android:layout_width="match_parent"
android:layout_height="0.5dp"
android:layout_below="@+id/tv_price"
android:layout_marginLeft="15dp"
android:layout_marginTop="18dp"
android:layout_marginRight="15dp"
android:background="#F0F0F0"/>
</RelativeLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/tvHotSearch"
android:layout_width="wrap_content"
android:layout_height="30dp"
android:layout_marginBottom="6dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:background="@drawable/bg_radius_line_green_5"
android:gravity="center"
android:orientation="vertical"
android:paddingLeft="15dp"
android:paddingRight="15dp"
android:textColor="@color/google_green"
tools:text="自闭症" />
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?android:attr/selectableItemBackground"
android:orientation="vertical">
<TextView
android:id="@+id/tvTestName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:textColor="@color/default_text_color"
android:textSize="14sp"
tools:text="测一测你多容易感情用事" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:background="@color/divide_color" />
</LinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:padding="16dp"
android:text="@string/recommend_test"
android:textColor="@color/color_black_333333" />
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/tvHotSearch"
android:layout_width="wrap_content"
android:layout_height="30dp"
android:layout_marginBottom="6dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:background="@drawable/bg_gray_radius_20"
android:gravity="center"
android:orientation="vertical"
android:paddingLeft="15dp"
android:paddingRight="15dp"
android:textColor="@color/color_333333"
tools:text="自闭症"
tools:ignore="MissingDefaultResource"/>
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?android:attr/selectableItemBackground"
android:orientation="horizontal">
<TextView
android:id="@+id/tvSort"
android:layout_width="wrap_content"
android:layout_height="40dp"
android:gravity="center_vertical"
android:layout_marginLeft="16dp"
android:layout_marginStart="16dp"
android:textSize="14sp"
android:textColor="@color/color_242424"
tools:text="智能排序" />
</RelativeLayout>
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?android:attr/selectableItemBackground"
>
<TextView
android:id="@+id/tvNo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:paddingBottom="6dp"
android:paddingTop="6dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="A" />
<TextView
android:id="@+id/tvAnswer"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="12dp"
android:layout_marginEnd="12dp"
android:layout_marginStart="12dp"
android:layout_marginTop="12dp"
android:gravity="center_vertical"
android:textSize="16sp"
android:paddingBottom="6dp"
android:lineSpacingExtra="6sp"
android:paddingTop="6dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/radioButton"
app:layout_constraintStart_toEndOf="@+id/tvNo"
app:layout_constraintTop_toTopOf="parent"
tools:text="测测试选项测试选项测试选项测试选项测试选项测试选项测试选项试选项" />
<RadioButton
android:id="@+id/radioButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginTop="8dp"
android:button="@drawable/bg_btn_radio"
android:clickable="false"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="20dp"
android:paddingTop="34dp">
<Button
android:id="@+id/btnGoBefore"
style="?android:attr/borderlessButtonStyle"
android:layout_width="wrap_content"
android:layout_height="40dp"
android:background="@drawable/bg_btn_big_corner_border_green"
android:drawableLeft="@drawable/ic_back"
android:drawablePadding="8dp"
android:drawableStart="@drawable/ic_back"
android:paddingLeft="34dp"
android:paddingRight="34dp"
android:text="@string/last_question"
android:textColor="@color/google_green"
android:textSize="16sp" />
</FrameLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingBottom="16dp"
android:paddingTop="16dp">
<TextView
android:id="@+id/tvQuestion"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="@color/color_black_333333"
android:textSize="18sp"
tools:text="觉得时间不够用,所以分秒必争" />
<ImageView
android:id="@+id/ivImage"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:adjustViewBounds="true"
android:contentDescription="@null"
android:scaleType="fitCenter"
android:visibility="gone" />
</LinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:padding="6dp"
android:layout_height="wrap_content">
<TextView
android:id="@+id/tvName"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginTop="8dp"
android:text="维度"
android:textAlignment="center"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/tvAverage"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintHorizontal_chainStyle="spread_inside"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tvAverage"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginTop="8dp"
android:text="平均分"
android:textAlignment="center"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/tvTotal"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/tvName"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tvTotal"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginTop="8dp"
android:text="得分"
android:textAlignment="center"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/tvAverage"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/white"
>
<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="15dp"
android:layout_marginTop="18dp"
android:layout_marginRight="146dp"
android:ellipsize="end"
android:maxLines="1"
android:textSize="@dimen/sp_16"
android:textStyle="bold"
android:textColor="@color/color_333333"
tools:text="你的心理足够成熟么你的心理足够成熟么"/>
<TextView
android:id="@+id/tvContent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/tv_title"
android:layout_marginLeft="15dp"
android:layout_marginTop="5dp"
android:layout_marginRight="146dp"
android:ellipsize="end"
android:maxLines="2"
android:textColor="#666"
android:textSize="12sp"
android:lineSpacingExtra="4dp"
android:minLines="2"
android:minHeight="24dp"
tools:text="这里是副标题,这里是副标题,这里是副标题,这里是副标题"/>
<TextView
android:id="@+id/tv_price"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/cv_recom"
android:layout_marginTop="@dimen/dp_12"
android:layout_marginLeft="15dp"
android:background="@drawable/testhome_recom_price_bg"
android:gravity="center"
android:paddingLeft="5dp"
android:paddingTop="2dp"
android:paddingRight="5dp"
android:paddingBottom="2dp"
android:textColor="#34CD65"
android:textSize="11dp"
tools:text="免费"/>
<TextView
android:id="@+id/tv_coupon_money"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/bg_corner_border_orange"
android:textColor="#FF5A4C"
tools:text="券已抵扣5元"
android:layout_toRightOf="@id/tv_price"
android:layout_marginLeft="6dp"
android:paddingTop="1dp"
android:paddingBottom="1dp"
android:paddingRight="4dp"
android:paddingLeft="4dp"
android:textSize="10sp"
android:gravity="center"
android:layout_alignBottom="@id/tv_price"
android:layout_marginBottom="2dp"
android:visibility="gone"
tools:visibility="visible"
/>
<android.support.v7.widget.CardView
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/cv_recom"
android:layout_width="115dp"
android:layout_height="68dp"
android:layout_alignParentRight="true"
android:layout_marginTop="20dp"
android:layout_marginRight="15dp"
app:cardCornerRadius="6dp"
app:cardElevation="0px">
<ImageView
android:id="@+id/ivCover"
android:layout_width="115dp"
android:layout_height="68dp"
android:scaleType="centerCrop"/>
</android.support.v7.widget.CardView>
<LinearLayout
android:layout_alignBottom="@id/tv_price"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/cv_recom"
android:layout_alignParentRight="true"
android:layout_marginRight="15dp"
android:gravity="bottom"
>
<TextView
android:id="@+id/tv_hits"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="bottom"
android:textColor="#333333"
android:textSize="10sp"
android:textStyle="bold"
tools:text="16w"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="bottom"
android:textColor="#666666"
android:textSize="10sp"
android:text="人气"/>
<TextView
android:id="@+id/tv_num"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:gravity="bottom"
android:textColor="#333333"
android:textSize="10sp"
android:textStyle="bold"
tools:text="14000"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="bottom"
android:text="人已测"
android:textColor="#666666"
android:textSize="10sp"/>
</LinearLayout>
<View
android:id="@+id/s_bottom_line"
android:layout_width="match_parent"
android:layout_height="0.5dp"
android:layout_below="@+id/tv_price"
android:layout_marginLeft="15dp"
android:layout_marginTop="18dp"
android:layout_marginRight="15dp"
android:background="#F0F0F0"/>
</RelativeLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:background="#ff0000">
<ImageView
android:id="@+id/sdv_head"
android:layout_width="50dp"
android:layout_height="50dp"
android:padding="5dp" />
<TextView
android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_gravity="center_vertical"
android:layout_marginLeft="10dp"
android:layout_marginTop="5dp"
android:layout_toRightOf="@id/sdv_head"
android:text="小壹"
android:textColor="#444444"
android:textSize="17sp" />
<TextView
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_below="@id/sdv_head"
android:background="@color/divide_color" />
</RelativeLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="40dp"
android:gravity="center"
android:orientation="horizontal"
android:background="@color/white"
>
<ProgressBar
android:id="@+id/circle_progress"
style="?android:attr/progressBarStyleSmallTitle"
android:layout_width="20dp"
android:layout_height="20dp"
android:padding="4dp"
android:visibility="gone"
tools:visibility="visible"/>
<ImageView
android:id="@+id/iv_no_more_left"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="4dp"
android:src="@drawable/icon_no_more_left"
android:visibility="gone"
/>
<TextView
android:id="@+id/tv_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="加载中"
android:textSize="10sp"
android:textColor="#BFBFBF"/>
<ImageView
android:id="@+id/iv_no_more_right"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="4dp"
android:src="@drawable/icon_no_more_right"
android:visibility="gone"/>
</LinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners
android:radius="50dp"/>
<solid
android:color="#40ffffff"/>
</shape>
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<gradient
android:startColor="#56CCF2"
android:endColor="#2F80ED"
android:angle="0" />
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<stroke
android:width="0.5dp"
android:color="#BEBEBE"/>
<corners
android:radius="20dp"/>
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners
android:radius="3dp"/>
<solid
android:color="@color/transparent"/>
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners
android:radius="3dp"/>
<solid
android:color="#1A34CD65"/>
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v4.widget.SwipeRefreshLayout
android:id="@+id/swipe_refresh_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone" />
<include layout="@layout/testhome_bar" />
</FrameLayout>
</android.support.v4.widget.SwipeRefreshLayout>
</FrameLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="162dp"
android:background="@drawable/testhome_bg" />
<android.support.v7.widget.CardView xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="15dp"
android:layout_marginTop="54dp"
android:layout_marginRight="15dp"
app:cardCornerRadius="6dp"
app:cardElevation="2dp">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="146dp">
<com.yidianling.ydlcommon.view.banner.Banner
android:id="@+id/banner"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:indicator_different_width="14dp"
app:indicator_drawable_selected="@drawable/testhome_tip_select"
app:indicator_drawable_unselected="@drawable/testhome_tip_unselect"
app:indicator_height="5dp"
app:indicator_margin="1.25dp"
app:is_selected_same_unselected="false" />
</FrameLayout>
</android.support.v7.widget.CardView>
</merge>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="48dp"
android:orientation="horizontal">
<View
android:id="@+id/v_bg"
android:layout_width="match_parent"
android:layout_height="48dp"
android:background="@drawable/testhome_bg" />
<LinearLayout
android:id="@+id/ll_bar_root"
android:layout_width="match_parent"
android:layout_height="48dp"
android:orientation="horizontal">
<ImageView
android:id="@+id/img_back"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="15dp"
android:background="@drawable/testhome_back" />
<RelativeLayout
android:id="@+id/rl_search"
android:layout_width="0px"
android:layout_height="32dp"
android:layout_gravity="center_vertical"
android:layout_marginLeft="15dp"
android:layout_weight="1"
android:background="@drawable/testhome_bar_search_bg"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:drawableLeft="@drawable/testhome_search"
android:drawablePadding="4dp"
android:hint="输入关键字查找测评"
android:textColorHint="#B3ffffff"
android:textSize="12dp" />
</RelativeLayout>
<ImageView
android:id="@+id/img_mine"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="15dp"
android:layout_marginRight="15dp"
android:padding="5dp"
android:src="@drawable/testhome_mine" />
</LinearLayout>
</FrameLayout>
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<android.support.v7.widget.CardView xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="30dp"
android:layout_marginLeft="15dp"
android:layout_marginRight="15dp"
android:layout_marginTop="20dp"
app:cardCornerRadius="6dp"
app:cardElevation="2dp">
<FrameLayout
android:id="@+id/fl_root"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="10dp"
android:paddingTop="24dp" />
</android.support.v7.widget.CardView>
<View
android:layout_width="match_parent"
android:layout_height="9dp"
android:background="#F0F0F0" />
</merge>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18dp"
android:layout_marginTop="30dp"
android:layout_marginLeft="15dp"
android:drawablePadding="5dp"
android:drawableLeft="@drawable/testhome_everyday"
tools:text="每日精选" />
<TextView
android:id="@id/testhome_dailyRight"
android:layout_width="48dp"
android:layout_height="19dp"
android:layout_marginTop="30dp"
android:layout_alignParentRight="true"
android:gravity="center"
android:text="@string/testhome_dailychange"
android:textSize="10dp"
android:textColor="#666"
android:layout_marginRight="15dp"
android:background="@drawable/testhome_dailychange_bg"/>
</merge>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/ll_root"
android:orientation="horizontal" android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="13dp"
android:paddingBottom="25dp">
</LinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="156dp"
android:layout_height="wrap_content"
xmlns:tools="http://schemas.android.com/tools"
android:paddingBottom="10dp"
>
<ImageView
android:id="@+id/img_icon"
android:layout_width="156dp"
android:layout_height="90dp"
android:scaleType="centerCrop"/>
<TextView
android:id="@+id/tv_title"
android:layout_below="@+id/img_icon"
android:layout_width="156dp"
android:layout_height="wrap_content"
android:textSize="14dp"
android:textColor="#333"
android:maxLines="2"
android:ellipsize="end"
android:layout_marginTop="16dp"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:textStyle="bold"
android:lines="2"
tools:text="天生命好?测试你是欧洲人还是非洲人"/>
<TextView
android:id="@+id/tv_price"
android:layout_below="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="15dp"
android:layout_marginTop="@dimen/dp_10"
android:background="@drawable/testhome_recom_price_bg"
android:gravity="center"
android:paddingBottom="2dp"
android:paddingLeft="5dp"
android:paddingRight="5dp"
android:paddingTop="2dp"
android:textColor="#34CD65"
android:textSize="11dp"
tools:text="免费"
/>
<TextView
android:layout_alignBottom="@id/img_icon"
android:id="@+id/tv_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="6dp"
android:layout_marginBottom="4dp"
android:gravity="right"
android:paddingRight="16dp"
android:textSize="10dp"
android:textColor="#d7ffffff"
android:layout_marginTop="6dp"
android:lines="1"
android:ellipsize="end"
tools:text="5616人测过"/>
<TextView
android:id="@+id/tv_coupon_money"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/bg_corner_border_orange"
android:textColor="#FF5A4C"
tools:text="券已抵扣5元"
android:layout_toRightOf="@id/tv_price"
android:layout_marginLeft="6dp"
android:paddingTop="1dp"
android:paddingBottom="1dp"
android:paddingRight="4dp"
android:paddingLeft="2dp"
android:textSize="10sp"
android:gravity="center"
android:layout_alignBottom="@id/tv_price"
android:visibility="gone"
tools:visibility="visible"
android:layout_marginBottom="4dp"
/>
</RelativeLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.Space
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="0px"/>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v4.widget.Space
android:layout_width="match_parent"
android:layout_height="1dp"/>
<TextView
android:id="@+id/item_load_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:layout_marginBottom="20dp"
android:layout_centerInParent="true"
android:drawablePadding="5dp"
android:text="上拉加载更多"
android:textColor="#666"
android:textSize="15dp"/>
<ProgressBar
android:id="@+id/item_load_pb"
style="@android:style/Widget.Holo.ProgressBar"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_centerVertical="true"
android:visibility="gone"/>
</RelativeLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:background="?android:attr/selectableItemBackground"
xmlns:tools="http://schemas.android.com/tools">
<ImageView
android:id="@+id/img_icon_in"
android:layout_width="15dp"
android:layout_height="15dp"
android:layout_gravity="center_vertical"
android:layout_marginLeft="15dp"
android:scaleType="centerCrop"
android:background="@drawable/testhome_category"/>
<TextView
android:layout_gravity="center_vertical"
tools:text="杰伦布朗刚测了"
android:layout_marginLeft="6dp"
android:id="@+id/tv_name_in"
android:textColor="#999"
android:textSize="12dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:layout_gravity="center_vertical"
tools:text="你的内心有几岁"
android:layout_marginLeft="6dp"
android:id="@+id/tv_title_in"
android:textSize="12dp"
android:textColor="#FAA05A"
android:lines="1"
android:ellipsize="end"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:background="?android:attr/selectableItemBackground"
xmlns:tools="http://schemas.android.com/tools">
<ImageView
android:id="@+id/img_icon_out"
android:layout_width="15dp"
android:layout_height="15dp"
android:layout_gravity="center_vertical"
android:layout_marginLeft="15dp"
android:scaleType="centerCrop"
android:background="@drawable/testhome_category"/>
<TextView
android:layout_gravity="center_vertical"
tools:text="杰伦布朗刚测了"
android:layout_marginLeft="6dp"
android:id="@+id/tv_name_out"
android:textColor="#999"
android:textSize="12dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:layout_gravity="center_vertical"
tools:text="你的内心有几岁"
android:layout_marginLeft="6dp"
android:id="@+id/tv_title_out"
android:textSize="12dp"
android:textColor="#FAA05A"
android:lines="1"
android:ellipsize="end"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="5dp"
android:layout_marginLeft="15dp"
android:layout_marginRight="15dp"
android:layout_marginTop="70dp"
app:cardCornerRadius="6dp"
app:cardElevation="2dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:id="@+id/img_recom"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="centerCrop" />
<TextView
android:id="@+id/tv_recomTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="15dp"
android:layout_marginRight="15dp"
android:layout_marginTop="15dp"
android:ellipsize="end"
android:lines="1"
android:textColor="#3d3d3d"
android:textSize="15dp"
tools:text="天生好命?测你是欧洲人还是非洲人" />
<TextView
android:id="@+id/tv_recomContent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="15dp"
android:layout_marginRight="15dp"
android:layout_marginTop="8dp"
android:ellipsize="end"
android:lines="1"
android:textColor="#666"
android:textSize="12dp"
tools:text="你是速度快放假独守空房绝对是框架的首付款涉及到开发商贷款纠纷" />
<View
android:id="@+id/v_line"
android:layout_width="match_parent"
android:layout_height="0.5dp"
android:layout_marginLeft="15dp"
android:layout_marginRight="15dp"
android:layout_marginTop="13dp"
android:background="#F0F0F0" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="36dp">
<TextView
android:id="@+id/tv_recomPrice"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="15dp"
android:layout_marginTop="@dimen/dp_10"
android:background="@drawable/testhome_recom_price_bg"
android:gravity="center"
android:paddingBottom="2dp"
android:paddingLeft="5dp"
android:paddingRight="5dp"
android:paddingTop="2dp"
android:textColor="#34CD65"
android:textSize="11dp"
tools:text="免费" />
<TextView
android:id="@+id/tv_coupon_money"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/bg_corner_border_orange"
android:textColor="#FF5A4C"
tools:text="券已抵扣5元"
android:layout_toRightOf="@id/tv_recomPrice"
android:layout_marginLeft="6dp"
android:paddingTop="1dp"
android:paddingBottom="1dp"
android:paddingRight="4dp"
android:paddingLeft="4dp"
android:textSize="10sp"
android:gravity="center"
android:layout_alignBottom="@id/tv_recomPrice"
android:layout_marginBottom="4dp"
android:visibility="gone"
tools:visibility="visible"
/>
<TextView
android:id="@+id/tv_recomNum"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginRight="15dp"
android:textColor="#999"
android:textSize="10dp"
tools:text="14000人测过" />
<TextView
android:id="@+id/tv_Hits"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginRight="14dp"
android:layout_toLeftOf="@+id/tv_recomNum"
android:textColor="#999"
android:textSize="10dp"
tools:text="5616人气" />
</RelativeLayout>
</LinearLayout>
</android.support.v7.widget.CardView>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="wrap_content"
android:layout_width="match_parent"
xmlns:tools="http://schemas.android.com/tools">
<TextView
android:id="@+id/tv_recomTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="@dimen/sp_16"
android:textStyle="bold"
android:layout_marginTop="20dp"
android:layout_marginLeft="15dp"
android:layout_marginRight="191dp"
android:maxLines="2"
android:ellipsize="end"
tools:text="你的心理足够成熟么"/>
<TextView
android:id="@+id/tv_recomContent"
android:layout_below="@+id/tv_recomTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="191dp"
android:textSize="12dp"
android:ellipsize="end"
android:textColor="#666"
android:maxLines="2"
android:layout_marginTop="8dp"
android:layout_marginLeft="15dp"
tools:text="这里是副标题,这里是副标题,这里是副标题,这里是副标题"/>
<TextView
android:id="@+id/tv_recomPrice"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="5dp"
android:paddingRight="5dp"
android:paddingTop="2dp"
android:paddingBottom="2dp"
android:layout_alignBottom="@+id/tv_recomNum"
android:gravity="center"
android:layout_marginTop="@dimen/dp_10"
android:layout_marginLeft="15dp"
android:textSize="11dp"
android:textColor="#34CD65"
android:background="@drawable/testhome_recom_price_bg"
tools:text="免费"/>
<TextView
android:id="@+id/tv_coupon_money"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/bg_corner_border_orange"
android:textColor="#FF5A4C"
tools:text="券已抵扣5元"
android:layout_toRightOf="@id/tv_recomPrice"
android:layout_marginLeft="6dp"
android:paddingTop="1dp"
android:paddingBottom="1dp"
android:paddingRight="4dp"
android:paddingLeft="4dp"
android:textSize="10sp"
android:gravity="center"
android:layout_alignBottom="@id/tv_recomPrice"
android:layout_marginBottom="2dp"
android:visibility="gone"
tools:visibility="visible"
/>
<android.support.v7.widget.CardView
android:id="@+id/cv_recom"
android:layout_width="156dp"
android:layout_height="90dp"
android:layout_marginTop="20dp"
android:layout_marginRight="15dp"
android:layout_alignParentRight="true"
xmlns:app="http://schemas.android.com/apk/res-auto"
app:cardElevation="0px"
app:cardCornerRadius="6dp">
<ImageView
android:id="@+id/img_recom"
android:scaleType="centerCrop"
android:layout_width="156dp"
android:layout_height="90dp"/>
</android.support.v7.widget.CardView>
<TextView
android:id="@+id/tv_recomNum"
android:layout_below="@+id/cv_recom"
android:layout_alignParentRight="true"
android:layout_marginRight="15dp"
android:layout_width="wrap_content"
android:layout_height="23dp"
android:textSize="10dp"
android:textColor="#999"
android:gravity="bottom"
tools:text="14000人测过"/>
<TextView
android:id="@+id/tv_Hits"
android:layout_width="wrap_content"
android:layout_height="23dp"
android:gravity="bottom"
android:textSize="10dp"
android:textColor="#999"
android:layout_below="@+id/cv_recom"
android:layout_toLeftOf="@+id/tv_recomNum"
android:layout_marginRight="14dp"
tools:text="5616人气"/>
<View
android:id="@+id/s_bottom_line"
android:layout_below="@+id/tv_recomNum"
android:layout_width="match_parent"
android:layout_height="0.5dp"
android:background="#F0F0F0"
android:layout_marginTop="13dp"
android:layout_marginLeft="15dp"
android:layout_marginRight="15dp" />
</RelativeLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
tools:ignore="MissingDefaultResource">
<View
android:clickable="false"
android:layout_width="72dp"
android:layout_height="100dp"/>
<android.support.v7.widget.RecyclerView
android:id="@+id/rvSortItem"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="@color/white"
tools:ignore="MissingDefaultResource"/>
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="testhome_line">#F0F0F0</color>
<color name="testhome_title">#666</color>
</resources>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<resources>
<item name="testhome_dailytitle" type="id"/>
<item name="testhome_dailyRight" type="id"/>
<item name="testhome_recommenTitle" type="id"/>
<item name="testhome_daily" type="id"/>
<item name="testhome_ll_tips" type="id"/>
</resources>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="testhome_dailychange">换一换</string>
<string name="testhome_just">刚刚</string>
<string name="testhome_test">测试了</string>
<string name="testhome_hit">人气</string>
<string name="testhome_peopletest">人测过</string>
</resources>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!---->
<style name="style_price_start">
<item name="android:textSize">16sp</item>
<item name="android:textColor">#FF5B05</item>
<item name="android:textStyle">bold</item>
</style>
<style name="style_price_end">
<item name="android:textSize">10sp</item>
<item name="android:textColor">#FF5B05</item>
</style>
<style name="FilterTextViewStyle">
<item name="android:layout_height">40dp</item>
<item name="android:textSize">14sp</item>
<item name="android:background">?android:attr/selectableItemBackground</item>
<item name="android:gravity">center</item>
<item name="android:paddingLeft">15dp</item>
<item name="android:paddingRight">15dp</item>
</style>
</resources>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="color_grey_888888">#888888</color>
<color name="colorDivider">#ebebeb</color>
<color name="color_black_333333">#333333</color>
<color name="color_black_ff999999">#999999</color>
</resources>
\ No newline at end of file
<resources>
<string name="app_name">tests</string>
<string name="start_test">立即测试</string>
<string name="test_result">测试结果</string>
<string name="test_again">重新测试</string>
<string name="send_to_expert">专家解读</string>
<string name="test_answer">测试回答</string>
<string name="introduction">说明</string>
<string name="last_question">上一题</string>
<string name="no_test_record_hint">还没有测试记录哦</string>
<string name="recommend_test">推荐测试</string>
<string name="test_count">%d人测过</string>
<string name="questions">%d个问题</string>
<string name="wrong_args">参数异常</string>
<string name="no_search_keyword_hint">请输入关键字</string>
<string name="gson_parse_error">解析错误</string>
<string name="test_either">我也要测试</string>
<string name="dialog_loading">加载中…</string>
<string name="load_end">没有更多了</string>
<string name="loading">正在加载中…</string>
<string name="search">搜索</string>
<string name="testdetail_tips">*温馨提示:测评报告生成后不可重复测试</string>
</resources>
package com.yidianling.tests;
import org.junit.Assert;
import org.junit.Test;
import static org.junit.Assert.*;
/**
* Example local unit test, which will execute on the development machine (host).
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
public class ExampleUnitTest {
@Test
public void addition_isCorrect() throws Exception {
assertEquals(4, 2 + 2);
}
String[] list1 = {"17826875951", "1782687595", "178268759", "17826875", "1782687", "178268", "17826", "1782", "178", "17", "1", "17826efdg465154",
"165e2244", "111e12345", "我的123是121223423", "我的123456789", "符合规范357545655分好尴尬", "符合规范3555分好尴尬", "订单1234", "订单12345",
"我的QQ号是3386218996", "178 2687 5951", "1q1q1q11q", "123456789a"};
String[] list2 = {"178****5951", "178****595", "178****59", "17****75", "17****7", "17****", "1****", "1782", "178", "17", "1", "1****efdg46****",
"165e2244", "111e1****", "我的123是121****23", "我的123****89", "符合规范357****55分好尴尬", "符合规范3555分好尴尬", "订单1234", "订单1****",
"我的QQ号是338****996", "178 2687 5951", "1q1q1q11q", "123****89a"};
/**
* 用于测试数字替换*的功能,功能与ios一样
*/
@Test
public void set() {
for (int tt = 0; tt < list1.length; tt++) {
String text = list1[tt];
String assertString = list2[tt];
String lastText = "";
int numberIndex = -1;
int numberCount = 0;
for (int i = 0; i < text.length(); i++) {
if (text.charAt(i) >= 48 && text.charAt(i) <= 57) {
numberIndex = i;
for (int j = i; j < text.length(); j++) {
if (text.charAt(j) >= 48 && text.charAt(j) <= 57) {
numberCount++;
if (j == text.length() - 1) {
if (numberCount >= 5) {
while (i < numberIndex + numberCount / 3) {
lastText += text.charAt(i++);
}
while (i < numberIndex + numberCount / 3 + 4) {
lastText += "*";
i++;
}
while (i <= j) {
lastText += text.charAt(i++);
}
} else {
while (i <= j) {
lastText += text.charAt(i++);
}
}
i = j;
break;
}
} else {
if (numberCount >= 5) {
while (i < numberIndex + numberCount / 3) {
lastText += text.charAt(i++);
}
while (i < numberIndex + numberCount / 3 + 4) {
lastText += "*";
i++;
}
while (i < j) {
lastText += text.charAt(i++);
}
} else {
while (i < j) {
lastText += text.charAt(i++);
}
}
i = j - 1;
numberIndex = -1;
numberCount = 0;
break;
}
}
} else {
lastText += text.charAt(i);
}
}
assertEquals(lastText, assertString);
}
}
}
\ No newline at end of file
......@@ -26,7 +26,7 @@ android {
}
}
flavorDimensions "versionCode"
flavorDimensions "versionCode"//Flavor 维度信息
}
......
modular {
//模块包名
packageName "com.yidianling.user"
// 模块发布需要的参数
publish {
modules {
xlzx {
//发布信息 module/api 通用
groupId = "com.ydl"
artifactId = "m-user-module-xlzx"
// 上报的业务模块 aar 包的版本号
artifactId = "m-xxx-module-xlzx"
// 上报的 心理咨询 业务模块 aar 包的版本号
version = "0.0.19"
}
ydl{
//发布信息 module/api 通用
groupId = "com.ydl"
artifactId = "m-user-module-ydl"
// 上报的业务模块 aar 包的版本号
// 上报的 壹点灵 业务模块 aar 包的版本号
version = "0.0.19"
}
}
api {
//发布信息 module/api 通用
//壹点灵/心理咨询 业务模块 API层 jar包的发布信息
groupId = "com.ydl"
artifactId = "m-user-api"
//开发时注释掉版本号,发布api时打开
version = "0.0.5"
// API 层打包时需要引入的依赖
apiDependencies {
......
include ':app', ':ydl-net', ':ydl-utils', ':ydl-platform', ':ydl-webview', ':ydl-media',":m-user", ':m-consultant',":router"
include ':app',":router", ':ydl-net', ':ydl-utils', ':ydl-platform', ':ydl-webview', ':ydl-media',":m-user", ':m-consultant'
//, ':m-tests'
\ No newline at end of file
......@@ -4,14 +4,14 @@
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<application>
<service android:name=".music.PlayService" />
<service android:name=".audio.PlayService" />
<receiver android:name=".music.receiver.RemoteControlReceiver">
<receiver android:name=".audio.receiver.RemoteControlReceiver">
<intent-filter>
<action android:name="android.intent.action.MEDIA_BUTTON" />
</intent-filter>
</receiver>
<receiver android:name=".music.receiver.StatusBarReceiver">
<receiver android:name=".audio.receiver.StatusBarReceiver">
<intent-filter>
<action android:name="com.ydl.media.STATUS_BAR_ACTIONS" />
</intent-filter>
......
package com.ydl.media.music
package com.ydl.media.audio
import android.content.Context
import android.content.IntentFilter
......@@ -6,13 +6,13 @@ import android.media.AudioManager
import android.os.Handler
import android.os.Looper
import com.tencent.bugly.Bugly.applicationContext
import com.ydl.media.music.enums.PlayModeEnum
import com.ydl.media.music.manager.AudioFocusManager
import com.ydl.media.music.manager.MediaSessionManager
import com.ydl.media.music.manager.NotifyManager
import com.ydl.media.music.model.Music
import com.ydl.media.music.receiver.NoisyAudioStreamReceiver
import com.ydl.media.music.utils.PlayProgressUtil
import com.ydl.media.audio.enums.PlayModeEnum
import com.ydl.media.audio.manager.AudioFocusManager
import com.ydl.media.audio.manager.MediaSessionManager
import com.ydl.media.audio.manager.NotifyManager
import com.ydl.media.audio.model.Music
import com.ydl.media.audio.receiver.NoisyAudioStreamReceiver
import com.ydl.media.audio.utils.PlayProgressUtil
import com.yidianling.common.tools.ToastUtil
import tv.danmaku.ijk.media.player.IMediaPlayer
import tv.danmaku.ijk.media.player.IjkMediaPlayer
......@@ -140,11 +140,16 @@ class AudioPlayer private constructor() {
PlayProgressUtil.saveProgress(applicationContext, playMusic!!.path, 0)
}
for (listener in listeners) {
listener.onComplete()
}
if (playMode == PlayModeEnum.SINGLE) {
stopPlayer()
playMode = PlayModeEnum.LIST_LOOP
return@setOnCompletionListener
}
next()
}
handler = Handler(Looper.getMainLooper())
......
package com.ydl.media.music
package com.ydl.media.audio
import com.ydl.media.music.model.Music
import com.ydl.media.audio.model.Music
/**
* Created by haorui on 2019-10-27 .
......@@ -42,4 +42,9 @@ interface OnPlayerEventListener {
* duration:时长
*/
fun onPrepared(duration:Long)
/**
* 单曲播放完成
*/
fun onComplete()
}
package com.ydl.media.music
package com.ydl.media.audio
import android.app.Service
import android.content.Context
......@@ -6,9 +6,9 @@ import android.content.Intent
import android.os.Binder
import android.os.IBinder
import android.util.Log
import com.ydl.media.music.constants.Extras
import com.ydl.media.music.manager.MediaSessionManager
import com.ydl.media.music.manager.NotifyManager
import com.ydl.media.audio.constants.Extras
import com.ydl.media.audio.manager.MediaSessionManager
import com.ydl.media.audio.manager.NotifyManager
/**
* Created by haorui on 2019-10-27 .
......
package com.ydl.media.music.constants
package com.ydl.media.audio.constants
/**
* Created by haorui on 2019-10-27 .
......
package com.ydl.media.music.enums
package com.ydl.media.audio.enums
/**
* Created by haorui on 2019-10-27 .
......
package com.ydl.media.music.manager
package com.ydl.media.audio.manager
import android.content.Context
import android.content.Context.AUDIO_SERVICE
import android.media.AudioManager
import com.ydl.media.music.AudioPlayer
import com.ydl.media.audio.AudioPlayer
/**
* Created by haorui on 2019-10-27 .
......
package com.ydl.media.music.manager
package com.ydl.media.audio.manager
import android.graphics.Bitmap
import android.os.Build
import android.support.v4.media.MediaMetadataCompat
import android.support.v4.media.session.MediaSessionCompat
import android.support.v4.media.session.PlaybackStateCompat
import com.ydl.media.music.AudioPlayer
import com.ydl.media.music.PlayService
import com.ydl.media.music.model.Music
import com.ydl.media.music.utils.CoverImageUtils
import com.ydl.media.audio.AudioPlayer
import com.ydl.media.audio.PlayService
import com.ydl.media.audio.model.Music
import com.ydl.media.audio.utils.CoverImageUtils
/**
......@@ -79,7 +79,7 @@ class MediaSessionManager private constructor() {
return
}
CoverImageUtils.loadThumb(music.coverPath!!,object :CoverImageUtils.OnCoverLoadListenre{
CoverImageUtils.loadThumb(music.coverPath!!,object :CoverImageUtils.OnCoverLoadListener{
override fun onComplete(bitmap: Bitmap) {
val metaData = MediaMetadataCompat.Builder()
.putString(MediaMetadataCompat.METADATA_KEY_TITLE, music.title)
......
package com.ydl.media.music.manager
package com.ydl.media.audio.manager
import android.annotation.SuppressLint
import android.app.Notification
......@@ -18,10 +18,10 @@ import android.widget.TextView
import com.bumptech.glide.Glide
import com.bumptech.glide.request.target.NotificationTarget
import com.ydl.media.R
import com.ydl.media.music.PlayService
import com.ydl.media.music.constants.Extras
import com.ydl.media.music.model.Music
import com.ydl.media.music.receiver.StatusBarReceiver
import com.ydl.media.audio.PlayService
import com.ydl.media.audio.constants.Extras
import com.ydl.media.audio.model.Music
import com.ydl.media.audio.receiver.StatusBarReceiver
import java.util.*
......@@ -112,18 +112,10 @@ class NotifyManager private constructor() {
private fun getRemoteViews(context: Context, music: Music, isPlaying: Boolean): RemoteViews {
val title = music.title
// String subtitle = FileUtils.getArtistAndAlbum(music.getArtist(), music.getAlbum());
val subtitle = music.artist + "-" + music.album
val remoteViews = RemoteViews(context.packageName, R.layout.notification)
// val cover = CoverLoader.get().loadThumb(music)
// if (cover != null) {
// remoteViews.setImageViewBitmap(R.id.iv_icon, cover)
// } else {
// remoteViews.setImageViewResource(R.id.iv_icon, R.drawable.ic_launcher)
// }
remoteViews.setTextViewText(R.id.tv_title, title)
remoteViews.setTextViewText(R.id.tv_subtitle, subtitle)
......
package com.ydl.media.music.model
package com.ydl.media.audio.model
import android.text.TextUtils
......
package com.ydl.media.music.receiver
package com.ydl.media.audio.receiver
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import com.ydl.media.music.AudioPlayer
import com.ydl.media.audio.AudioPlayer
/**
......
package com.ydl.media.music.receiver
package com.ydl.media.audio.receiver
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.support.v4.media.session.MediaSessionCompat
import android.view.KeyEvent
import com.ydl.media.music.AudioPlayer
import com.ydl.media.audio.AudioPlayer
/**
......
package com.ydl.media.music.receiver
package com.ydl.media.audio.receiver
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.text.TextUtils
import com.ydl.media.music.AudioPlayer
import com.ydl.media.audio.AudioPlayer
/**
......
package com.ydl.media.music.utils
package com.ydl.media.audio.utils
import android.graphics.*
import com.bumptech.glide.Glide
......@@ -347,7 +347,7 @@ object CoverImageUtils {
return target
}
fun loadThumb(url: String,onCoverLoadListener: OnCoverLoadListenre) {
fun loadThumb(url: String,onCoverLoadListener: OnCoverLoadListener) {
Glide.with(BaseApp.getApp()).asBitmap()
.load(url).into(object : SimpleTarget<Bitmap>() {
override fun onResourceReady(resource: Bitmap?, transition: Transition<in Bitmap>?) {
......@@ -356,7 +356,7 @@ object CoverImageUtils {
})
}
fun loadRound(url: String,onCoverLoadListener: OnCoverLoadListenre){
fun loadRound(url: String,onCoverLoadListener: OnCoverLoadListener){
Glide.with(BaseApp.getApp()).asBitmap()
.apply(
RequestOptions.bitmapTransform(
......@@ -368,7 +368,7 @@ object CoverImageUtils {
})
}
fun loadBlur(url: String,onCoverLoadListener: OnCoverLoadListenre){
fun loadBlur(url: String,onCoverLoadListener: OnCoverLoadListener){
val disallowHardwareConfig =
RequestOptions().format(DecodeFormat.PREFER_RGB_565).disallowHardwareConfig()
Glide.with(BaseApp.getApp()).asBitmap().apply(disallowHardwareConfig).load(url).into(object : SimpleTarget<Bitmap>() {
......@@ -378,7 +378,7 @@ object CoverImageUtils {
})
}
interface OnCoverLoadListenre {
interface OnCoverLoadListener {
fun onComplete(bitmap: Bitmap)
}
}
package com.ydl.media.music.utils
package com.ydl.media.audio.utils
import android.content.Context
import android.text.TextUtils
......
package com.ydl.media.view
/**
* Created by haorui on 2019-10-27 .
* Des: 播放类型
*/
enum class PlayTypeEnum private constructor(private val value: Int) {
//未指定具体类型
PLAY_TYPE_NONE(0),
//电台播放类型
PLAY_TYPE_FM(1),
//课程播放类型
PLAY_TYPE_COURSE(2),
//倾诉播放类型
PLAY_TYPE_CONFIDE(3),
//冥想播放类型
PLAY_TYPE_MUSE(4);
fun value(): Int {
return value
}
companion object {
fun valueOf(value: Int): PlayTypeEnum {
when (value) {
0 -> return PLAY_TYPE_NONE
1 -> return PLAY_TYPE_FM
2 -> return PLAY_TYPE_COURSE
3 -> return PLAY_TYPE_CONFIDE
4 -> return PLAY_TYPE_MUSE
else -> return PLAY_TYPE_NONE
}
}
}
}
package com.ydl.media.view
import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.graphics.PixelFormat
import android.graphics.Point
import android.os.Bundle
import android.text.TextUtils
import android.view.Gravity
import android.view.View
import android.view.WindowManager
import com.alibaba.android.arouter.launcher.ARouter
import com.ydl.media.audio.AudioPlayer
import com.yidianling.common.tools.RxImageTool
/**
* 音频播放悬浮窗 帮助类
*
* 需要在Activity onDestroy中调用removeView()方法移除
* 避免内存泄露
*/
class PlayerFloatHelper {
companion object {
@SuppressLint("StaticFieldLeak")
private var mPlayerFloatView: PlayerFloatView? = null
//已添加悬浮窗页面全路径名
private var showingPageName: String? = null
private var wm: WindowManager? = null
var playingType = PlayTypeEnum.PLAY_TYPE_NONE
var playTempData = hashMapOf<String,String>()
/**
* 如果有音频正在播放则显示
*/
fun showIfPlaying(context: Context) {
if (AudioPlayer.get().isPlaying) {
show(context)
mPlayerFloatView?.updatePlayState()
} else {
hide()
}
}
/**
* 显示悬浮控件
*/
fun show(context: Context, playTypeEnum: PlayTypeEnum = PlayTypeEnum.PLAY_TYPE_NONE, playData:HashMap<String,String> = hashMapOf<String,String>()) {
playingType = playTypeEnum
if (playData.size>0){
this.playTempData.putAll(playData)
}
if (mPlayerFloatView == null) {
mPlayerFloatView = PlayerFloatView(context)
mPlayerFloatView?.addFloatClickListener(object :PlayerFloatView.FloatViewPlayListener{
override fun onPauseClick() {
}
override fun onStartClick() {
}
override fun onPlayFinish() {
}
})
}
if (showingPageName != context::class.qualifiedName) {
mPlayerFloatView?.resetWm(context)
addFloatToWm(context)
}
mPlayerFloatView?.resetView()
mPlayerFloatView?.visibility = View.VISIBLE
mPlayerFloatView?.setPlayingState()
}
fun hide() {
mPlayerFloatView?.visibility = View.GONE
}
fun addClickListener(listener: PlayerFloatView.FloatViewPlayListener) {
mPlayerFloatView?.addFloatClickListener(listener)
}
fun removeClickListener(listener: PlayerFloatView.FloatViewPlayListener) {
mPlayerFloatView?.removeFloatClickListener(listener)
}
fun isShow(context: Context): Boolean {
return !TextUtils.isEmpty(showingPageName) && showingPageName == context::class.qualifiedName && mPlayerFloatView?.visibility == View.VISIBLE
}
fun removeView(context: Context) {
if (TextUtils.isEmpty(showingPageName) || showingPageName != context::class.qualifiedName) {
return
}
mPlayerFloatView?.visibility = View.GONE
wm?.removeViewImmediate(mPlayerFloatView)
showingPageName = ""
wm = null
}
fun onDestroy() {
if (mPlayerFloatView != null) {
if (!TextUtils.isEmpty(showingPageName)) {
wm?.removeViewImmediate(mPlayerFloatView)
showingPageName = ""
}
mPlayerFloatView?.onDestroy()
mPlayerFloatView?.removeAllViews()
}
}
fun setPlayingState(context: Context) {
show(context)
mPlayerFloatView?.setPlayingState()
}
fun updatePlayState() {
mPlayerFloatView?.updatePlayState()
}
private fun addFloatToWm(context: Context) {
if (wm != null && !TextUtils.isEmpty(showingPageName)) {
wm?.removeViewImmediate(mPlayerFloatView)
wm = null
}
//获取WindowManager
wm = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
//设置LayoutParams(全局变量)相关参数
val wmParams = mPlayerFloatView?.wmParams
wmParams?.type = WindowManager.LayoutParams.TYPE_APPLICATION //设置window type
wmParams?.format = PixelFormat.RGBA_8888 //设置图片格式,效果为背景透明
//设置Window flag
wmParams?.flags =
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL or WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
wmParams?.gravity = Gravity.LEFT or Gravity.TOP //调整悬浮窗口至左上角
//以屏幕左上角为原点,设置x、y初始值
val size = Point()
wm?.defaultDisplay?.getSize(size)
wmParams?.x = 0
wmParams?.y = size.y * 5 / 6
//设置悬浮窗口长宽数据
wmParams?.width = WindowManager.LayoutParams.MATCH_PARENT
wmParams?.height = RxImageTool.dp2px(56f)
//显示myFloatView图像
wm?.addView(mPlayerFloatView, wmParams)
showingPageName = context::class.qualifiedName!!
}
/**
* 打开播放中的页面详情
*/
fun startPlayingActivity(context: Context?, fullScreen: Int = 0) {
if (playingType == PlayTypeEnum.PLAY_TYPE_FM) {
//FM播放页
startFMPlayActivity(context)
} else if (playingType == PlayTypeEnum.PLAY_TYPE_COURSE) {
var url = AudioPlayer.get().playMusic?.path
//课程播放页
startCoursePlayActivity(context, 1, fullScreen, url, true)
}
}
fun startCoursePlayActivity(context: Context?, from: Int, fullScreen: Int = 0, coursePlayUrl: String? = "", isFromFloatView: Boolean = false) {
ARouter.getInstance()
.build("/course/play")
.withInt("course_id", playTempData["course_id"]?.toInt()?:0)
.withInt("course_type", 0)
.withString("coursePlayUrl", coursePlayUrl)
.withInt("from", from)
.withBoolean("isFromFloatView", isFromFloatView)
.withInt("fullScreen", fullScreen)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
.navigation()
}
fun startFMPlayActivity(context: Context?) {
val bundle = Bundle()
bundle.putInt("id", playTempData["fmId"]?.toInt()?:0)
ARouter.getInstance().build("/fm/detail")
.withBundle("bundle", bundle)
.navigation()
}
}
}
package com.ydl.media.view
import android.annotation.SuppressLint
import android.content.Context
import android.os.Handler
import android.os.Message
import android.text.TextUtils
import android.util.Log
import android.view.MotionEvent
import android.view.View
import android.view.ViewConfiguration
import android.view.WindowManager
import android.widget.*
import com.ydl.media.R
import com.ydl.media.audio.AudioPlayer
import com.ydl.media.audio.OnPlayerEventListener
import com.ydl.media.audio.model.Music
import com.ydl.ydl_image.module.GlideApp
import com.ydl.ydl_image.transform.GlideRoundTransform
import java.util.*
import java.util.concurrent.CopyOnWriteArraySet
class PlayerFloatView(var mContext: Context) : FrameLayout(mContext) {
private var mTouchStartX: Float = 0.toFloat()
private var mTouchStartY: Float = 0.toFloat()
private var mCurrX: Float = 0.toFloat()
private var mCurrY: Float = 0.toFloat()
private var playState: ImageView? = null
private var mAudioLayout: LinearLayout? = null
private var mInfoLayout: RelativeLayout? = null
private var playClose: ImageView? = null
private var playHead: ImageView? = null
private var titleView: TextView? = null
private var nameView: TextView? = null
private var currentPlayingTimeView: TextView? = null
private var durationView: TextView? = null
private var mTouchSlop: Int = 0
private var time: Int = 0
private var allTime: Int = 0
private var isMove: Boolean = false
private var wm: WindowManager? = null
//此wmParams为获取的全局变量,用以保存悬浮窗口的属性
var wmParams = WindowManager.LayoutParams()
private var myHandler: Handler? = null
private val UPDATE_VIEW_STATE = 1
private val UPDATE_VIEW_COMPLETE = 2
private val UPDATE_PLAY_TIME = 3//更新播放时间
private var listeners: CopyOnWriteArraySet<FloatViewPlayListener> = CopyOnWriteArraySet()
private var mStateChangeListener: OnPlayerEventListener? = null
private var playData:HashMap<String,String> = hashMapOf<String,String>()
init {
init(context)
}
fun resetWm(context: Context) {
wm = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
wmParams = WindowManager.LayoutParams()
}
fun resetView() {
resetAudioView()
}
@SuppressLint("ClickableViewAccessibility")
private fun init(context: Context) {
wm = getContext().getSystemService(Context.WINDOW_SERVICE) as WindowManager
mTouchSlop = ViewConfiguration.get(getContext()).scaledTouchSlop + 8
val view = View.inflate(context, R.layout.item_playing_float_btn, this)
mAudioLayout = view.findViewById(R.id.ll_audio_layout)
mInfoLayout = view.findViewById(R.id.rl_info)
playHead = view.findViewById(R.id.play_head)
playState = view.findViewById(R.id.play_state)
playClose = view.findViewById(R.id.play_close)
titleView = view.findViewById(R.id.tv_title)
nameView = view.findViewById(R.id.tv_name)
currentPlayingTimeView = view.findViewById(R.id.tv_now_playing_time)
durationView = view.findViewById(R.id.tv_duration)
resetAudioView()
if (!TextUtils.isEmpty(AudioPlayer.get().playMusic?.coverPath)) {
GlideApp.with(context.applicationContext)
.load(AudioPlayer.get().playMusic?.coverPath)
.transform(GlideRoundTransform(context, 4))
.error(R.drawable.ico_play_float_pic)
.into(playHead!!)
}
myHandler = MyHandler()
playHead!!.setOnTouchListener { _, event ->
mCurrX = event.rawX
mCurrY = event.rawY - 25
when (event.action) {
MotionEvent.ACTION_DOWN -> {
//获取相对View的坐标,即以此View左上角为原点
mTouchStartX = event.x
mTouchStartY = event.y
}
MotionEvent.ACTION_MOVE -> {
if (Math.abs(event.x - mTouchStartX) > mTouchSlop || Math.abs(event.y - mTouchStartY) > mTouchSlop) {
updateViewPosition()
isMove = true
}
}
MotionEvent.ACTION_UP -> {
if (Math.abs(event.x - mTouchStartX) > mTouchSlop ||
Math.abs(event.y - mTouchStartY) > mTouchSlop || isMove) {
updateViewPosition()
} else {
if (!isMove) {
PlayerFloatHelper.startPlayingActivity(context)
}
}
isMove = false
mTouchStartY = 0f
mTouchStartX = mTouchStartY
}
}
true
}
titleView!!.setOnTouchListener { v, event ->
mCurrX = event.rawX
mCurrY = event.rawY - 25
when (event.action) {
MotionEvent.ACTION_DOWN -> {
//获取相对View的坐标,即以此View左上角为原点
mTouchStartX = event.x
mTouchStartY = event.y
}
MotionEvent.ACTION_MOVE -> {
if (Math.abs(event.x - mTouchStartX) > mTouchSlop || Math.abs(event.y - mTouchStartY) > mTouchSlop) {
updateViewPosition()
isMove = true
}
}
MotionEvent.ACTION_UP -> {
if (Math.abs(event.x - mTouchStartX) > mTouchSlop ||
Math.abs(event.y - mTouchStartY) > mTouchSlop || isMove) {
updateViewPosition()
} else {
if (!isMove) {
PlayerFloatHelper.startPlayingActivity(context)
}
}
isMove = false
mTouchStartY = 0f
mTouchStartX = mTouchStartY
}
}
true
}
nameView!!.setOnTouchListener { _, event ->
mCurrX = event.rawX
mCurrY = event.rawY - 25
when (event.action) {
MotionEvent.ACTION_DOWN -> {
//获取相对View的坐标,即以此View左上角为原点
mTouchStartX = event.x
mTouchStartY = event.y
}
MotionEvent.ACTION_MOVE -> {
if (Math.abs(event.x - mTouchStartX) > mTouchSlop || Math.abs(event.y - mTouchStartY) > mTouchSlop) {
updateViewPosition()
isMove = true
}
}
MotionEvent.ACTION_UP -> {
if (Math.abs(event.x - mTouchStartX) > mTouchSlop ||
Math.abs(event.y - mTouchStartY) > mTouchSlop || isMove) {
updateViewPosition()
} else {
if (!isMove) {
PlayerFloatHelper.startPlayingActivity(context)
}
}
isMove = false
mTouchStartY = 0f
mTouchStartX = mTouchStartY
}
}
true
}
playClose!!.setOnTouchListener { v, event ->
mCurrX = event.rawX
mCurrY = event.rawY - 25
when (event.action) {
MotionEvent.ACTION_DOWN -> {
//获取相对View的坐标,即以此View左上角为原点
mTouchStartX = event.x
mTouchStartY = event.y
}
MotionEvent.ACTION_MOVE -> {
if (Math.abs(event.x - mTouchStartX) > mTouchSlop || Math.abs(event.y - mTouchStartY) > mTouchSlop) {
updateViewPosition()
isMove = true
}
}
MotionEvent.ACTION_UP -> {
if (Math.abs(event.x - mTouchStartX) > mTouchSlop ||
Math.abs(event.y - mTouchStartY) > mTouchSlop || isMove) {
updateViewPosition()
} else {
if (!isMove) {
this@PlayerFloatView.visibility = View.GONE
PlayerFloatHelper.removeView(mContext)
PlayerFloatHelper.playTempData.clear()
AudioPlayer.get().stopPlayer()
}
}
isMove = false
mTouchStartY = 0f
mTouchStartX = mTouchStartY
}
}
true
}
playState!!.setOnTouchListener { _, event ->
mCurrX = event.rawX
mCurrY = event.rawY - 25
when (event.action) {
MotionEvent.ACTION_DOWN -> {
//获取相对View的坐标,即以此View左上角为原点
mTouchStartX = event.x
mTouchStartY = event.y
}
MotionEvent.ACTION_MOVE -> {
if (Math.abs(event.x - mTouchStartX) > mTouchSlop || Math.abs(event.y - mTouchStartY) > mTouchSlop) {
updateViewPosition()
isMove = true
}
}
MotionEvent.ACTION_UP -> {
if (Math.abs(event.x - mTouchStartX) > mTouchSlop ||
Math.abs(event.y - mTouchStartY) > mTouchSlop || isMove) {
updateViewPosition()
} else {
if (!isMove) {
if (AudioPlayer.get().isPlaying) {
playState!!.setImageResource(R.drawable.ico_yyfc_play)
AudioPlayer.get().playPause()
for (listener in listeners) {
//数据重新设置回调
listener.onPauseClick()
}
} else {
playState!!.setImageResource(R.drawable.ico_yyfc_pause)
AudioPlayer.get().playPause()
for (listener in listeners) {
//数据重新设置回调
listener.onStartClick()
}
}
}
}
isMove = false
mTouchStartY = 0f
mTouchStartX = mTouchStartY
}
}
true
}
if (mStateChangeListener == null) {
mStateChangeListener = object : OnPlayerEventListener{
override fun onComplete() {
myHandler?.sendEmptyMessage(UPDATE_VIEW_COMPLETE)
}
override fun onChange(music: Music) {
}
override fun onPlayerStart() {
}
override fun onPlayerPause() {
}
override fun onPublish(percent: Int, currentPosition: Long) {
this@PlayerFloatView.time = currentPosition.toInt()
myHandler?.sendEmptyMessage(UPDATE_PLAY_TIME)
}
override fun onBufferingUpdate(percent: Int) {
}
override fun onPrepared(duration: Long) {
this@PlayerFloatView.allTime = duration.toInt()
myHandler?.sendEmptyMessage(UPDATE_PLAY_TIME)
myHandler?.sendEmptyMessage(UPDATE_VIEW_STATE)
}
}
AudioPlayer.get().addOnPlayEventListener(mStateChangeListener!!)
}
}
private fun resetAudioView() {
if (!TextUtils.isEmpty(AudioPlayer.get().playMusic?.coverPath)) {
GlideApp.with(context.applicationContext)
.load(AudioPlayer.get().playMusic?.coverPath)
.transform(GlideRoundTransform(context, 4))
.error(R.drawable.ico_play_float_pic)
.into(playHead!!)
}
if (TextUtils.isEmpty(AudioPlayer.get().playMusic?.title)) {
if (PlayerFloatHelper.playingType == PlayTypeEnum.PLAY_TYPE_FM) {
titleView!!.text = "心灵电台"
}
if (PlayerFloatHelper.playingType == PlayTypeEnum.PLAY_TYPE_CONFIDE) {
titleView!!.text = "壹点倾诉,心灵寄语"
}
} else {
titleView!!.text = AudioPlayer.get().playMusic?.title
}
if (TextUtils.isEmpty(AudioPlayer.get().playMusic?.artist)) {
nameView!!.text = "壹点灵"
} else {
nameView!!.text = AudioPlayer.get().playMusic?.artist
}
mAudioLayout!!.visibility = View.VISIBLE
}
private fun getStringTime(time: Int): String {
if (time <= 0) return "00:00"
var min = time / 60000
var ss = (time - min * 60000) / 1000
var mm = "" + min
var SS = "" + ss
if (min < 10) {
mm = "0$mm"
}
if (ss < 10) {
SS = "0$ss"
}
return "$mm:$SS"
}
private fun updatePlayTime() {
currentPlayingTimeView?.text = getStringTime(time)
durationView?.text = getStringTime(allTime)
}
override fun onTouchEvent(event: MotionEvent): Boolean {
//获取相对屏幕的坐标,即以屏幕左上角为原点
mCurrX = event.rawX
mCurrY = event.rawY - 25
Log.i("currP", "currX$mCurrX====currY$mCurrY")
when (event.action) {
MotionEvent.ACTION_DOWN -> {
//获取相对View的坐标,即以此View左上角为原点
mTouchStartX = event.x
mTouchStartY = event.y
}
MotionEvent.ACTION_MOVE -> updateViewPosition()
MotionEvent.ACTION_UP -> {
updateViewPosition()
mTouchStartY = 0f
mTouchStartX = mTouchStartY
}
}
return true
}
private fun updateViewPosition() {
//更新浮动窗口位置参数
wmParams.x = (mCurrX - mTouchStartX).toInt()
wmParams.y = (mCurrY - mTouchStartY).toInt()
wm!!.updateViewLayout(this, wmParams)
}
fun updatePlayState() {
if (AudioPlayer.get().isPlaying) {
playState!!.setImageResource(R.drawable.ico_yyfc_pause)
} else {
playState!!.setImageResource(R.drawable.ico_yyfc_play)
for (listener in listeners) {
listener.onPauseClick()
}
}
}
fun setPlayingState() {
playState!!.setImageResource(R.drawable.ico_yyfc_pause)
resetAudioView()
}
fun onDestroy() {
listeners.clear()
mStateChangeListener?.let { AudioPlayer.get().removeOnPlayEventListener(it) }
}
fun addFloatClickListener(floatClickListener: FloatViewPlayListener) {
listeners.add(floatClickListener)
}
fun removeFloatClickListener(floatClickListener: FloatViewPlayListener) {
listeners.remove(floatClickListener)
}
interface FloatViewPlayListener {
fun onPauseClick()
fun onStartClick()
fun onPlayFinish()
}
internal inner class MyHandler : Handler() {
override fun handleMessage(msg: Message) {
when (msg.what) {
UPDATE_VIEW_STATE -> updatePlayState()
UPDATE_VIEW_COMPLETE -> {
updatePlayState()
for (listener in listeners) {
//数据重新设置回调
listener.onPlayFinish()
}
}
UPDATE_PLAY_TIME -> {
updatePlayTime()
}
}
}
}
}
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="10dp" />
<solid android:color="@color/platform_color_99000000" />
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:id="@+id/ll_audio_layout"
android:layout_width="match_parent"
android:layout_height="56dp"
android:layout_marginLeft="15dp"
android:layout_marginRight="15dp"
android:background="@drawable/play_float_background"
android:gravity="center_vertical"
android:orientation="horizontal">
<ImageView
android:id="@+id/play_close"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_gravity="center"
android:layout_marginLeft="12.5dp"
android:padding="2.5dp"
android:src="@drawable/ico_play_float_pause"
android:visibility="visible" />
<ImageView
android:id="@+id/play_head"
android:layout_width="66dp"
android:layout_height="36dp"
android:layout_marginLeft="12.5dp"
android:src="@drawable/ico_play_float_pic" />
<RelativeLayout
android:id="@+id/rl_info"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="6dp"
android:layout_weight="1">
<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="1"
android:textColor="@color/white"
android:textSize="14sp"
tools:text="丁sir说抑郁丁sir说抑郁:像心理学" />
<TextView
android:id="@+id/tv_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/tv_title"
android:textColor="@color/platform_color_BFBFBF"
android:textSize="10sp"
android:maxLength="10"
tools:text="丁建略丁建略丁建略丁建略" />
<TextView
android:id="@+id/tv_line"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/tv_title"
android:layout_toRightOf="@+id/tv_name"
android:text=" | "
android:textColor="@color/platform_color_BFBFBF"
android:textSize="10sp" />
<TextView
android:id="@+id/tv_now_playing_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/tv_title"
android:layout_toRightOf="@+id/tv_line"
android:textColor="@color/platform_color_BFBFBF"
android:textSize="10sp"
tools:text="00:06" />
<TextView
android:id="@+id/tv_line_two"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/tv_title"
android:layout_toRightOf="@+id/tv_now_playing_time"
android:text=" / "
android:textColor="@color/platform_color_BFBFBF"
android:textSize="10sp" />
<TextView
android:id="@+id/tv_duration"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/tv_title"
android:layout_toRightOf="@+id/tv_line_two"
android:textColor="@color/platform_color_BFBFBF"
android:textSize="10sp"
tools:text="30:28" />
</RelativeLayout>
<ImageView
android:id="@+id/play_state"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_gravity="center"
android:layout_marginLeft="8dp"
android:layout_marginRight="15dp"
android:scaleType="centerCrop"
android:src="@drawable/ico_yyfc_play" />
</LinearLayout>
</FrameLayout>
\ No newline at end of file
......@@ -11,7 +11,7 @@
android:layout_gravity="center_vertical"
android:contentDescription="@null"
android:scaleType="fitCenter"
android:src="@drawable/ic_launcher" />
android:src="@drawable/default_cover" />
<LinearLayout
android:layout_width="0.0dp"
......
......@@ -21,6 +21,12 @@ import okio.BufferedSink
import java.util.*
/**
* Created by haorui on 2019-08-30 .
* Des: 默认Http配置参数类
......@@ -86,7 +92,7 @@ class HttpConfig {
// 添加公共参数
private fun commonParams(): Interceptor {
return Interceptor {
val request = it.request()
var request = it.request()
//如果是POST请求,则再在Body中增加公共参数
if ("POST"==request.method()){
var body = request.body()
......@@ -123,13 +129,50 @@ class HttpConfig {
body = bodyBuild.build()
}
it.proceed(request.newBuilder().post(body!!).build())
}else{
} else if ("GET"==request.method()){
val url = request.url()
val newBuilder = url.newBuilder()
for (i in 0 until url.querySize()) {
//取出url中?后的参数
val key = url.queryParameterName(i)
val value = url.queryParameterValue(i)
newBuilder.
addQueryParameter(key, value)
}
newBuilder.
addQueryParameter(FFROM, PlatformDataManager.getRam().getChannelName())
.addQueryParameter(IS_FROM_APP, "1")
.addQueryParameter(
OS_BUILD,
"""${RxDeviceTool.getBuildBrandModel()},${RxDeviceTool.getSDKVersionName()},${RxAppTool.getAppVersionName(
BaseApp.getApp()
)}"""
)
.addQueryParameter(TS, (System.currentTimeMillis() / 1000).toString())
.addQueryParameter(
VERSION, RxAppTool.getAppVersionName(
BaseApp.getApp()
)
)
val loginBean = ModularServiceManager.getPlatformUserService()?.getUser()
if (loginBean != null) {
newBuilder.addQueryParameter(UID, loginBean.userId)
.addQueryParameter(TOKEN, loginBean.token)
}
it.proceed(request.newBuilder().url(newBuilder.build()).build())
} else {
it.proceed(request)
}
}
}
private data class Param(val name: String, val value: String)
// 添加请求头
......
......@@ -2,9 +2,13 @@
package com.ydl.ydlcommon.data.http
import com.ydl.ydlcommon.base.BaseApp
import com.ydl.ydlcommon.mvp.base.IView
import com.ydl.ydlcommon.mvp.lce.ILceView
import com.ydl.ydlcommon.utils.RxLifecycleUtils
import com.yidianling.common.tools.RxNetTool
import io.reactivex.Observable
import io.reactivex.ObservableTransformer
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import java.net.ConnectException
......@@ -77,4 +81,49 @@ object RxUtils {
}
}
}
//====================Rxjava 线程调度====================
/**
* RxJava 线程协调 / RxLifecycle绑定方法
* @param view LceView 强转使用
*/
fun <T> applySchedulers(view: ILceView): ObservableTransformer<T, T> {
return ObservableTransformer { observable ->
observable.subscribeOn(Schedulers.io())
.doOnSubscribe {
view.showLoading()//显示进度条
}
.subscribeOn(AndroidSchedulers.mainThread())
.observeOn(AndroidSchedulers.mainThread())
.doFinally {
view.hideLoading()//隐藏进度条
}.compose(RxLifecycleUtils.bindToLifecycle(view))
}
}
/**
* RxJava 线程协调 / RxLifecycle绑定方法
*
*/
fun <T> applySchedulers(view: IView): ObservableTransformer<T, T> {
return ObservableTransformer { observable ->
observable.subscribeOn(Schedulers.io())
.subscribeOn(AndroidSchedulers.mainThread())
.observeOn(AndroidSchedulers.mainThread())
.compose(RxLifecycleUtils.bindToLifecycle(view))
}
}
/**
* RxJava 线程协调方法
*/
fun <T> applySchedulers(): ObservableTransformer<T, T> {
return ObservableTransformer { observable ->
observable.subscribeOn(Schedulers.io())
.subscribeOn(AndroidSchedulers.mainThread())
.observeOn(AndroidSchedulers.mainThread())
}
}
}
\ No newline at end of file
......@@ -7,7 +7,6 @@ import com.ydl.ydlcommon.base.BaseMvpActivity
import com.ydl.ydlcommon.mvp.base.IPresenter
import com.ydl.ydlcommon.mvp.base.IView
import com.ydl.ydlcommon.mvp.lce.view.ILceViewState
import com.ydl.ydlnet.client.interfaces.ILoadingView
/**
* Created by haorui on 2019-08-14.
......@@ -17,7 +16,7 @@ import com.ydl.ydlnet.client.interfaces.ILoadingView
* 【注意:StateView需设置id为:R.id.lce_state_view】
* 【注意:ContentView需设置id为:R.id.lce_content_view】
*/
abstract class BaseLceActivity<V : IView, P : IPresenter<V>> : BaseMvpActivity<V, P>(), ILceView ,ILoadingView{
abstract class BaseLceActivity<V : IView, P : IPresenter<V>> : BaseMvpActivity<V, P>(), ILceView{
protected lateinit var lceStateView: ILceViewState
protected var lceContentView: View? = null
......@@ -64,6 +63,10 @@ abstract class BaseLceActivity<V : IView, P : IPresenter<V>> : BaseMvpActivity<V
lceStateView.showLoading()
}
override fun hideLoading() {
lceStateView.hideLoading()
}
override fun showContent() {
lceContentView?.visibility = View.VISIBLE
lceStateView.hideLoading()
......@@ -77,14 +80,6 @@ abstract class BaseLceActivity<V : IView, P : IPresenter<V>> : BaseMvpActivity<V
lceStateView.showError(msg)
}
override fun showLoadingView() {
lceStateView.showLoading()
}
override fun hideLoadingView() {
lceStateView.hideLoading()
}
}
......@@ -68,6 +68,10 @@ abstract class BaseLceDialogFragment<V : IView, P : IPresenter<V>> : BaseMvpDial
lceStateView!!.showLoading()
}
override fun hideLoading() {
lceStateView!!.hideLoading()
}
override fun showContent() {
lceContentView?.visibility = View.VISIBLE
lceStateView!!.hideLoading()
......
......@@ -4,11 +4,11 @@ import android.os.Bundle
import android.support.annotation.CallSuper
import android.support.v4.app.FragmentActivity
import android.view.View
import com.ydl.ydlcommon.R
import com.ydl.ydlcommon.base.BaseMvpFragment
import com.ydl.ydlcommon.mvp.base.IPresenter
import com.ydl.ydlcommon.mvp.base.IView
import com.ydl.ydlcommon.mvp.lce.view.ILceViewState
import com.ydl.ydlcommon.R
import java.util.*
/**
* Created by haorui on 2019-08-14.
......@@ -67,6 +67,10 @@ abstract class BaseLceFragment< V : IView, P : IPresenter<V>> : BaseMvpFragment<
lceStateView!!.showLoading()
}
override fun hideLoading() {
lceStateView!!.hideLoading()
}
override fun showContent() {
lceContentView?.visibility = View.VISIBLE
lceStateView!!.hideLoading()
......
......@@ -2,18 +2,20 @@ package com.ydl.ydlcommon.mvp.lce
import android.support.annotation.UiThread
import com.ydl.ydlcommon.mvp.base.IView
import com.ydl.ydlnet.client.interfaces.ILoadingView
/**
* Created by haorui on 2019-08-14.
* Des: Lce View 接口类,所有使用Lce架构的View必须实现
*/
interface ILceView : IView ,ILoadingView{
interface ILceView : IView{
@UiThread
fun showLoading()
@UiThread
fun hideLoading()
@UiThread
fun showContent()
@UiThread
......
......@@ -3,11 +3,16 @@ package com.ydl.ydlcommon.utils;
import com.ydl.ydlcommon.data.http.BaseCommand;
import com.ydl.ydlcommon.data.http.FormatText;
import java.io.File;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import okhttp3.MediaType;
import okhttp3.RequestBody;
/**
* Created by haorui on 2019-09-19.
......@@ -49,4 +54,80 @@ public class NetworkParamsUtils {
}
//获取网络请求表
public static Map<String, String> getMaps(BaseCommand cmd) {
Map<String, String> map = new HashMap<>();
List<FormatText> list = getPostList(cmd);
int size = list.size();
for (int i = 0; i < size; i++) {
FormatText formatText = list.get(i);
map.put(formatText.getmKey(), String.valueOf(formatText.getmValue()));
}
return map;
}
//获取文件传输网络请求表
@SuppressWarnings("unused")
public static Map<String, RequestBody> getFileMaps(BaseCommand cmd, String key, File[] files) {
Map<String, RequestBody> map = new TreeMap<>();
List<FormatText> list = getPostList(cmd);
int size = list.size();
for (int i = 0; i < size; i++) {
FormatText formatText = list.get(i);
// RequestBody rb = RequestBody.create(MediaType.parse("multipart/form-data"),list.get(i).getmValue());
RequestBody rb = RequestBody.create(MediaType.parse("text/plain"), String.valueOf(list.get(i).getmValue()));
map.put(formatText.getmKey(), rb);
}
if (files != null && files.length > 0) {
if (files.length == 1) {
if (files[0] != null) {
RequestBody fileBody = RequestBody.create(MediaType.parse("multipart/form-data"), files[0]);
map.put(key + "\"; filename=\"" + files[0].getName() + "", fileBody);
}
} else {
for (int i = 0; i < files.length; i++) {
if (files[i] != null) {
RequestBody fileBody = RequestBody.create(MediaType.parse("multipart/form-data"), files[i]);
map.put(key + i + "\"; filename=\"" + files[i].getName() + "", fileBody);
}
}
}
}
return map;
}
//获取网络请求表
private static Map<String, RequestBody> getFileMaps(List<FormatText> list, String key, File[] file) {
Map<String, RequestBody> map = new TreeMap<>();
int size = list.size();
for (int i = 0; i < size; i++) {
FormatText formatText = list.get(i);
// RequestBody rb = RequestBody.create(MediaType.parse("multipart/form-data"),list.get(i).getmValue());
RequestBody rb = RequestBody.create(MediaType.parse("text/plain"), String.valueOf(list.get(i).getmValue()));
map.put(formatText.getmKey(), rb);
}
if (file != null && file.length > 0) {
if (file.length == 1) {
if (file[0] != null) {
RequestBody fileBody = RequestBody.create(MediaType.parse("multipart/form-data"), file[0]);
map.put(key + "\"; filename=\"" + file[0].getName() + "", fileBody);
}
} else {
for (int i = 0; i < file.length; i++) {
if (file[i] != null) {
RequestBody fileBody = RequestBody.create(MediaType.parse("multipart/form-data"), file[i]);
map.put(key + i + "\"; filename=\"" + file[i].getName() + "", fileBody);
}
}
}
}
return map;
}
}
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