Compare commits
15 Commits
branch_new
...
dev-lxj-be
| Author | SHA1 | Date | |
|---|---|---|---|
| 4a59bcd797 | |||
| 8080e476a5 | |||
| ee06345de7 | |||
| ec58f46bf8 | |||
| c592da4d55 | |||
| f5aeeb88d7 | |||
| d0337a723c | |||
| 6b9490cceb | |||
| 877ef5ea05 | |||
| 771138d34c | |||
| 520bc8e1bb | |||
| f5377127ce | |||
| f4f04b59a8 | |||
| a993a7710f | |||
| a5ebc83dea |
20
.gitignore
vendored
@@ -1,15 +1,9 @@
|
|||||||
|
.idea/
|
||||||
*.iml
|
*.iml
|
||||||
.gradle
|
build/
|
||||||
/local.properties
|
|
||||||
/.idea/caches
|
|
||||||
/.idea/libraries
|
|
||||||
/.idea/modules.xml
|
|
||||||
/.idea/workspace.xml
|
|
||||||
/.idea/navEditor.xml
|
|
||||||
/.idea/assetWizardSettings.xml
|
|
||||||
.DS_Store
|
|
||||||
/build
|
|
||||||
/captures
|
|
||||||
.externalNativeBuild
|
|
||||||
.cxx
|
|
||||||
local.properties
|
local.properties
|
||||||
|
.gradle/
|
||||||
|
.externalNativeBuild/
|
||||||
|
.DS_Store
|
||||||
|
*.dm
|
||||||
|
*.log
|
||||||
3
.idea/.gitignore
generated
vendored
@@ -1,3 +0,0 @@
|
|||||||
# Default ignored files
|
|
||||||
/shelf/
|
|
||||||
/workspace.xml
|
|
||||||
1
.idea/.name
generated
@@ -1 +0,0 @@
|
|||||||
秘地
|
|
||||||
6
.idea/AndroidProjectSystem.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="AndroidProjectSystem">
|
||||||
|
<option name="providerId" value="com.android.tools.idea.GradleProjectSystem" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
10
.idea/deploymentTargetSelector.xml
generated
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="deploymentTargetSelector">
|
||||||
|
<selectionStates>
|
||||||
|
<SelectionState runConfigName="app">
|
||||||
|
<option name="selectionMode" value="DROPDOWN" />
|
||||||
|
</SelectionState>
|
||||||
|
</selectionStates>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
17
.idea/runConfigurations.xml
generated
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="RunConfigurationProducerService">
|
||||||
|
<option name="ignoredProducers">
|
||||||
|
<set>
|
||||||
|
<option value="com.intellij.execution.junit.AbstractAllInDirectoryConfigurationProducer" />
|
||||||
|
<option value="com.intellij.execution.junit.AllInPackageConfigurationProducer" />
|
||||||
|
<option value="com.intellij.execution.junit.PatternConfigurationProducer" />
|
||||||
|
<option value="com.intellij.execution.junit.TestInClassConfigurationProducer" />
|
||||||
|
<option value="com.intellij.execution.junit.UniqueIdConfigurationProducer" />
|
||||||
|
<option value="com.intellij.execution.junit.testDiscovery.JUnitTestDiscoveryConfigurationProducer" />
|
||||||
|
<option value="org.jetbrains.kotlin.idea.junit.KotlinJUnitRunConfigurationProducer" />
|
||||||
|
<option value="org.jetbrains.kotlin.idea.junit.KotlinPatternConfigurationProducer" />
|
||||||
|
</set>
|
||||||
|
</option>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
6
.idea/vcs.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
<component name="ProjectRunConfigurationManager">
|
|
||||||
<configuration default="false" name="app" type="AndroidRunConfigurationType" factoryName="Android App" activateToolWindowBeforeRun="false">
|
|
||||||
<module name="羽声.app" />
|
|
||||||
<option name="ANDROID_RUN_CONFIGURATION_SCHEMA_VERSION" value="1" />
|
|
||||||
<option name="DEPLOY" value="true" />
|
|
||||||
<option name="DEPLOY_APK_FROM_BUNDLE" value="true" />
|
|
||||||
<option name="DEPLOY_AS_INSTANT" value="false" />
|
|
||||||
<option name="ARTIFACT_NAME" value="" />
|
|
||||||
<option name="PM_INSTALL_OPTIONS" value="" />
|
|
||||||
<option name="ALL_USERS" value="false" />
|
|
||||||
<option name="ALWAYS_INSTALL_WITH_PM" value="false" />
|
|
||||||
<option name="ALLOW_ASSUME_VERIFIED" value="false" />
|
|
||||||
<option name="CLEAR_APP_STORAGE" value="false" />
|
|
||||||
<option name="DYNAMIC_FEATURES_DISABLED_LIST" value="" />
|
|
||||||
<option name="ACTIVITY_EXTRA_FLAGS" value="" />
|
|
||||||
<option name="MODE" value="default_activity" />
|
|
||||||
<option name="RESTORE_ENABLED" value="false" />
|
|
||||||
<option name="RESTORE_FILE" value="" />
|
|
||||||
<option name="RESTORE_FRESH_INSTALL_ONLY" value="true" />
|
|
||||||
<option name="CLEAR_LOGCAT" value="true" />
|
|
||||||
<option name="SHOW_LOGCAT_AUTOMATICALLY" value="true" />
|
|
||||||
<option name="TARGET_SELECTION_MODE" value="DEVICE_AND_SNAPSHOT_COMBO_BOX" />
|
|
||||||
<option name="DEBUGGER_TYPE" value="Java" />
|
|
||||||
<Java>
|
|
||||||
<option name="ATTACH_ON_WAIT_FOR_DEBUGGER" value="false" />
|
|
||||||
<option name="DEBUG_SANDBOX_SDK" value="false" />
|
|
||||||
</Java>
|
|
||||||
<Profilers>
|
|
||||||
<option name="ADVANCED_PROFILING_ENABLED" value="false" />
|
|
||||||
<option name="STARTUP_PROFILING_ENABLED" value="false" />
|
|
||||||
<option name="STARTUP_CPU_PROFILING_ENABLED" value="false" />
|
|
||||||
<option name="STARTUP_CPU_PROFILING_CONFIGURATION_NAME" value="Java/Kotlin Method Sample (legacy)" />
|
|
||||||
<option name="STARTUP_NATIVE_MEMORY_PROFILING_ENABLED" value="false" />
|
|
||||||
<option name="NATIVE_MEMORY_SAMPLE_RATE_BYTES" value="2048" />
|
|
||||||
</Profilers>
|
|
||||||
<option name="DEEP_LINK" value="" />
|
|
||||||
<option name="ACTIVITY" value="" />
|
|
||||||
<option name="ACTIVITY_CLASS" value="" />
|
|
||||||
<option name="SEARCH_ACTIVITY_IN_GLOBAL_SCOPE" value="false" />
|
|
||||||
<option name="SKIP_ACTIVITY_VALIDATION" value="false" />
|
|
||||||
<method v="2">
|
|
||||||
<option name="Android.Gradle.BeforeRunTask" enabled="true" />
|
|
||||||
</method>
|
|
||||||
</configuration>
|
|
||||||
</component>
|
|
||||||
@@ -17,7 +17,7 @@ android {
|
|||||||
}
|
}
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId "com.qxcm.qxlive"
|
applicationId "com.qxcm.qxlive"
|
||||||
minSdk 24
|
minSdk 26
|
||||||
targetSdk 33
|
targetSdk 33
|
||||||
versionCode Integer.parseInt(project.findProperty("APP_VERSION_CODE"))
|
versionCode Integer.parseInt(project.findProperty("APP_VERSION_CODE"))
|
||||||
versionName project.findProperty("APP_VERSION_NAME")
|
versionName project.findProperty("APP_VERSION_NAME")
|
||||||
@@ -66,19 +66,19 @@ android {
|
|||||||
|
|
||||||
// // 测试版配置
|
// // 测试版配置
|
||||||
beta {
|
beta {
|
||||||
// dimension "environment"
|
dimension "environment"
|
||||||
// // 测试版包名:基础包名 + .beta(com.example.myapp.beta)
|
// 测试版包名:基础包名 + .beta(com.example.myapp.beta)
|
||||||
// applicationIdSuffix ".beta"
|
applicationIdSuffix ".beta"
|
||||||
// // 测试版版本名:1.0-beta
|
// 测试版版本名:1.0-beta
|
||||||
// versionNameSuffix "-beta"
|
versionNameSuffix "-beta"
|
||||||
//
|
|
||||||
// // 【测试版应用名称】动态生成带标识的名称
|
// 【测试版应用名称】动态生成带标识的名称
|
||||||
// resValue "string", "app_name", "羽声-测试版"
|
resValue "string", "app_name", "羽声-测试版"
|
||||||
//
|
|
||||||
// // 【测试版图标】替换为测试专用图标
|
// 【测试版图标】替换为测试专用图标
|
||||||
// manifestPlaceholders = [
|
manifestPlaceholders = [
|
||||||
// appIcon: "@mipmap/ic_launcher_app_bat" // 需在main/res/mipmap放置该图标
|
appIcon: "@mipmap/ic_launcher_app_bat" // 需在main/res/mipmap放置该图标
|
||||||
// ]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,37 +0,0 @@
|
|||||||
{
|
|
||||||
"version": 3,
|
|
||||||
"artifactType": {
|
|
||||||
"type": "APK",
|
|
||||||
"kind": "Directory"
|
|
||||||
},
|
|
||||||
"applicationId": "com.qxcm.qxlive",
|
|
||||||
"variantName": "releasRelease",
|
|
||||||
"elements": [
|
|
||||||
{
|
|
||||||
"type": "SINGLE",
|
|
||||||
"filters": [],
|
|
||||||
"attributes": [],
|
|
||||||
"versionCode": 43,
|
|
||||||
"versionName": "1.0.5.3",
|
|
||||||
"outputFile": "羽声_1.0.5.3_43.apk"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"elementType": "File",
|
|
||||||
"baselineProfiles": [
|
|
||||||
{
|
|
||||||
"minApi": 28,
|
|
||||||
"maxApi": 30,
|
|
||||||
"baselineProfiles": [
|
|
||||||
"baselineProfiles/1/羽声_1.0.5.3_43.dm"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"minApi": 31,
|
|
||||||
"maxApi": 2147483647,
|
|
||||||
"baselineProfiles": [
|
|
||||||
"baselineProfiles/0/羽声_1.0.5.3_43.dm"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"minSdkVersionForDexing": 24
|
|
||||||
}
|
|
||||||
@@ -406,7 +406,7 @@ public class PasswordLoginActivity extends BaseMvpActivity<LoginPresenter, Activ
|
|||||||
.setPrivacyTextSize(11)
|
.setPrivacyTextSize(11)
|
||||||
.setPrivacyAlertContentVerticalMargin(20)
|
.setPrivacyAlertContentVerticalMargin(20)
|
||||||
.setPrivacyMargin(39)
|
.setPrivacyMargin(39)
|
||||||
.setPrivacyState(true)
|
.setPrivacyState(false)
|
||||||
.setCheckboxHidden(false)
|
.setCheckboxHidden(false)
|
||||||
.setCheckedImgPath("ic_agreement_selected")
|
.setCheckedImgPath("ic_agreement_selected")
|
||||||
.setUncheckedImgPath("ic_agreement_unselect")
|
.setUncheckedImgPath("ic_agreement_unselect")
|
||||||
@@ -485,20 +485,20 @@ public class PasswordLoginActivity extends BaseMvpActivity<LoginPresenter, Activ
|
|||||||
}
|
}
|
||||||
String phone = mBinding.edPhone.getText().toString().trim();
|
String phone = mBinding.edPhone.getText().toString().trim();
|
||||||
if (TextUtils.isEmpty(phone)) {
|
if (TextUtils.isEmpty(phone)) {
|
||||||
com.blankj.utilcode.util.ToastUtils.showShort("请输入手机号");
|
ToastUtils.show("请输入手机号");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (type==1) {
|
if (type==1) {
|
||||||
String code = mBinding.edPassword.getText().toString().trim();
|
String code = mBinding.edPassword.getText().toString().trim();
|
||||||
if (TextUtils.isEmpty(code)) {
|
if (TextUtils.isEmpty(code)) {
|
||||||
com.blankj.utilcode.util.ToastUtils.showShort("请输入验证码");
|
ToastUtils.show("请输入验证码");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
MvpPre.login(phone, "", code, 1);
|
MvpPre.login(phone, "", code, 1);
|
||||||
}else if (type==2) {
|
}else if (type==2) {
|
||||||
String password = mBinding.edPasswordCode.getText().toString().trim();
|
String password = mBinding.edPasswordCode.getText().toString().trim();
|
||||||
if (TextUtils.isEmpty(password)) {
|
if (TextUtils.isEmpty(password)) {
|
||||||
com.blankj.utilcode.util.ToastUtils.showShort("请输入密码");
|
ToastUtils.show("请输入密码");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
MvpPre.login(phone, password, "", 2);
|
MvpPre.login(phone, password, "", 2);
|
||||||
@@ -525,10 +525,10 @@ public class PasswordLoginActivity extends BaseMvpActivity<LoginPresenter, Activ
|
|||||||
} else if (id == R.id.tv_send_code) {
|
} else if (id == R.id.tv_send_code) {
|
||||||
String phone = mBinding.edPhone.getText().toString().trim();
|
String phone = mBinding.edPhone.getText().toString().trim();
|
||||||
if (TextUtils.isEmpty(phone)) {
|
if (TextUtils.isEmpty(phone)) {
|
||||||
com.blankj.utilcode.util.ToastUtils.showShort("请输入手机号");
|
ToastUtils.show("请输入手机号");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
sendCodeSuccess(phone);
|
|
||||||
MvpPre.sendCode(phone, 1);
|
MvpPre.sendCode(phone, 1);
|
||||||
}else if (id == R.id.iv_eye) {
|
}else if (id == R.id.iv_eye) {
|
||||||
|
|
||||||
@@ -575,7 +575,7 @@ public class PasswordLoginActivity extends BaseMvpActivity<LoginPresenter, Activ
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendCodeSuccess(String phoneNumber) {
|
public void sendCodeSuccess() {
|
||||||
com.blankj.utilcode.util.ToastUtils.showShort("短信验证码发送成功请注意查收");
|
com.blankj.utilcode.util.ToastUtils.showShort("短信验证码发送成功请注意查收");
|
||||||
mBinding.tvSendCode.setEnabled(false);
|
mBinding.tvSendCode.setEnabled(false);
|
||||||
mBinding.tvSendCode.setAlpha(0.5f);
|
mBinding.tvSendCode.setAlpha(0.5f);
|
||||||
@@ -604,6 +604,7 @@ public class PasswordLoginActivity extends BaseMvpActivity<LoginPresenter, Activ
|
|||||||
@Override
|
@Override
|
||||||
public void sendCodeSuccess1(String s) {
|
public void sendCodeSuccess1(String s) {
|
||||||
LogUtils.e(s);
|
LogUtils.e(s);
|
||||||
|
sendCodeSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -46,7 +46,8 @@ public class WXPayEntryActivity extends Activity implements IWXAPIEventHandler {
|
|||||||
switch (resp.errCode) {
|
switch (resp.errCode) {
|
||||||
case BaseResp.ErrCode.ERR_OK:
|
case BaseResp.ErrCode.ERR_OK:
|
||||||
// 支付成功:这里需要调用后台接口确认支付状态(避免本地判断不可靠)
|
// 支付成功:这里需要调用后台接口确认支付状态(避免本地判断不可靠)
|
||||||
|
PayEvent messageEvent = new PayEvent(1, "支付成功");
|
||||||
|
EventBus.getDefault().post(messageEvent);
|
||||||
break;
|
break;
|
||||||
case BaseResp.ErrCode.ERR_USER_CANCEL:
|
case BaseResp.ErrCode.ERR_USER_CANCEL:
|
||||||
checkPayResultFromServer();
|
checkPayResultFromServer();
|
||||||
|
|||||||
@@ -28,8 +28,8 @@ isBuildModule=false
|
|||||||
#org.gradle.deamon=false
|
#org.gradle.deamon=false
|
||||||
android.injected.testOnly=false
|
android.injected.testOnly=false
|
||||||
|
|
||||||
APP_VERSION_NAME=1.0.5.3
|
APP_VERSION_NAME=1.0.6.1
|
||||||
APP_VERSION_CODE=43
|
APP_VERSION_CODE=51
|
||||||
|
|
||||||
org.gradle.jvm.toolchain.useLegacyAdapters=false
|
org.gradle.jvm.toolchain.useLegacyAdapters=false
|
||||||
#org.gradle.java.home=C\:\\Users\\qx\\.jdks\\ms-17.0.15
|
#org.gradle.java.home=C\:\\Users\\qx\\.jdks\\ms-17.0.15
|
||||||
|
|||||||
@@ -3,15 +3,9 @@ agp = "8.4.0"
|
|||||||
alipayAlipaysdkAndroid = "15.8.33"
|
alipayAlipaysdkAndroid = "15.8.33"
|
||||||
arouterApiVersion = "1.5.2"
|
arouterApiVersion = "1.5.2"
|
||||||
comJacktuotuoCustomviewVerificationcodeview2 = "1.0.5"
|
comJacktuotuoCustomviewVerificationcodeview2 = "1.0.5"
|
||||||
comLiulishuoOkdownloadOkdownload4 = "1.0.7"
|
|
||||||
comLiulishuoOkdownloadSqlite3 = "1.0.7"
|
|
||||||
comLiulishuoOkdownloadOkhttp3 = "1.0.7"
|
|
||||||
comLiulishuoOkdownloadFiledownloader3 = "1.0.7"
|
|
||||||
custompopwindow = "2.1.1"
|
|
||||||
databindingRuntimeVersion = "7.0.2"
|
databindingRuntimeVersion = "7.0.2"
|
||||||
easypermissions = "3.0.0"
|
easypermissions = "3.0.0"
|
||||||
easyProtectorRelease = "1.1.2"
|
easyProtectorRelease = "1.1.2"
|
||||||
egameAnimplayer = "2.0.8"
|
|
||||||
flexboxVersion = "1.0.0"
|
flexboxVersion = "1.0.0"
|
||||||
githubBannerviewpagerVersion = "3.5.12"
|
githubBannerviewpagerVersion = "3.5.12"
|
||||||
githubGlide = "4.12.0"
|
githubGlide = "4.12.0"
|
||||||
@@ -20,28 +14,23 @@ githubPhotoview = "2.3.0"
|
|||||||
githubRealtimeblurviewVersion = "1.2.1"
|
githubRealtimeblurviewVersion = "1.2.1"
|
||||||
githubShadowlayout = "3.3.1"
|
githubShadowlayout = "3.3.1"
|
||||||
gradle = "8.8.0"
|
gradle = "8.8.0"
|
||||||
#gradle = "8.5.0-alpha04"
|
|
||||||
greendaoGradlePlugin = "3.3.0"
|
greendaoGradlePlugin = "3.3.0"
|
||||||
junit = "4.13.2"
|
junit = "4.13.2"
|
||||||
junitVersion = "1.1.5"
|
junitVersion = "1.1.5"
|
||||||
espressoCore = "3.5.1"
|
espressoCore = "3.5.1"
|
||||||
appcompat = "1.6.1"
|
appcompat = "1.6.1"
|
||||||
libraryVersion = "1.4"
|
|
||||||
lombok = "1.18.32"
|
lombok = "1.18.32"
|
||||||
marqueeview = "1.1.0"
|
marqueeview = "1.1.0"
|
||||||
material = "1.10.0"
|
material = "1.10.0"
|
||||||
activity = "1.8.0"
|
activity = "1.8.0"
|
||||||
constraintlayout = "2.1.4"
|
constraintlayout = "2.1.4"
|
||||||
arouter = "1.0.2"
|
|
||||||
|
|
||||||
arouterAnnotation = "1.0.6"
|
arouterAnnotation = "1.0.6"
|
||||||
arouterCompiler = "1.5.2"
|
arouterCompiler = "1.5.2"
|
||||||
arouterApi = "1.5.2"
|
|
||||||
comSquareupRetrofit2Retrofit3 = "2.9.0"
|
comSquareupRetrofit2Retrofit3 = "2.9.0"
|
||||||
fastjson = "1.2.60"
|
fastjson = "1.2.60"
|
||||||
githubBaserecyclerviewadapterhelper = "2.9.30"
|
githubBaserecyclerviewadapterhelper = "2.9.30"
|
||||||
gsonVersion = "2.10.1"
|
gsonVersion = "2.10.1"
|
||||||
eventbusAnnotationProcessorVersion = "3.3.1"
|
|
||||||
eventbusVersion = "3.3.1"
|
eventbusVersion = "3.3.1"
|
||||||
logger = "2.2.0"
|
logger = "2.2.0"
|
||||||
loggingInterceptorVersion = "3.10.0"
|
loggingInterceptorVersion = "3.10.0"
|
||||||
@@ -49,36 +38,29 @@ multidex = "2.0.1"
|
|||||||
ossAndroidSdkVersion = "2.9.21"
|
ossAndroidSdkVersion = "2.9.21"
|
||||||
permissionx = "1.7.1"
|
permissionx = "1.7.1"
|
||||||
persistentcookiejar = "v1.0.1"
|
persistentcookiejar = "v1.0.1"
|
||||||
picture_libraryVersion = "v2.6.0"
|
|
||||||
reactivexRxjava = "2.2.21"
|
reactivexRxjava = "2.2.21"
|
||||||
retrofit2KotlinCoroutinesAdapterVersion = "0.9.2"
|
retrofit2KotlinCoroutinesAdapterVersion = "0.9.2"
|
||||||
roundedimageview = "2.3.0"
|
roundedimageview = "2.3.0"
|
||||||
rxandroid = "2.1.1"
|
rxandroid = "2.1.1"
|
||||||
scwangSmartrefreshlayout = "1.1.0-alpha-20"
|
scwangSmartrefreshlayout = "1.1.0-alpha-20"
|
||||||
scwangSmartrefreshheader = "1.1.0-alpha-20"
|
scwangSmartrefreshheader = "1.1.0-alpha-20"
|
||||||
singledateandtimepicker = "2.2.7"
|
|
||||||
svgaplayerAndroid = "2.5.13"
|
svgaplayerAndroid = "2.5.13"
|
||||||
toastVersion = "8.2"
|
toastVersion = "8.2"
|
||||||
togglebuttonLibraryVersion = "1.0.0"
|
togglebuttonLibraryVersion = "1.0.0"
|
||||||
utilcode = "1.30.6"
|
utilcode = "1.30.6"
|
||||||
databindingRuntime = "8.8.0"
|
|
||||||
datastoreCoreAndroid = "1.1.5"
|
|
||||||
kotlin = "2.0.0"
|
|
||||||
lifecycleRuntimeKtx = "2.6.1"
|
|
||||||
activityCompose = "1.8.0"
|
|
||||||
composeBom = "2024.04.01"
|
|
||||||
kotlinVersion = "1.9.24"
|
kotlinVersion = "1.9.24"
|
||||||
coreKtx = "1.10.1"
|
coreKtx = "1.10.1"
|
||||||
lifecycleLivedataKtx = "2.6.1"
|
lifecycleLivedataKtx = "2.6.1"
|
||||||
lifecycleViewmodelKtx = "2.6.1"
|
lifecycleViewmodelKtx = "2.6.1"
|
||||||
webpdecoder = "1.6.4.9.0"
|
|
||||||
wechatSdkAndroid = "6.8.30"
|
wechatSdkAndroid = "6.8.30"
|
||||||
xbanner = "1.7.0"
|
xbanner = "1.7.0"
|
||||||
appcompatVersion = "1.3.1"
|
|
||||||
legacySupportV4 = "1.0.0"
|
legacySupportV4 = "1.0.0"
|
||||||
fragmentKtx = "1.5.6"
|
fragmentKtx = "1.5.6"
|
||||||
cosAndroidLite = "5.9.46"
|
|
||||||
interpolator = "1.0.0"
|
interpolator = "1.0.0"
|
||||||
|
material3Android = "1.4.0"
|
||||||
|
uiToolingPreviewAndroid = "1.9.4"
|
||||||
|
tilesToolingPreview = "1.5.0"
|
||||||
|
constraintlayoutVersion = "2.2.1"
|
||||||
|
|
||||||
[libraries]
|
[libraries]
|
||||||
alipay-alipaysdk-android = { module = "com.alipay.sdk:alipaysdk-android", version.ref = "alipayAlipaysdkAndroid" }
|
alipay-alipaysdk-android = { module = "com.alipay.sdk:alipaysdk-android", version.ref = "alipayAlipaysdkAndroid" }
|
||||||
@@ -89,11 +71,6 @@ com-github-bumptech-glide-glide = { module = "com.github.bumptech.glide:glide",
|
|||||||
com-github-mmin18-realtimeblurview = { module = "com.github.mmin18:realtimeblurview", version.ref = "githubRealtimeblurviewVersion" }
|
com-github-mmin18-realtimeblurview = { module = "com.github.mmin18:realtimeblurview", version.ref = "githubRealtimeblurviewVersion" }
|
||||||
com-github-zhpanvip-bannerviewpager = { module = "com.github.zhpanvip:bannerviewpager", version.ref = "githubBannerviewpagerVersion" }
|
com-github-zhpanvip-bannerviewpager = { module = "com.github.zhpanvip:bannerviewpager", version.ref = "githubBannerviewpagerVersion" }
|
||||||
com-jacktuotuo-customview-verificationcodeview3 = { module = "com.jacktuotuo.customview:verificationcodeview", version.ref = "comJacktuotuoCustomviewVerificationcodeview2" }
|
com-jacktuotuo-customview-verificationcodeview3 = { module = "com.jacktuotuo.customview:verificationcodeview", version.ref = "comJacktuotuoCustomviewVerificationcodeview2" }
|
||||||
#com-liulishuo-okdownload-filedownloader4 = { module = "com.liulishuo.okdownload:filedownloader", version.ref = "comLiulishuoOkdownloadFiledownloader3" }
|
|
||||||
#com-liulishuo-okdownload-okhttp4 = { module = "com.liulishuo.okdownload:okhttp", version.ref = "comLiulishuoOkdownloadOkhttp3" }
|
|
||||||
#com-liulishuo-okdownload-sqlite4 = { module = "com.liulishuo.okdownload:sqlite", version.ref = "comLiulishuoOkdownloadSqlite3" }
|
|
||||||
#com-liulishuo-okdownload-okdownload6 = { module = "com.liulishuo.okdownload:okdownload", version.ref = "comLiulishuoOkdownloadOkdownload4" }
|
|
||||||
#custompopwindow = { module = "com.github.pinguo-zhouwei:CustomPopwindow", version.ref = "custompopwindow" }
|
|
||||||
databinding-runtime-v702 = { module = "androidx.databinding:databinding-runtime", version.ref = "databindingRuntimeVersion" }
|
databinding-runtime-v702 = { module = "androidx.databinding:databinding-runtime", version.ref = "databindingRuntimeVersion" }
|
||||||
dpa-oss-android-sdk = { module = "com.aliyun.dpa:oss-android-sdk", version.ref = "ossAndroidSdkVersion" }
|
dpa-oss-android-sdk = { module = "com.aliyun.dpa:oss-android-sdk", version.ref = "ossAndroidSdkVersion" }
|
||||||
easy-protector-release = { module = "com.lahm.library:easy-protector-release", version.ref = "easyProtectorRelease" }
|
easy-protector-release = { module = "com.lahm.library:easy-protector-release", version.ref = "easyProtectorRelease" }
|
||||||
@@ -101,7 +78,6 @@ easypermissions = { module = "pub.devrel:easypermissions", version.ref = "easype
|
|||||||
#egame-animplayer = { module = "com.egame.vap:animplayer", version.ref = "egameAnimplayer" }
|
#egame-animplayer = { module = "com.egame.vap:animplayer", version.ref = "egameAnimplayer" }
|
||||||
github-photoview = { module = "com.github.chrisbanes:PhotoView", version.ref = "githubPhotoview" }
|
github-photoview = { module = "com.github.chrisbanes:PhotoView", version.ref = "githubPhotoview" }
|
||||||
github-shadowlayout = { module = "com.github.lihangleo2:ShadowLayout", version.ref = "githubShadowlayout" }
|
github-shadowlayout = { module = "com.github.lihangleo2:ShadowLayout", version.ref = "githubShadowlayout" }
|
||||||
#glide-compiler = { module = "com.github.bumptech.glide:compiler", version.ref = "githubGlide" }
|
|
||||||
gradle = { module = "com.android.tools.build:gradle", version.ref = "gradle" }
|
gradle = { module = "com.android.tools.build:gradle", version.ref = "gradle" }
|
||||||
greendao-gradle-plugin = { module = "org.greenrobot:greendao-gradle-plugin", version.ref = "greendaoGradlePlugin" }
|
greendao-gradle-plugin = { module = "org.greenrobot:greendao-gradle-plugin", version.ref = "greendaoGradlePlugin" }
|
||||||
junit = { group = "junit", name = "junit", version.ref = "junit" }
|
junit = { group = "junit", name = "junit", version.ref = "junit" }
|
||||||
@@ -124,46 +100,32 @@ github-baserecyclerviewadapterhelper = { module = "com.github.CymChad:BaseRecycl
|
|||||||
hjq-toast = { module = "com.hjq:toast", version.ref = "toastVersion" }
|
hjq-toast = { module = "com.hjq:toast", version.ref = "toastVersion" }
|
||||||
jakewharton-retrofit2-kotlin-coroutines-adapter = { module = "com.jakewharton.retrofit:retrofit2-kotlin-coroutines-adapter", version.ref = "retrofit2KotlinCoroutinesAdapterVersion" }
|
jakewharton-retrofit2-kotlin-coroutines-adapter = { module = "com.jakewharton.retrofit:retrofit2-kotlin-coroutines-adapter", version.ref = "retrofit2KotlinCoroutinesAdapterVersion" }
|
||||||
greenrobot-eventbus = { module = "org.greenrobot:eventbus", version.ref = "eventbusVersion" }
|
greenrobot-eventbus = { module = "org.greenrobot:eventbus", version.ref = "eventbusVersion" }
|
||||||
#greenrobot-eventbus-annotation-processor = { module = "org.greenrobot:eventbus-annotation-processor", version.ref = "eventbusAnnotationProcessorVersion" }
|
|
||||||
google-gson = { module = "com.google.code.gson:gson", version.ref = "gsonVersion" }
|
google-gson = { module = "com.google.code.gson:gson", version.ref = "gsonVersion" }
|
||||||
logger = { module = "com.orhanobut:logger", version.ref = "logger" }
|
logger = { module = "com.orhanobut:logger", version.ref = "logger" }
|
||||||
multidex = { module = "androidx.multidex:multidex", version.ref = "multidex" }
|
multidex = { module = "androidx.multidex:multidex", version.ref = "multidex" }
|
||||||
#numberprogressbar-library = { module = "com.daimajia.numberprogressbar:library", version.ref = "libraryVersion" }
|
|
||||||
okhttp3-logging-interceptor = { module = "com.squareup.okhttp3:logging-interceptor", version.ref = "loggingInterceptorVersion" }
|
okhttp3-logging-interceptor = { module = "com.squareup.okhttp3:logging-interceptor", version.ref = "loggingInterceptorVersion" }
|
||||||
permissionx = { module = "com.guolindev.permissionx:permissionx", version.ref = "permissionx" }
|
permissionx = { module = "com.guolindev.permissionx:permissionx", version.ref = "permissionx" }
|
||||||
persistentcookiejar = { module = "com.github.franmontiel:PersistentCookieJar", version.ref = "persistentcookiejar" }
|
persistentcookiejar = { module = "com.github.franmontiel:PersistentCookieJar", version.ref = "persistentcookiejar" }
|
||||||
#pictureselector-picture_library = { module = "com.github.LuckSiege.PictureSelector:picture_library", version.ref = "picture_libraryVersion" }
|
|
||||||
reactivex-rxjava = { module = "io.reactivex.rxjava2:rxjava", version.ref = "reactivexRxjava" }
|
reactivex-rxjava = { module = "io.reactivex.rxjava2:rxjava", version.ref = "reactivexRxjava" }
|
||||||
roundedimageview = { module = "com.makeramen:roundedimageview", version.ref = "roundedimageview" }
|
roundedimageview = { module = "com.makeramen:roundedimageview", version.ref = "roundedimageview" }
|
||||||
rxandroid = { module = "io.reactivex.rxjava2:rxandroid", version.ref = "rxandroid" }
|
rxandroid = { module = "io.reactivex.rxjava2:rxandroid", version.ref = "rxandroid" }
|
||||||
#singledateandtimepicker = { module = "com.github.florent37:singledateandtimepicker", version.ref = "singledateandtimepicker" }
|
|
||||||
squareup-converter-gson = { module = "com.squareup.retrofit2:converter-gson", version.ref = "comSquareupRetrofit2Retrofit3" }
|
squareup-converter-gson = { module = "com.squareup.retrofit2:converter-gson", version.ref = "comSquareupRetrofit2Retrofit3" }
|
||||||
retrofit2-adapter-rxjava2 = { module = "com.squareup.retrofit2:adapter-rxjava2", version.ref = "comSquareupRetrofit2Retrofit3" }
|
retrofit2-adapter-rxjava2 = { module = "com.squareup.retrofit2:adapter-rxjava2", version.ref = "comSquareupRetrofit2Retrofit3" }
|
||||||
svgaplayer-android = { module = "com.github.yyued:SVGAPlayer-Android", version.ref = "svgaplayerAndroid" }
|
svgaplayer-android = { module = "com.github.yyued:SVGAPlayer-Android", version.ref = "svgaplayerAndroid" }
|
||||||
utilcode = { module = "com.blankj:utilcode", version.ref = "utilcode" }
|
utilcode = { module = "com.blankj:utilcode", version.ref = "utilcode" }
|
||||||
#databinding-runtime = { group = "androidx.databinding", name = "databinding-runtime", version.ref = "databindingRuntime" }
|
|
||||||
#datastore-core-android = { group = "androidx.datastore", name = "datastore-core-android", version.ref = "datastoreCoreAndroid" }
|
|
||||||
#lifecycle-runtime-ktx = { group = "androidx.lifecycle", name = "lifecycle-runtime-ktx", version.ref = "lifecycleRuntimeKtx" }
|
|
||||||
#activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "activityCompose" }
|
|
||||||
#compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "composeBom" }
|
|
||||||
#ui = { group = "androidx.compose.ui", name = "ui" }
|
|
||||||
#ui-graphics = { group = "androidx.compose.ui", name = "ui-graphics" }
|
|
||||||
#ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling" }
|
|
||||||
#ui-tooling-preview = { group = "androidx.compose.ui", name = "ui-tooling-preview" }
|
|
||||||
#ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest" }
|
|
||||||
#ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" }
|
|
||||||
#material3 = { group = "androidx.compose.material3", name = "material3" }
|
|
||||||
core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
|
core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
|
||||||
lifecycle-livedata-ktx = { group = "androidx.lifecycle", name = "lifecycle-livedata-ktx", version.ref = "lifecycleLivedataKtx" }
|
lifecycle-livedata-ktx = { group = "androidx.lifecycle", name = "lifecycle-livedata-ktx", version.ref = "lifecycleLivedataKtx" }
|
||||||
lifecycle-viewmodel-ktx = { group = "androidx.lifecycle", name = "lifecycle-viewmodel-ktx", version.ref = "lifecycleViewmodelKtx" }
|
lifecycle-viewmodel-ktx = { group = "androidx.lifecycle", name = "lifecycle-viewmodel-ktx", version.ref = "lifecycleViewmodelKtx" }
|
||||||
#webpdecoder = { module = "com.zlc.glide:webpdecoder", version.ref = "webpdecoder" }
|
|
||||||
wechat-sdk-android = { module = "com.tencent.mm.opensdk:wechat-sdk-android", version.ref = "wechatSdkAndroid" }
|
wechat-sdk-android = { module = "com.tencent.mm.opensdk:wechat-sdk-android", version.ref = "wechatSdkAndroid" }
|
||||||
xbanner = { module = "com.github.xiaohaibin:XBanner", version.ref = "xbanner" }
|
xbanner = { module = "com.github.xiaohaibin:XBanner", version.ref = "xbanner" }
|
||||||
zcw-togglebutton-library = { module = "com.zcw:togglebutton-library", version.ref = "togglebuttonLibraryVersion" }
|
zcw-togglebutton-library = { module = "com.zcw:togglebutton-library", version.ref = "togglebuttonLibraryVersion" }
|
||||||
androidx-appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompatVersion" }
|
|
||||||
androidx-legacy-support-v4 = { group = "androidx.legacy", name = "legacy-support-v4", version.ref = "legacySupportV4" }
|
androidx-legacy-support-v4 = { group = "androidx.legacy", name = "legacy-support-v4", version.ref = "legacySupportV4" }
|
||||||
androidx-fragment-ktx = { group = "androidx.fragment", name = "fragment-ktx", version.ref = "fragmentKtx" }
|
androidx-fragment-ktx = { group = "androidx.fragment", name = "fragment-ktx", version.ref = "fragmentKtx" }
|
||||||
androidx-interpolator = { group = "androidx.interpolator", name = "interpolator", version.ref = "interpolator" }
|
androidx-interpolator = { group = "androidx.interpolator", name = "interpolator", version.ref = "interpolator" }
|
||||||
|
androidx-material3-android = { group = "androidx.compose.material3", name = "material3-android", version.ref = "material3Android" }
|
||||||
|
androidx-ui-tooling-preview-android = { group = "androidx.compose.ui", name = "ui-tooling-preview-android", version.ref = "uiToolingPreviewAndroid" }
|
||||||
|
androidx-tiles-tooling-preview = { group = "androidx.wear.tiles", name = "tiles-tooling-preview", version.ref = "tilesToolingPreview" }
|
||||||
|
androidx-constraintlayout = { group = "androidx.constraintlayout", name = "constraintlayout", version.ref = "constraintlayoutVersion" }
|
||||||
|
|
||||||
|
|
||||||
[plugins]
|
[plugins]
|
||||||
|
|||||||
1
locktableview/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
/build
|
||||||
31
locktableview/build.gradle
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
apply plugin: 'com.android.library'
|
||||||
|
group='com.github.RmondJone'
|
||||||
|
android {
|
||||||
|
namespace 'com.rmondjone.locktableview'
|
||||||
|
compileSdk 35
|
||||||
|
|
||||||
|
defaultConfig {
|
||||||
|
minSdk 24
|
||||||
|
targetSdk 35
|
||||||
|
versionCode 12
|
||||||
|
versionName "1.1.2"
|
||||||
|
|
||||||
|
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||||
|
|
||||||
|
}
|
||||||
|
buildTypes {
|
||||||
|
release {
|
||||||
|
minifyEnabled false
|
||||||
|
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||||
|
// 1. 核心:AppCompat 依赖(必须添加,主题基础)
|
||||||
|
implementation 'androidx.appcompat:appcompat:1.6.1'
|
||||||
|
implementation 'com.android.support:design:25.0.0'
|
||||||
|
|
||||||
|
implementation project(':moduleUtil')
|
||||||
|
}
|
||||||
8
locktableview/src/main/AndroidManifest.xml
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
package="com.rmondjone.locktableview">
|
||||||
|
|
||||||
|
<application>
|
||||||
|
|
||||||
|
</application>
|
||||||
|
|
||||||
|
</manifest>
|
||||||
@@ -0,0 +1,106 @@
|
|||||||
|
package com.rmondjone.locktableview;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.view.MotionEvent;
|
||||||
|
import android.widget.HorizontalScrollView;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 说明 自定义水平滚动视图,解决ScrollView在API23以下没有滚动监听事件问题
|
||||||
|
* 作者 郭翰林
|
||||||
|
* 创建时间 2017/3/31.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class CustomHorizontalScrollView extends HorizontalScrollView {
|
||||||
|
//触摸前的点
|
||||||
|
private float x;
|
||||||
|
|
||||||
|
//手势抬起之后的点
|
||||||
|
private float x1;
|
||||||
|
|
||||||
|
private onScrollChangeListener onScrollChangeListener;
|
||||||
|
|
||||||
|
public CustomHorizontalScrollView(Context context) {
|
||||||
|
super(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CustomHorizontalScrollView(Context context, AttributeSet attrs) {
|
||||||
|
super(context, attrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CustomHorizontalScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||||
|
super(context, attrs, defStyleAttr);
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface onScrollChangeListener {
|
||||||
|
/**
|
||||||
|
* 滚动监听
|
||||||
|
*
|
||||||
|
* @param scrollView
|
||||||
|
* @param x
|
||||||
|
* @param y
|
||||||
|
*/
|
||||||
|
void onScrollChanged(HorizontalScrollView scrollView, int x, int y);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 滑动到最左侧
|
||||||
|
*
|
||||||
|
* @param scrollView
|
||||||
|
*/
|
||||||
|
void onScrollFarLeft(HorizontalScrollView scrollView);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 滑动到最右侧
|
||||||
|
*
|
||||||
|
* @param scrollView
|
||||||
|
*/
|
||||||
|
void onScrollFarRight(HorizontalScrollView scrollView);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onTouchEvent(MotionEvent ev) {
|
||||||
|
switch (ev.getAction()) {
|
||||||
|
case MotionEvent.ACTION_DOWN:
|
||||||
|
x = ev.getX();
|
||||||
|
break;
|
||||||
|
case MotionEvent.ACTION_UP:
|
||||||
|
x1 = ev.getX();
|
||||||
|
if (computeHorizontalScrollOffset() == 0 && x-x1<0) {
|
||||||
|
//滑动最左边
|
||||||
|
if (onScrollChangeListener != null) {
|
||||||
|
onScrollChangeListener.onScrollFarLeft(this);
|
||||||
|
}
|
||||||
|
} else if (computeHorizontalScrollRange() - computeHorizontalScrollOffset()
|
||||||
|
<= computeHorizontalScrollExtent() && x-x1>0) {
|
||||||
|
//滑动最右边
|
||||||
|
if (onScrollChangeListener != null) {
|
||||||
|
onScrollChangeListener.onScrollFarRight(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return super.onTouchEvent(ev);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置监听
|
||||||
|
*
|
||||||
|
* @param onScrollChangeListener
|
||||||
|
*/
|
||||||
|
public void setOnScrollChangeListener(CustomHorizontalScrollView.onScrollChangeListener onScrollChangeListener) {
|
||||||
|
this.onScrollChangeListener = onScrollChangeListener;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
|
||||||
|
super.onScrollChanged(l, t, oldl, oldt);
|
||||||
|
//回调
|
||||||
|
if (onScrollChangeListener != null) {
|
||||||
|
onScrollChangeListener.onScrollChanged(this, l, t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
package com.rmondjone.locktableview;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by aaron on 16/8/3.
|
||||||
|
*/
|
||||||
|
public class DisplayUtil
|
||||||
|
{
|
||||||
|
|
||||||
|
public static int screenWidthPx; //屏幕宽 px
|
||||||
|
public static int screenhightPx; //屏幕高 px
|
||||||
|
public static float density;//屏幕密度
|
||||||
|
public static int densityDPI;//屏幕密度
|
||||||
|
public static float screenWidthDip;// dp单位
|
||||||
|
public static float screenHightDip;// dp单位
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据手机的分辨率从 dp 的单位 转成为 px(像素)
|
||||||
|
*/
|
||||||
|
public static int dip2px(Context context, float dpValue) {
|
||||||
|
final float scale = context.getResources().getDisplayMetrics().density;
|
||||||
|
return (int) (dpValue * scale + 0.5f);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据手机的分辨率从 px(像素) 的单位 转成为 dp
|
||||||
|
*/
|
||||||
|
public static int px2dip(Context context, float pxValue) {
|
||||||
|
final float scale = context.getResources().getDisplayMetrics().density;
|
||||||
|
return (int) (pxValue / scale + 0.5f);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,281 @@
|
|||||||
|
package com.rmondjone.locktableview;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.graphics.Color;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.LinearLayout;
|
||||||
|
import android.widget.NumberPicker;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import androidx.core.content.ContextCompat;
|
||||||
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 说明
|
||||||
|
* 作者 郭翰林
|
||||||
|
* 创建时间 2017/9/17.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class LockColumnAdapter extends RecyclerView.Adapter<LockColumnAdapter.LockViewHolder> {
|
||||||
|
/**
|
||||||
|
* 上下文
|
||||||
|
*/
|
||||||
|
private Context mContext;
|
||||||
|
/**
|
||||||
|
* 第一列数据
|
||||||
|
*/
|
||||||
|
private ArrayList<String> mLockColumnDatas;
|
||||||
|
/**
|
||||||
|
* 第一行背景颜色
|
||||||
|
*/
|
||||||
|
private int mFristRowBackGroudColor;
|
||||||
|
/**
|
||||||
|
* 表格头部字体颜色
|
||||||
|
*/
|
||||||
|
private int mTableHeadTextColor;
|
||||||
|
/**
|
||||||
|
* 表格内容字体颜色
|
||||||
|
*/
|
||||||
|
private int mTableContentTextColor;
|
||||||
|
/**
|
||||||
|
* 是否锁定首行
|
||||||
|
*/
|
||||||
|
private boolean isLockFristRow = true;
|
||||||
|
/**
|
||||||
|
* 记录每列最大宽度
|
||||||
|
*/
|
||||||
|
private ArrayList<Integer> mColumnMaxWidths = new ArrayList<Integer>();
|
||||||
|
/**
|
||||||
|
* 记录每行最大高度
|
||||||
|
*/
|
||||||
|
private ArrayList<Integer> mRowMaxHeights = new ArrayList<Integer>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 单元格字体大小
|
||||||
|
*/
|
||||||
|
private int mTextViewSize;
|
||||||
|
/**
|
||||||
|
* 单元格内边距
|
||||||
|
*/
|
||||||
|
private int mCellPadding;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Item点击事件
|
||||||
|
*/
|
||||||
|
private LockTableView.OnItemClickListenter mOnItemClickListenter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Item长按事件
|
||||||
|
*/
|
||||||
|
private LockTableView.OnItemLongClickListenter mOnItemLongClickListenter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Item项被选中监听(处理被选中的效果)
|
||||||
|
*/
|
||||||
|
private TableViewAdapter.OnItemSelectedListenter mOnItemSelectedListenter;
|
||||||
|
/**
|
||||||
|
* 是否启用交替行背景
|
||||||
|
*/
|
||||||
|
private boolean isAlternateRowBackground = false;
|
||||||
|
/**
|
||||||
|
* 交替行背景颜色1(透明)
|
||||||
|
*/
|
||||||
|
private int mAlternateRowColor1 = Color.TRANSPARENT;
|
||||||
|
/**
|
||||||
|
* 交替行背景颜色2(#323252)
|
||||||
|
*/
|
||||||
|
private int mAlternateRowColor2 = Color.parseColor("#323252");
|
||||||
|
|
||||||
|
// ... 在构造方法后添加以下方法
|
||||||
|
|
||||||
|
public void setAlternateRowBackground(boolean alternateRowBackground) {
|
||||||
|
isAlternateRowBackground = alternateRowBackground;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAlternateRowColors(int color1, int color2) {
|
||||||
|
mAlternateRowColor1 = color1;
|
||||||
|
mAlternateRowColor2 = color2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LockColumnAdapter(Context mContext, ArrayList<String> mLockColumnDatas) {
|
||||||
|
this.mContext = mContext;
|
||||||
|
this.mLockColumnDatas = mLockColumnDatas;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LockViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||||
|
LockViewHolder holder = new LockViewHolder(LayoutInflater.from(mContext).inflate(R.layout.lock_item, null));
|
||||||
|
return holder;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBindViewHolder(LockViewHolder holder, final int position) {
|
||||||
|
// 设置交替行背景颜色
|
||||||
|
if (isAlternateRowBackground && !isLockFristRow) {
|
||||||
|
if (position % 2 == 0) {
|
||||||
|
holder.mLinearLayout.setBackgroundColor(mAlternateRowColor1); // 偶数行透明
|
||||||
|
} else {
|
||||||
|
holder.mLinearLayout.setBackgroundColor(mAlternateRowColor2); // 奇数行#323252
|
||||||
|
}
|
||||||
|
} else if (isAlternateRowBackground && isLockFristRow) {
|
||||||
|
// 如果锁定首行,从第二行开始计算交替背景
|
||||||
|
if (position % 2 == 1) {
|
||||||
|
holder.mLinearLayout.setBackgroundColor(mAlternateRowColor1); // 偶数行透明
|
||||||
|
} else {
|
||||||
|
holder.mLinearLayout.setBackgroundColor(mAlternateRowColor2); // 奇数行#323252
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//设置布局
|
||||||
|
holder.mTextView.setText(mLockColumnDatas.get(position));
|
||||||
|
holder.mTextView.setTextSize(mTextViewSize);
|
||||||
|
LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) holder.mTextView.getLayoutParams();
|
||||||
|
layoutParams.width = DisplayUtil.dip2px(mContext, mColumnMaxWidths.get(0));
|
||||||
|
if (isLockFristRow) {
|
||||||
|
layoutParams.height = DisplayUtil.dip2px(mContext, mRowMaxHeights.get(position + 1));
|
||||||
|
} else {
|
||||||
|
layoutParams.height = DisplayUtil.dip2px(mContext, mRowMaxHeights.get(position));
|
||||||
|
}
|
||||||
|
layoutParams.setMargins(mCellPadding, mCellPadding, mCellPadding, mCellPadding);
|
||||||
|
holder.mTextView.setLayoutParams(layoutParams);
|
||||||
|
//设置颜色
|
||||||
|
if (!isLockFristRow) {
|
||||||
|
if (position == 0) {
|
||||||
|
holder.mLinearLayout.setBackgroundColor(ContextCompat.getColor(mContext, mFristRowBackGroudColor));
|
||||||
|
holder.mTextView.setTextColor(ContextCompat.getColor(mContext, mTableHeadTextColor));
|
||||||
|
} else {
|
||||||
|
holder.mTextView.setTextColor(ContextCompat.getColor(mContext, mTableContentTextColor));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
holder.mTextView.setTextColor(ContextCompat.getColor(mContext, mTableContentTextColor));
|
||||||
|
}
|
||||||
|
//添加事件
|
||||||
|
if(mOnItemClickListenter!=null){
|
||||||
|
holder.mLinearLayout.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
if(mOnItemSelectedListenter!=null){
|
||||||
|
mOnItemSelectedListenter.onItemSelected(v,position);
|
||||||
|
}
|
||||||
|
if(isLockFristRow){
|
||||||
|
mOnItemClickListenter.onItemClick(v,position+1);
|
||||||
|
}else{
|
||||||
|
if(position!=0){
|
||||||
|
mOnItemClickListenter.onItemClick(v,position);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if(mOnItemLongClickListenter!=null){
|
||||||
|
holder.mLinearLayout.setOnLongClickListener(new View.OnLongClickListener() {
|
||||||
|
@Override
|
||||||
|
public boolean onLongClick(View v) {
|
||||||
|
if(mOnItemSelectedListenter!=null){
|
||||||
|
mOnItemSelectedListenter.onItemSelected(v,position);
|
||||||
|
}
|
||||||
|
if (isLockFristRow){
|
||||||
|
mOnItemLongClickListenter.onItemLongClick(v,position+1);
|
||||||
|
}else{
|
||||||
|
if(position!=0){
|
||||||
|
mOnItemLongClickListenter.onItemLongClick(v,position);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
//如果没有设置点击事件和长按事件
|
||||||
|
if(mOnItemClickListenter==null&&mOnItemLongClickListenter==null){
|
||||||
|
holder.mLinearLayout.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
if(mOnItemSelectedListenter!=null){
|
||||||
|
mOnItemSelectedListenter.onItemSelected(v,position);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
holder.mLinearLayout.setOnLongClickListener(new View.OnLongClickListener() {
|
||||||
|
@Override
|
||||||
|
public boolean onLongClick(View v) {
|
||||||
|
if(mOnItemSelectedListenter!=null){
|
||||||
|
mOnItemSelectedListenter.onItemSelected(v,position);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemCount() {
|
||||||
|
return mLockColumnDatas.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemViewType(int position) {
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
|
class LockViewHolder extends RecyclerView.ViewHolder {
|
||||||
|
TextView mTextView;
|
||||||
|
LinearLayout mLinearLayout;
|
||||||
|
|
||||||
|
public LockViewHolder(View itemView) {
|
||||||
|
super(itemView);
|
||||||
|
mTextView = (TextView) itemView.findViewById(R.id.lock_text);
|
||||||
|
mLinearLayout = (LinearLayout) itemView.findViewById(R.id.lock_linearlayout);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//取得每行每列应用高宽
|
||||||
|
public void setColumnMaxWidths(ArrayList<Integer> mColumnMaxWidths) {
|
||||||
|
this.mColumnMaxWidths = mColumnMaxWidths;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRowMaxHeights(ArrayList<Integer> mRowMaxHeights) {
|
||||||
|
this.mRowMaxHeights = mRowMaxHeights;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTextViewSize(int mTextViewSize) {
|
||||||
|
this.mTextViewSize = mTextViewSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLockFristRow(boolean lockFristRow) {
|
||||||
|
isLockFristRow = lockFristRow;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCellPadding(int mCellPadding) {
|
||||||
|
this.mCellPadding = mCellPadding;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFristRowBackGroudColor(int mFristRowBackGroudColor) {
|
||||||
|
this.mFristRowBackGroudColor = mFristRowBackGroudColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTableHeadTextColor(int mTableHeadTextColor) {
|
||||||
|
this.mTableHeadTextColor = mTableHeadTextColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTableContentTextColor(int mTableContentTextColor) {
|
||||||
|
this.mTableContentTextColor = mTableContentTextColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOnItemClickListenter(LockTableView.OnItemClickListenter mOnItemClickListenter) {
|
||||||
|
this.mOnItemClickListenter = mOnItemClickListenter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOnItemLongClickListenter(LockTableView.OnItemLongClickListenter mOnItemLongClickListenter) {
|
||||||
|
this.mOnItemLongClickListenter = mOnItemLongClickListenter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOnItemSelectedListenter(TableViewAdapter.OnItemSelectedListenter mOnItemSelectedListenter) {
|
||||||
|
this.mOnItemSelectedListenter = mOnItemSelectedListenter;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,993 @@
|
|||||||
|
package com.rmondjone.locktableview;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Color;
|
||||||
|
import android.text.Layout;
|
||||||
|
import android.text.StaticLayout;
|
||||||
|
import android.text.TextPaint;
|
||||||
|
import android.text.method.NumberKeyListener;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.util.TypedValue;
|
||||||
|
import android.view.Gravity;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.HorizontalScrollView;
|
||||||
|
import android.widget.LinearLayout;
|
||||||
|
import android.widget.ScrollView;
|
||||||
|
import android.widget.TextView;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
|
||||||
|
import androidx.core.content.ContextCompat;
|
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
|
|
||||||
|
import com.rmondjone.xrecyclerview.ProgressStyle;
|
||||||
|
import com.rmondjone.xrecyclerview.XRecyclerView;
|
||||||
|
import com.xscm.moduleutil.bean.TableCellData;
|
||||||
|
|
||||||
|
import java.lang.reflect.Array;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 说明 可锁定首行和首列的表格视图
|
||||||
|
* 作者 郭翰林
|
||||||
|
* 创建时间 2017/3/29.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class LockTableView {
|
||||||
|
/**
|
||||||
|
* 上下文
|
||||||
|
*/
|
||||||
|
private Context mContext;
|
||||||
|
/**
|
||||||
|
* 表格父视图
|
||||||
|
*/
|
||||||
|
private ViewGroup mContentView;
|
||||||
|
/**
|
||||||
|
* 表格数据,每一行为一条数据,从表头计算
|
||||||
|
*/
|
||||||
|
private ArrayList<ArrayList<TableCellData>> mTableDatas = new ArrayList<ArrayList<TableCellData>>();
|
||||||
|
/**
|
||||||
|
* 表格视图
|
||||||
|
*/
|
||||||
|
private View mTableView;
|
||||||
|
/**
|
||||||
|
* 是否锁定首行
|
||||||
|
*/
|
||||||
|
private boolean isLockFristRow = true;
|
||||||
|
/**
|
||||||
|
* 是否锁定首列
|
||||||
|
*/
|
||||||
|
private boolean isLockFristColumn = true;
|
||||||
|
/**
|
||||||
|
* 最大列宽(dp)
|
||||||
|
*/
|
||||||
|
private int maxColumnWidth;
|
||||||
|
/**
|
||||||
|
* 最小列宽(dp)
|
||||||
|
*/
|
||||||
|
private int minColumnWidth;
|
||||||
|
/**
|
||||||
|
* 最大行高(dp)
|
||||||
|
*/
|
||||||
|
private int maxRowHeight;
|
||||||
|
/**
|
||||||
|
* 最小行高dp)
|
||||||
|
*/
|
||||||
|
private int minRowHeight;
|
||||||
|
/**
|
||||||
|
* 第一行背景颜色
|
||||||
|
*/
|
||||||
|
private int mFristRowBackGroudColor;
|
||||||
|
/**
|
||||||
|
* 数据为空时的缺省值
|
||||||
|
*/
|
||||||
|
private TableCellData mNullableString;
|
||||||
|
/**
|
||||||
|
* 单元格字体大小
|
||||||
|
*/
|
||||||
|
private int mTextViewSize;
|
||||||
|
/**
|
||||||
|
* 表格头部字体颜色
|
||||||
|
*/
|
||||||
|
private int mTableHeadTextColor;
|
||||||
|
/**
|
||||||
|
* 表格内容字体颜色
|
||||||
|
*/
|
||||||
|
private int mTableContentTextColor;
|
||||||
|
/**
|
||||||
|
* 表格横向滚动监听事件
|
||||||
|
*/
|
||||||
|
private OnTableViewListener mTableViewListener;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 表格横向滚动到边界监听事件
|
||||||
|
*/
|
||||||
|
private OnTableViewRangeListener mTableViewRangeListener;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 表格上拉刷新、下拉加载监听事件
|
||||||
|
*/
|
||||||
|
private OnLoadingListener mOnLoadingListener;
|
||||||
|
/**
|
||||||
|
* Item点击事件
|
||||||
|
*/
|
||||||
|
private OnItemClickListenter mOnItemClickListenter;
|
||||||
|
/**
|
||||||
|
* Item长按事件
|
||||||
|
*/
|
||||||
|
private OnItemLongClickListenter mOnItemLongClickListenter;
|
||||||
|
/**
|
||||||
|
* Item选中样式
|
||||||
|
*/
|
||||||
|
private int mOnItemSeletor;
|
||||||
|
/**
|
||||||
|
* 单元格内边距
|
||||||
|
*/
|
||||||
|
private int mCellPadding;
|
||||||
|
/**
|
||||||
|
* 要改变的列集合
|
||||||
|
*/
|
||||||
|
private HashMap<Integer, Integer> mChangeColumns = new HashMap<>();
|
||||||
|
|
||||||
|
|
||||||
|
//表格数据
|
||||||
|
/**
|
||||||
|
* 表格第一行数据,不包括第一个元素
|
||||||
|
*/
|
||||||
|
private ArrayList<TableCellData> mTableFristData = new ArrayList<>();
|
||||||
|
/**
|
||||||
|
* 表格第一列数据,不包括第一个元素
|
||||||
|
*/
|
||||||
|
private ArrayList<String> mTableColumnDatas = new ArrayList<>();
|
||||||
|
/**
|
||||||
|
* 表格左上角数据
|
||||||
|
*/
|
||||||
|
private String mColumnTitle;
|
||||||
|
/**
|
||||||
|
* 表格每一行数据,不包括第一行和第一列
|
||||||
|
*/
|
||||||
|
private ArrayList<ArrayList<TableCellData>> mTableRowDatas = new ArrayList<ArrayList<TableCellData>>();
|
||||||
|
/**
|
||||||
|
* 记录每列最大宽度
|
||||||
|
*/
|
||||||
|
private ArrayList<Integer> mColumnMaxWidths = new ArrayList<Integer>();
|
||||||
|
/**
|
||||||
|
* 记录每行最大高度
|
||||||
|
*/
|
||||||
|
private ArrayList<Integer> mRowMaxHeights = new ArrayList<Integer>();
|
||||||
|
/**
|
||||||
|
* 把所有的滚动视图放图列表,后面实现联动效果
|
||||||
|
*/
|
||||||
|
private ArrayList<HorizontalScrollView> mScrollViews = new ArrayList<HorizontalScrollView>();
|
||||||
|
|
||||||
|
|
||||||
|
//表格视图
|
||||||
|
/**
|
||||||
|
* 表格左上角视图
|
||||||
|
*/
|
||||||
|
private TextView mColumnTitleView;
|
||||||
|
/**
|
||||||
|
* 第一行布局(锁状态)
|
||||||
|
*/
|
||||||
|
private LinearLayout mLockHeadView;
|
||||||
|
/**
|
||||||
|
* 第一行布局(未锁状态)
|
||||||
|
*/
|
||||||
|
private LinearLayout mUnLockHeadView;
|
||||||
|
/**
|
||||||
|
* 第一行滚动视图(锁状态)
|
||||||
|
*/
|
||||||
|
private CustomHorizontalScrollView mLockScrollView;
|
||||||
|
/**
|
||||||
|
* 第一行滚动视图(未锁状态)
|
||||||
|
*/
|
||||||
|
private CustomHorizontalScrollView mUnLockScrollView;
|
||||||
|
/**
|
||||||
|
* 表格主视图
|
||||||
|
*/
|
||||||
|
private XRecyclerView mTableScrollView;
|
||||||
|
/**
|
||||||
|
* 列表适配器
|
||||||
|
*/
|
||||||
|
private TableViewAdapter mTableViewAdapter;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构造方法
|
||||||
|
*
|
||||||
|
* @param mContext 上下文
|
||||||
|
* @param mContentView 表格父视图
|
||||||
|
* @param mTableDatas 表格数据
|
||||||
|
*/
|
||||||
|
public LockTableView(Context mContext, ViewGroup mContentView, ArrayList<ArrayList<TableCellData>> mTableDatas) {
|
||||||
|
this.mContext = mContext;
|
||||||
|
this.mContentView = mContentView;
|
||||||
|
this.mTableDatas = mTableDatas;
|
||||||
|
initAttrs();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化属性
|
||||||
|
*/
|
||||||
|
private void initAttrs() {
|
||||||
|
mTableView = LayoutInflater.from(mContext).inflate(R.layout.locktableview, null);
|
||||||
|
maxColumnWidth =60;
|
||||||
|
minColumnWidth = 30;
|
||||||
|
minRowHeight = 42;
|
||||||
|
maxRowHeight = 42;
|
||||||
|
mTableHeadTextColor = R.color.beijin;
|
||||||
|
mTableContentTextColor = R.color.border_color;
|
||||||
|
mFristRowBackGroudColor = R.color.table_head;
|
||||||
|
mTextViewSize = 14;
|
||||||
|
mCellPadding=DisplayUtil.dip2px(mContext,11);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 展现视图
|
||||||
|
*/
|
||||||
|
public void show() {
|
||||||
|
initData();
|
||||||
|
initView();
|
||||||
|
mContentView.removeAllViews();//清空视图
|
||||||
|
mContentView.addView(mTableView);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化表格数据
|
||||||
|
*/
|
||||||
|
private void initData() {
|
||||||
|
if (mTableDatas != null && mTableDatas.size() > 0) {
|
||||||
|
//检查数据,如果有一行数据长度不一致,以最长为标准填"N/A"字符串,如果有null也替换
|
||||||
|
int maxLength = 0;
|
||||||
|
for (int i = 0; i < mTableDatas.size(); i++) {
|
||||||
|
if (mTableDatas.get(i).size() >= maxLength) {
|
||||||
|
maxLength = mTableDatas.get(i).size();
|
||||||
|
}
|
||||||
|
ArrayList<TableCellData> rowDatas = mTableDatas.get(i);
|
||||||
|
for (int j = 0; j < rowDatas.size(); j++) {
|
||||||
|
if (rowDatas.get(j) == null || rowDatas.get(j).equals("")) {
|
||||||
|
rowDatas.set(j, mNullableString);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mTableDatas.set(i, rowDatas);
|
||||||
|
}
|
||||||
|
// Log.e("每行最多个数",maxLength+"");
|
||||||
|
for (int i = 0; i < mTableDatas.size(); i++) {
|
||||||
|
ArrayList<TableCellData> rowDatas = mTableDatas.get(i);
|
||||||
|
if (rowDatas.size() < maxLength) {
|
||||||
|
int size = maxLength - rowDatas.size();
|
||||||
|
for (int j = 0; j < size; j++) {
|
||||||
|
rowDatas.add(mNullableString);
|
||||||
|
}
|
||||||
|
mTableDatas.set(i, rowDatas);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// //测试
|
||||||
|
// for (int i=0;i<mTableDatas.size();i++){
|
||||||
|
// ArrayList<String> rowDatas=mTableDatas.get(i);
|
||||||
|
// StringBuffer b=new StringBuffer();
|
||||||
|
// for (String str:rowDatas){
|
||||||
|
// b.append("["+str+"]");
|
||||||
|
// }
|
||||||
|
// Log.e("第"+i+"行数据",b.toString()+"/"+rowDatas.size()+"个");
|
||||||
|
// }
|
||||||
|
//初始化每列最大宽度
|
||||||
|
for (int i = 0; i < mTableDatas.size(); i++) {
|
||||||
|
ArrayList<TableCellData> rowDatas = mTableDatas.get(i);
|
||||||
|
StringBuffer buffer = new StringBuffer();
|
||||||
|
for (int j = 0; j < rowDatas.size(); j++) {
|
||||||
|
TextView textView = new TextView(mContext);
|
||||||
|
textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, mTextViewSize);
|
||||||
|
textView.setText(rowDatas.get(j).getTitle());
|
||||||
|
textView.setGravity(Gravity.CENTER);
|
||||||
|
//设置布局
|
||||||
|
LinearLayout.LayoutParams textViewParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,
|
||||||
|
LinearLayout.LayoutParams.WRAP_CONTENT);
|
||||||
|
textViewParams.setMargins(mCellPadding, mCellPadding, mCellPadding, mCellPadding);//android:layout_margin="15dp"
|
||||||
|
textView.setLayoutParams(textViewParams);
|
||||||
|
if (i == 0) {
|
||||||
|
mColumnMaxWidths.add(measureTextWidth(textView, rowDatas.get(j).getTitle()));
|
||||||
|
buffer.append("[" + measureTextWidth(textView, rowDatas.get(j).getTitle()) + "]");
|
||||||
|
} else {
|
||||||
|
int length = mColumnMaxWidths.get(j);
|
||||||
|
int current = measureTextWidth(textView, rowDatas.get(j).getTitle());
|
||||||
|
if (current > length) {
|
||||||
|
mColumnMaxWidths.set(j, current);
|
||||||
|
}
|
||||||
|
buffer.append("[" + measureTextWidth(textView, rowDatas.get(j).getTitle()) + "]");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Log.e("第"+i+"行列最大宽度",buffer.toString());
|
||||||
|
}
|
||||||
|
//如果用户指定某列宽度则按照用户指定宽度算
|
||||||
|
if (mChangeColumns.size() > 0) {
|
||||||
|
for (Integer key : mChangeColumns.keySet()) {
|
||||||
|
changeColumnWidth(key, mChangeColumns.get(key));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Log.e("每列最大宽度dp:",mColumnMaxWidths.toString());
|
||||||
|
|
||||||
|
|
||||||
|
//初始化每行最大高度
|
||||||
|
for (int i = 0; i < mTableDatas.size(); i++) {
|
||||||
|
ArrayList<TableCellData> rowDatas = mTableDatas.get(i);
|
||||||
|
StringBuffer buffer = new StringBuffer();
|
||||||
|
|
||||||
|
TextView textView = new TextView(mContext);
|
||||||
|
textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, mTextViewSize);
|
||||||
|
textView.setGravity(Gravity.CENTER);
|
||||||
|
//设置布局
|
||||||
|
LinearLayout.LayoutParams textViewParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,
|
||||||
|
LinearLayout.LayoutParams.WRAP_CONTENT);
|
||||||
|
textViewParams.setMargins(mCellPadding, mCellPadding, mCellPadding, mCellPadding);//android:layout_margin="15dp"
|
||||||
|
textView.setLayoutParams(textViewParams);
|
||||||
|
int maxHeight = measureTextHeight(textView, rowDatas.get(0).getTitle());
|
||||||
|
mRowMaxHeights.add(maxHeight);
|
||||||
|
for (int j = 0; j < rowDatas.size(); j++) {
|
||||||
|
int currentHeight;
|
||||||
|
//如果用户指定某列宽度则按照用户指定宽度算对应列的高度
|
||||||
|
if (mChangeColumns.size() > 0 && mChangeColumns.containsKey(j)) {
|
||||||
|
currentHeight = getTextViewHeight(textView, rowDatas.get(j).getTitle(), mChangeColumns.get(j));
|
||||||
|
} else {
|
||||||
|
currentHeight = measureTextHeight(textView, rowDatas.get(j).getTitle());
|
||||||
|
}
|
||||||
|
buffer.append("[" + currentHeight + "]");
|
||||||
|
if (currentHeight > maxHeight) {
|
||||||
|
mRowMaxHeights.set(i, currentHeight);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Log.e("第"+i+"行高度",buffer.toString());
|
||||||
|
}
|
||||||
|
// Log.e("每行最大高度dp:",mRowMaxHeights.toString());
|
||||||
|
|
||||||
|
if (isLockFristRow) {
|
||||||
|
ArrayList<TableCellData> fristRowDatas = (ArrayList<TableCellData>) mTableDatas.get(0).clone();
|
||||||
|
if (isLockFristColumn) {
|
||||||
|
//锁定第一列
|
||||||
|
mColumnTitle = fristRowDatas.get(0).getTitle();
|
||||||
|
fristRowDatas.remove(0);
|
||||||
|
mTableFristData.addAll(fristRowDatas);
|
||||||
|
//构造第一列数据,并且构造表格每行数据
|
||||||
|
for (int i = 1; i < mTableDatas.size(); i++) {
|
||||||
|
ArrayList<TableCellData> rowDatas = (ArrayList<TableCellData>) mTableDatas.get(i).clone();
|
||||||
|
mTableColumnDatas.add(rowDatas.get(0).getTitle());
|
||||||
|
rowDatas.remove(0);
|
||||||
|
mTableRowDatas.add(rowDatas);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
mTableFristData.addAll(fristRowDatas);
|
||||||
|
for (int i = 1; i < mTableDatas.size(); i++) {
|
||||||
|
mTableRowDatas.add(mTableDatas.get(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (isLockFristColumn) {
|
||||||
|
//锁定第一列
|
||||||
|
//构造第一列数据,并且构造表格每行数据
|
||||||
|
for (int i = 0; i < mTableDatas.size(); i++) {
|
||||||
|
ArrayList<TableCellData> rowDatas = (ArrayList<TableCellData>) mTableDatas.get(i).clone();
|
||||||
|
mTableColumnDatas.add(rowDatas.get(0).getTitle());
|
||||||
|
rowDatas.remove(0);
|
||||||
|
mTableRowDatas.add(rowDatas);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (int i = 0; i < mTableDatas.size(); i++) {
|
||||||
|
mTableRowDatas.add(mTableDatas.get(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Log.e("第一行数据", mTableFristData.toString());
|
||||||
|
// Log.e("第一列数据", mTableColumnDatas.toString());
|
||||||
|
// Log.e("每行数据", mTableRowDatas.toString());
|
||||||
|
} else {
|
||||||
|
Toast.makeText(mContext, "表格数据为空!", Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化表格视图
|
||||||
|
*/
|
||||||
|
private void initView() {
|
||||||
|
mColumnTitleView = (TextView) mTableView.findViewById(R.id.lockHeadView_Text);
|
||||||
|
mLockHeadView = (LinearLayout) mTableView.findViewById(R.id.lockHeadView);
|
||||||
|
mUnLockHeadView = (LinearLayout) mTableView.findViewById(R.id.unLockHeadView);
|
||||||
|
mLockScrollView = (CustomHorizontalScrollView) mTableView.findViewById(R.id.lockHeadView_ScrollView);
|
||||||
|
mUnLockScrollView = (CustomHorizontalScrollView) mTableView.findViewById(R.id.unlockHeadView_ScrollView);
|
||||||
|
//表格主视图
|
||||||
|
mTableScrollView = (XRecyclerView) mTableView.findViewById(R.id.table_scrollView);
|
||||||
|
LinearLayoutManager layoutManager = new LinearLayoutManager(mContext);
|
||||||
|
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
|
||||||
|
mTableScrollView.setLayoutManager(layoutManager);
|
||||||
|
// mTableScrollView.setArrowImageView(R.drawable.iconfont_downgrey);
|
||||||
|
// mTableScrollView.setRefreshProgressStyle(ProgressStyle.BallRotate);
|
||||||
|
// mTableScrollView.setLoadingMoreProgressStyle(ProgressStyle.BallRotate);
|
||||||
|
// mTableScrollView.setLoadingListener(new XRecyclerView.LoadingListener() {
|
||||||
|
// @Override
|
||||||
|
// public void onRefresh() {
|
||||||
|
// if (mOnLoadingListener != null) {
|
||||||
|
// mOnLoadingListener.onRefresh(mTableScrollView, mTableDatas);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Override
|
||||||
|
// public void onLoadMore() {
|
||||||
|
// if (mOnLoadingListener != null) {
|
||||||
|
// mOnLoadingListener.onLoadMore(mTableScrollView, mTableDatas);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
mTableViewAdapter = new TableViewAdapter(mContext, mTableColumnDatas, mTableRowDatas, isLockFristColumn, isLockFristRow);
|
||||||
|
mTableViewAdapter.setCellPadding(mCellPadding);
|
||||||
|
mTableViewAdapter.setColumnMaxWidths(mColumnMaxWidths);
|
||||||
|
mTableViewAdapter.setRowMaxHeights(mRowMaxHeights);
|
||||||
|
mTableViewAdapter.setTextViewSize(mTextViewSize);
|
||||||
|
mTableViewAdapter.setTableContentTextColor(mTableContentTextColor);
|
||||||
|
mTableViewAdapter.setTableHeadTextColor(mTableHeadTextColor);
|
||||||
|
mTableViewAdapter.setFristRowBackGroudColor(mFristRowBackGroudColor);
|
||||||
|
mTableViewAdapter.setHorizontalScrollView(new OnTableViewListener() {
|
||||||
|
@Override
|
||||||
|
public void onTableViewScrollChange(int x, int y) {
|
||||||
|
changeAllScrollView(x, y);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// if (mOnItemClickListenter != null) {
|
||||||
|
mTableViewAdapter.setOnItemClickListenter(null);
|
||||||
|
// }
|
||||||
|
// if (mOnItemLongClickListenter != null) {
|
||||||
|
// mTableViewAdapter.setOnItemLongClickListenter(mOnItemLongClickListenter);
|
||||||
|
// }
|
||||||
|
// if (mOnItemSeletor != 0) {
|
||||||
|
// mTableViewAdapter.setOnItemSeletor(mOnItemSeletor);
|
||||||
|
// } else {
|
||||||
|
// mTableViewAdapter.setOnItemSeletor(R.color.dashline_color);
|
||||||
|
// }
|
||||||
|
mTableViewAdapter.setTableViewRangeListener(new OnTableViewRangeListener() {
|
||||||
|
@Override
|
||||||
|
public void onLeft(HorizontalScrollView view) {
|
||||||
|
if (mTableViewRangeListener != null) {
|
||||||
|
mTableViewRangeListener.onLeft(view);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onRight(HorizontalScrollView view) {
|
||||||
|
if (mTableViewRangeListener != null) {
|
||||||
|
mTableViewRangeListener.onRight(view);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
mTableViewAdapter.setOnTableViewCreatedListener(new TableViewAdapter.OnTableViewCreatedListener() {
|
||||||
|
@Override
|
||||||
|
public void onTableViewCreatedCompleted(CustomHorizontalScrollView mScrollView) {
|
||||||
|
mScrollViews.add(mScrollView);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
mTableScrollView.setAdapter(mTableViewAdapter);
|
||||||
|
|
||||||
|
mLockHeadView.setBackgroundColor(ContextCompat.getColor(mContext, mFristRowBackGroudColor));
|
||||||
|
mUnLockHeadView.setBackgroundColor(ContextCompat.getColor(mContext, mFristRowBackGroudColor));
|
||||||
|
if (isLockFristRow) {
|
||||||
|
if (isLockFristColumn) {
|
||||||
|
mLockHeadView.setVisibility(View.VISIBLE);
|
||||||
|
mUnLockHeadView.setVisibility(View.GONE);
|
||||||
|
} else {
|
||||||
|
mLockHeadView.setVisibility(View.GONE);
|
||||||
|
mUnLockHeadView.setVisibility(View.VISIBLE);
|
||||||
|
}
|
||||||
|
creatHeadView();
|
||||||
|
} else {
|
||||||
|
mLockHeadView.setVisibility(View.GONE);
|
||||||
|
mUnLockHeadView.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建头部视图
|
||||||
|
*/
|
||||||
|
private void creatHeadView() {
|
||||||
|
if (isLockFristColumn) {
|
||||||
|
mColumnTitleView.setTextColor(ContextCompat.getColor(mContext, mTableHeadTextColor));
|
||||||
|
mColumnTitleView.setTextSize(TypedValue.COMPLEX_UNIT_SP, mTextViewSize);
|
||||||
|
mColumnTitleView.setText(mColumnTitle);
|
||||||
|
LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) mColumnTitleView.getLayoutParams();
|
||||||
|
layoutParams.width = DisplayUtil.dip2px(mContext, mColumnMaxWidths.get(0));
|
||||||
|
layoutParams.height = DisplayUtil.dip2px(mContext, mRowMaxHeights.get(0));
|
||||||
|
layoutParams.setMargins(mCellPadding, mCellPadding, mCellPadding, mCellPadding);
|
||||||
|
mColumnTitleView.setLayoutParams(layoutParams);
|
||||||
|
//构造滚动视图
|
||||||
|
createScollview(mLockScrollView, mTableFristData, true);
|
||||||
|
mScrollViews.add(mLockScrollView);
|
||||||
|
mLockScrollView.setOnScrollChangeListener(new CustomHorizontalScrollView.onScrollChangeListener() {
|
||||||
|
@Override
|
||||||
|
public void onScrollChanged(HorizontalScrollView scrollView, int x, int y) {
|
||||||
|
changeAllScrollView(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onScrollFarLeft(HorizontalScrollView scrollView) {
|
||||||
|
if (mTableViewRangeListener != null) {
|
||||||
|
mTableViewRangeListener.onLeft(scrollView);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onScrollFarRight(HorizontalScrollView scrollView) {
|
||||||
|
if (mTableViewRangeListener != null) {
|
||||||
|
mTableViewRangeListener.onRight(scrollView);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
createScollview(mUnLockScrollView, mTableFristData, true);
|
||||||
|
mScrollViews.add(mUnLockScrollView);
|
||||||
|
mUnLockScrollView.setOnScrollChangeListener(new CustomHorizontalScrollView.onScrollChangeListener() {
|
||||||
|
@Override
|
||||||
|
public void onScrollChanged(HorizontalScrollView scrollView, int x, int y) {
|
||||||
|
changeAllScrollView(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onScrollFarLeft(HorizontalScrollView scrollView) {
|
||||||
|
if (mTableViewRangeListener != null) {
|
||||||
|
mTableViewRangeListener.onLeft(scrollView);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onScrollFarRight(HorizontalScrollView scrollView) {
|
||||||
|
if (mTableViewRangeListener != null) {
|
||||||
|
mTableViewRangeListener.onRight(scrollView);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 改变所有滚动视图位置
|
||||||
|
*
|
||||||
|
* @param x
|
||||||
|
* @param y
|
||||||
|
*/
|
||||||
|
private void changeAllScrollView(int x, int y) {
|
||||||
|
if (mScrollViews.size() > 0) {
|
||||||
|
if (mTableViewListener != null) {
|
||||||
|
mTableViewListener.onTableViewScrollChange(x, y);
|
||||||
|
}
|
||||||
|
for (int i = 0; i < mScrollViews.size(); i++) {
|
||||||
|
HorizontalScrollView scrollView = mScrollViews.get(i);
|
||||||
|
scrollView.scrollTo(x, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据最大最小值,计算TextView的宽度
|
||||||
|
*
|
||||||
|
* @param textView
|
||||||
|
* @param text
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private int measureTextWidth(TextView textView, String text) {
|
||||||
|
if (textView != null) {
|
||||||
|
LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) textView.getLayoutParams();
|
||||||
|
int width = DisplayUtil.px2dip(mContext, layoutParams.leftMargin) +
|
||||||
|
DisplayUtil.px2dip(mContext, layoutParams.rightMargin) +
|
||||||
|
getTextViewWidth(textView, text);
|
||||||
|
if (width <= minColumnWidth) {
|
||||||
|
return minColumnWidth;
|
||||||
|
} else if (width > minColumnWidth && width <= maxColumnWidth) {
|
||||||
|
return width;
|
||||||
|
} else {
|
||||||
|
return maxColumnWidth;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 计算TextView高度
|
||||||
|
*
|
||||||
|
* @param textView
|
||||||
|
* @param text
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private int measureTextHeight(TextView textView, String text) {
|
||||||
|
if (textView != null) {
|
||||||
|
LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) textView.getLayoutParams();
|
||||||
|
int height = getTextViewHeight(textView, text);
|
||||||
|
if (height < minRowHeight) {
|
||||||
|
return minRowHeight;
|
||||||
|
} else if (height > minRowHeight && height < maxRowHeight) {
|
||||||
|
return height;
|
||||||
|
} else {
|
||||||
|
return maxRowHeight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据文字计算textview的高度
|
||||||
|
*
|
||||||
|
* @param textView
|
||||||
|
* @param text
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private int getTextViewHeight(TextView textView, String text) {
|
||||||
|
if (textView != null) {
|
||||||
|
int width = measureTextWidth(textView, text);
|
||||||
|
TextPaint textPaint = textView.getPaint();
|
||||||
|
StaticLayout staticLayout = new StaticLayout(text, textPaint, DisplayUtil.dip2px(mContext, width), Layout.Alignment.ALIGN_NORMAL, 1, 0, false);
|
||||||
|
int height = DisplayUtil.px2dip(mContext, staticLayout.getHeight());
|
||||||
|
return height;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 说明 根据文字和指定宽度计算高度
|
||||||
|
* 作者 郭翰林
|
||||||
|
* 创建时间 2018/3/15 下午12:39
|
||||||
|
*
|
||||||
|
* @param textView
|
||||||
|
* @param text
|
||||||
|
* @param width
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private int getTextViewHeight(TextView textView, String text, int width) {
|
||||||
|
if (textView != null) {
|
||||||
|
TextPaint textPaint = textView.getPaint();
|
||||||
|
StaticLayout staticLayout = new StaticLayout(text, textPaint, DisplayUtil.dip2px(mContext, width), Layout.Alignment.ALIGN_NORMAL, 1, 0, false);
|
||||||
|
int height = DisplayUtil.px2dip(mContext, staticLayout.getHeight());
|
||||||
|
return height;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据文字计算textview的高度
|
||||||
|
*
|
||||||
|
* @param view
|
||||||
|
* @param text
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private int getTextViewWidth(TextView view, String text) {
|
||||||
|
if (view != null) {
|
||||||
|
TextPaint paint = view.getPaint();
|
||||||
|
return DisplayUtil.px2dip(mContext, (int) paint.measureText(text));
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构造滚动视图
|
||||||
|
*
|
||||||
|
* @param scrollView
|
||||||
|
* @param datas
|
||||||
|
* @param isFristRow 是否是第一行
|
||||||
|
*/
|
||||||
|
private void createScollview(HorizontalScrollView scrollView, List<TableCellData> datas, boolean isFristRow) {
|
||||||
|
//设置LinearLayout
|
||||||
|
LinearLayout linearLayout = new LinearLayout(mContext);
|
||||||
|
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,
|
||||||
|
LinearLayout.LayoutParams.MATCH_PARENT);
|
||||||
|
linearLayout.setLayoutParams(layoutParams);
|
||||||
|
linearLayout.setGravity(Gravity.CENTER);
|
||||||
|
linearLayout.setOrientation(LinearLayout.HORIZONTAL);
|
||||||
|
for (int i = 0; i < datas.size(); i++) {
|
||||||
|
//构造单元格
|
||||||
|
TextView textView = new TextView(mContext);
|
||||||
|
if (isFristRow) {
|
||||||
|
textView.setTextColor(ContextCompat.getColor(mContext, mTableHeadTextColor));
|
||||||
|
} else {
|
||||||
|
textView.setTextColor(ContextCompat.getColor(mContext, mTableContentTextColor));
|
||||||
|
}
|
||||||
|
textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, mTextViewSize);
|
||||||
|
textView.setGravity(Gravity.CENTER);
|
||||||
|
textView.setText(datas.get(i).getTitle());
|
||||||
|
//设置布局
|
||||||
|
LinearLayout.LayoutParams textViewParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,
|
||||||
|
LinearLayout.LayoutParams.WRAP_CONTENT);
|
||||||
|
textViewParams.setMargins(mCellPadding, mCellPadding, mCellPadding, mCellPadding);
|
||||||
|
textView.setLayoutParams(textViewParams);
|
||||||
|
ViewGroup.LayoutParams textViewParamsCopy = textView.getLayoutParams();
|
||||||
|
if (isLockFristColumn) {
|
||||||
|
textViewParamsCopy.width = DisplayUtil.dip2px(mContext, mColumnMaxWidths.get(i + 1));
|
||||||
|
} else {
|
||||||
|
textViewParamsCopy.width = DisplayUtil.dip2px(mContext, mColumnMaxWidths.get(i));
|
||||||
|
}
|
||||||
|
linearLayout.addView(textView);
|
||||||
|
// //画分隔线
|
||||||
|
// if (i != datas.size() - 1) {
|
||||||
|
// View splitView = new View(mContext);
|
||||||
|
// ViewGroup.LayoutParams splitViewParmas = new ViewGroup.LayoutParams(DisplayUtil.dip2px(mContext, 1),
|
||||||
|
// ViewGroup.LayoutParams.MATCH_PARENT);
|
||||||
|
// splitView.setLayoutParams(splitViewParmas);
|
||||||
|
// if (isFristRow) {
|
||||||
|
// splitView.setBackgroundColor(ContextCompat.getColor(mContext, R.color.white));
|
||||||
|
// } else {
|
||||||
|
// splitView.setBackgroundColor(ContextCompat.getColor(mContext, R.color.light_gray));
|
||||||
|
// }
|
||||||
|
// linearLayout.addView(splitView);
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
scrollView.addView(linearLayout);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 说明 改变指定列指定宽度
|
||||||
|
* 作者 郭翰林
|
||||||
|
* 创建时间 2018/3/15 上午11:06
|
||||||
|
*
|
||||||
|
* @param mColumnNum
|
||||||
|
* @param mColumnWidth
|
||||||
|
*/
|
||||||
|
private void changeColumnWidth(int mColumnNum, int mColumnWidth) {
|
||||||
|
if (mColumnMaxWidths != null && mColumnMaxWidths.size() > 0) {
|
||||||
|
if (mColumnNum < mColumnMaxWidths.size() && mColumnNum >= 0) {
|
||||||
|
mColumnMaxWidths.set(mColumnNum, mColumnWidth + DisplayUtil.px2dip(mContext, 15) * 2);
|
||||||
|
} else {
|
||||||
|
Log.e("LockTableView", "指定列数不存在");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//属性设置
|
||||||
|
public LockTableView setLockFristRow(boolean lockFristRow) {
|
||||||
|
isLockFristRow = lockFristRow;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LockTableView setLockFristColumn(boolean lockFristColumn) {
|
||||||
|
isLockFristColumn = lockFristColumn;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LockTableView setMaxColumnWidth(int maxColumnWidth) {
|
||||||
|
this.maxColumnWidth = maxColumnWidth;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LockTableView setMinColumnWidth(int minColumnWidth) {
|
||||||
|
this.minColumnWidth = minColumnWidth;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LockTableView setFristRowBackGroudColor(int mFristRowBackGroudColor) {
|
||||||
|
this.mFristRowBackGroudColor = mFristRowBackGroudColor;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LockTableView setNullableString(TableCellData mNullableString) {
|
||||||
|
this.mNullableString = mNullableString;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LockTableView setTextViewSize(int mTextViewSize) {
|
||||||
|
this.mTextViewSize = mTextViewSize;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LockTableView setTableHeadTextColor(int mTableHeadTextColor) {
|
||||||
|
this.mTableHeadTextColor = mTableHeadTextColor;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LockTableView setTableContentTextColor(int mTableContentTextColor) {
|
||||||
|
this.mTableContentTextColor = mTableContentTextColor;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LockTableView setMaxRowHeight(int maxRowHeight) {
|
||||||
|
this.maxRowHeight = maxRowHeight;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LockTableView setMinRowHeight(int minRowHeight) {
|
||||||
|
this.minRowHeight = minRowHeight;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LockTableView setTableViewListener(OnTableViewListener mTableViewListener) {
|
||||||
|
this.mTableViewListener = mTableViewListener;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LockTableView setOnLoadingListener(OnLoadingListener mOnLoadingListener) {
|
||||||
|
this.mOnLoadingListener = mOnLoadingListener;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LockTableView setTableViewRangeListener(OnTableViewRangeListener mTableViewRangeListener) {
|
||||||
|
this.mTableViewRangeListener = mTableViewRangeListener;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LockTableView setOnItemClickListenter(OnItemClickListenter mOnItemClickListenter) {
|
||||||
|
this.mOnItemClickListenter = mOnItemClickListenter;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LockTableView setOnItemLongClickListenter(OnItemLongClickListenter mOnItemLongClickListenter) {
|
||||||
|
this.mOnItemLongClickListenter = mOnItemLongClickListenter;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LockTableView setOnItemSeletor(int mOnItemSeletor) {
|
||||||
|
this.mOnItemSeletor = mOnItemSeletor;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LockTableView setCellPadding(int mCellPadding) {
|
||||||
|
this.mCellPadding = DisplayUtil.dip2px(mContext,mCellPadding);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 指定第几列对应的宽度
|
||||||
|
*
|
||||||
|
* @param mColumnNum
|
||||||
|
* @param mColumnWidth
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public LockTableView setColumnWidth(int mColumnNum, int mColumnWidth) {
|
||||||
|
//判断是否已经设置过
|
||||||
|
if (mChangeColumns.containsKey(mColumnNum)) {
|
||||||
|
mChangeColumns.remove(mColumnNum);
|
||||||
|
}
|
||||||
|
mChangeColumns.put(mColumnNum, mColumnWidth);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//值获取
|
||||||
|
public ArrayList<Integer> getColumnMaxWidths() {
|
||||||
|
return mColumnMaxWidths;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ArrayList<Integer> getRowMaxHeights() {
|
||||||
|
return mRowMaxHeights;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LinearLayout getLockHeadView() {
|
||||||
|
return mLockHeadView;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LinearLayout getUnLockHeadView() {
|
||||||
|
return mUnLockHeadView;
|
||||||
|
}
|
||||||
|
|
||||||
|
public XRecyclerView getTableScrollView() {
|
||||||
|
return mTableScrollView;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ArrayList<HorizontalScrollView> getScrollViews() {
|
||||||
|
return mScrollViews;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 说明 数据刷新时,重新设值
|
||||||
|
* 作者 郭翰林
|
||||||
|
* 创建时间 2017/9/17 下午2:33
|
||||||
|
*
|
||||||
|
* @param mTableDatas
|
||||||
|
*/
|
||||||
|
public void setTableDatas(ArrayList<ArrayList<TableCellData>> mTableDatas) {
|
||||||
|
this.mTableDatas = mTableDatas;
|
||||||
|
mTableFristData.clear();
|
||||||
|
mTableColumnDatas.clear();
|
||||||
|
mTableRowDatas.clear();
|
||||||
|
mColumnMaxWidths.clear();
|
||||||
|
mRowMaxHeights.clear();
|
||||||
|
initData();
|
||||||
|
mTableViewAdapter.notifyDataSetChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 横向滚动监听
|
||||||
|
*/
|
||||||
|
public interface OnTableViewListener {
|
||||||
|
/**
|
||||||
|
* 滚动监听
|
||||||
|
*
|
||||||
|
* @param x
|
||||||
|
* @param y
|
||||||
|
*/
|
||||||
|
void onTableViewScrollChange(int x, int y);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 横向滚动视图滑动到边界的监听
|
||||||
|
*/
|
||||||
|
public interface OnTableViewRangeListener {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 说明 最左侧
|
||||||
|
* 作者 郭翰林
|
||||||
|
* 创建时间 2017/12/14 下午4:45
|
||||||
|
*
|
||||||
|
* @param view
|
||||||
|
*/
|
||||||
|
void onLeft(HorizontalScrollView view);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 说明 最右侧
|
||||||
|
* 作者 郭翰林
|
||||||
|
* 创建时间 2017/12/14 下午4:45
|
||||||
|
*
|
||||||
|
* @param view
|
||||||
|
*/
|
||||||
|
void onRight(HorizontalScrollView view);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上拉刷新,下拉加载
|
||||||
|
*/
|
||||||
|
public interface OnLoadingListener {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 说明 下拉刷新
|
||||||
|
* 作者 郭翰林
|
||||||
|
* 创建时间 2017/9/17 下午1:54
|
||||||
|
*
|
||||||
|
* @param mXRecyclerView
|
||||||
|
* @param mTableDatas
|
||||||
|
*/
|
||||||
|
void onRefresh(XRecyclerView mXRecyclerView, ArrayList<ArrayList<String>> mTableDatas);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 说明 上拉加载
|
||||||
|
* 作者 郭翰林
|
||||||
|
* 创建时间 2017/9/17 下午1:55
|
||||||
|
*
|
||||||
|
* @param mXRecyclerView
|
||||||
|
* @param mTableDatas
|
||||||
|
*/
|
||||||
|
void onLoadMore(XRecyclerView mXRecyclerView, ArrayList<ArrayList<String>> mTableDatas);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 说明 Item点击事件
|
||||||
|
* 作者 郭翰林
|
||||||
|
* 创建时间 2018/2/2 下午4:50
|
||||||
|
*/
|
||||||
|
public interface OnItemClickListenter {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param item 点击项
|
||||||
|
* @param position 点击位置
|
||||||
|
*/
|
||||||
|
void onItemClick(View item, int position);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 说明 Item长按事件
|
||||||
|
* 作者 郭翰林
|
||||||
|
* 创建时间 2018/2/2 下午4:50
|
||||||
|
*/
|
||||||
|
public interface OnItemLongClickListenter {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param item 点击项
|
||||||
|
* @param position 点击位置
|
||||||
|
*/
|
||||||
|
void onItemLongClick(View item, int position);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,376 @@
|
|||||||
|
package com.rmondjone.locktableview;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.graphics.Color;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.HorizontalScrollView;
|
||||||
|
|
||||||
|
import androidx.core.content.ContextCompat;
|
||||||
|
import androidx.recyclerview.widget.DividerItemDecoration;
|
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
|
import com.rmondjone.xrecyclerview.XRecyclerView;
|
||||||
|
import com.xscm.moduleutil.bean.TableCellData;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 说明
|
||||||
|
* 作者 郭翰林
|
||||||
|
* 创建时间 2017/9/17.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class TableViewAdapter extends RecyclerView.Adapter<TableViewAdapter.TableViewHolder> {
|
||||||
|
/**
|
||||||
|
* 上下文
|
||||||
|
*/
|
||||||
|
private Context mContext;
|
||||||
|
/**
|
||||||
|
* 第一列数据
|
||||||
|
*/
|
||||||
|
private ArrayList<String> mLockColumnDatas;
|
||||||
|
/**
|
||||||
|
* 表格数据
|
||||||
|
*/
|
||||||
|
private ArrayList<ArrayList<TableCellData>> mTableDatas;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 第一列是否被锁定
|
||||||
|
*/
|
||||||
|
private boolean isLockColumn;
|
||||||
|
/**
|
||||||
|
* 第一行是否被锁定
|
||||||
|
*/
|
||||||
|
private boolean isLockFristRow;
|
||||||
|
/**
|
||||||
|
* 记录每列最大宽度
|
||||||
|
*/
|
||||||
|
private ArrayList<Integer> mColumnMaxWidths = new ArrayList<Integer>();
|
||||||
|
/**
|
||||||
|
* 记录每行最大高度
|
||||||
|
*/
|
||||||
|
private ArrayList<Integer> mRowMaxHeights = new ArrayList<Integer>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 单元格字体大小
|
||||||
|
*/
|
||||||
|
private int mTextViewSize;
|
||||||
|
/**
|
||||||
|
* 第一行背景颜色
|
||||||
|
*/
|
||||||
|
private int mFristRowBackGroudColor;
|
||||||
|
/**
|
||||||
|
* 表格头部字体颜色
|
||||||
|
*/
|
||||||
|
private int mTableHeadTextColor;
|
||||||
|
/**
|
||||||
|
* 表格内容字体颜色
|
||||||
|
*/
|
||||||
|
private int mTableContentTextColor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 单元格内边距
|
||||||
|
*/
|
||||||
|
private int mCellPadding;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 表格横向滚动监听事件
|
||||||
|
*/
|
||||||
|
private LockTableView.OnTableViewListener mTableViewListener;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 表格横向滚动到边界监听事件
|
||||||
|
*/
|
||||||
|
private LockTableView.OnTableViewRangeListener mTableViewRangeListener;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Item点击事件
|
||||||
|
*/
|
||||||
|
private LockTableView.OnItemClickListenter mOnItemClickListenter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Item长按事件
|
||||||
|
*/
|
||||||
|
private LockTableView.OnItemLongClickListenter mOnItemLongClickListenter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Item选中样式
|
||||||
|
*/
|
||||||
|
private int mOnItemSeletor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 表格视图加载完成监听事件
|
||||||
|
*/
|
||||||
|
private OnTableViewCreatedListener mOnTableViewCreatedListener;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 锁定视图Adapter
|
||||||
|
*/
|
||||||
|
private LockColumnAdapter mLockAdapter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 未锁定视图Adapter
|
||||||
|
*/
|
||||||
|
private UnLockColumnAdapter mUnLockAdapter;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构造方法
|
||||||
|
*
|
||||||
|
* @param mContext
|
||||||
|
* @param mLockColumnDatas
|
||||||
|
* @param mTableDatas
|
||||||
|
* @param isLockColumn
|
||||||
|
*/
|
||||||
|
public TableViewAdapter(Context mContext, ArrayList<String> mLockColumnDatas, ArrayList<ArrayList<TableCellData>> mTableDatas, boolean isLockColumn, boolean isLockRow) {
|
||||||
|
this.mContext = mContext;
|
||||||
|
this.mLockColumnDatas = mLockColumnDatas;
|
||||||
|
this.mTableDatas = mTableDatas;
|
||||||
|
this.isLockColumn = isLockColumn;
|
||||||
|
this.isLockFristRow = isLockRow;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TableViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||||
|
TableViewHolder mTableViewHolder = new TableViewHolder(LayoutInflater.from(mContext).inflate(R.layout.locktablecontentview, null));
|
||||||
|
if (mOnTableViewCreatedListener != null) {
|
||||||
|
mOnTableViewCreatedListener.onTableViewCreatedCompleted(mTableViewHolder.mScrollView);
|
||||||
|
}
|
||||||
|
return mTableViewHolder;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBindViewHolder(final TableViewHolder holder, int position) {
|
||||||
|
LinearLayoutManager layoutManager = new LinearLayoutManager(mContext);
|
||||||
|
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
|
||||||
|
if (isLockColumn) {
|
||||||
|
//构造锁定视图
|
||||||
|
holder.mLockRecyclerView.setVisibility(View.VISIBLE);
|
||||||
|
if (mLockAdapter == null) {
|
||||||
|
mLockAdapter = new LockColumnAdapter(mContext, mLockColumnDatas);
|
||||||
|
mLockAdapter.setCellPadding(mCellPadding);
|
||||||
|
mLockAdapter.setRowMaxHeights(mRowMaxHeights);
|
||||||
|
mLockAdapter.setColumnMaxWidths(mColumnMaxWidths);
|
||||||
|
mLockAdapter.setTextViewSize(mTextViewSize);
|
||||||
|
mLockAdapter.setLockFristRow(isLockFristRow);
|
||||||
|
mLockAdapter.setFristRowBackGroudColor(mFristRowBackGroudColor);
|
||||||
|
mLockAdapter.setTableHeadTextColor(mTableHeadTextColor);
|
||||||
|
mLockAdapter.setTableContentTextColor(mTableContentTextColor);
|
||||||
|
// 添加交替行背景颜色设置
|
||||||
|
mLockAdapter.setAlternateRowBackground(true);
|
||||||
|
// mLockAdapter.setOnItemSelectedListenter(new OnItemSelectedListenter() {
|
||||||
|
// @Override
|
||||||
|
// public void onItemSelected(View view, int position) {
|
||||||
|
// RecyclerView.LayoutManager mLockLayoutManager = holder.mLockRecyclerView.getLayoutManager();
|
||||||
|
// int itemCount=mLockLayoutManager.getItemCount();
|
||||||
|
// View item=mLockLayoutManager.getChildAt(position);
|
||||||
|
// item.setBackgroundColor(ContextCompat.getColor(mContext,mOnItemSeletor));
|
||||||
|
// for(int i=0;i<itemCount;i++){
|
||||||
|
// if(i!=position){
|
||||||
|
// mLockLayoutManager.getChildAt(i).setBackgroundColor(Color.TRANSPARENT);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// RecyclerView.LayoutManager mUnLockLayoutManager = holder.mMainRecyclerView.getLayoutManager();
|
||||||
|
// int itemUnLockCount=mUnLockLayoutManager.getItemCount();
|
||||||
|
// View mUnlockItem=mUnLockLayoutManager.getChildAt(position);
|
||||||
|
// mUnlockItem.setBackgroundColor(ContextCompat.getColor(mContext,mOnItemSeletor));
|
||||||
|
// for(int i=0;i<itemUnLockCount;i++){
|
||||||
|
// if(i!=position){
|
||||||
|
// mUnLockLayoutManager.getChildAt(i).setBackgroundColor(Color.TRANSPARENT);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
// if (mOnItemClickListenter != null) {
|
||||||
|
// mLockAdapter.setOnItemClickListenter(mOnItemClickListenter);
|
||||||
|
// }
|
||||||
|
// if (mOnItemLongClickListenter != null) {
|
||||||
|
// mLockAdapter.setOnItemLongClickListenter(mOnItemLongClickListenter);
|
||||||
|
// }
|
||||||
|
holder.mLockRecyclerView.setLayoutManager(layoutManager);
|
||||||
|
// holder.mLockRecyclerView.addItemDecoration(new DividerItemDecoration(mContext
|
||||||
|
// , DividerItemDecoration.VERTICAL));
|
||||||
|
holder.mLockRecyclerView.setAdapter(mLockAdapter);
|
||||||
|
} else {
|
||||||
|
mLockAdapter.notifyDataSetChanged();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
holder.mLockRecyclerView.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
//构造主表格视图
|
||||||
|
if (mUnLockAdapter == null) {
|
||||||
|
mUnLockAdapter = new UnLockColumnAdapter(mContext, mTableDatas);
|
||||||
|
mUnLockAdapter.setCellPadding(mCellPadding);
|
||||||
|
mUnLockAdapter.setColumnMaxWidths(mColumnMaxWidths);
|
||||||
|
mUnLockAdapter.setRowMaxHeights(mRowMaxHeights);
|
||||||
|
mUnLockAdapter.setTextViewSize(mTextViewSize);
|
||||||
|
mUnLockAdapter.setLockFristRow(isLockFristRow);
|
||||||
|
mUnLockAdapter.setFristRowBackGroudColor(mFristRowBackGroudColor);
|
||||||
|
mUnLockAdapter.setTableHeadTextColor(mTableHeadTextColor);
|
||||||
|
mUnLockAdapter.setTableContentTextColor(mTableContentTextColor);
|
||||||
|
mUnLockAdapter.setLockFristColumn(isLockColumn);
|
||||||
|
|
||||||
|
// 添加交替行背景颜色设置
|
||||||
|
mUnLockAdapter.setAlternateRowBackground(true);
|
||||||
|
|
||||||
|
// mUnLockAdapter.setOnItemSelectedListenter(new OnItemSelectedListenter() {
|
||||||
|
// @Override
|
||||||
|
// public void onItemSelected(View view, int position) {
|
||||||
|
// if(isLockColumn){
|
||||||
|
// RecyclerView.LayoutManager mLockLayoutManager = holder.mLockRecyclerView.getLayoutManager();
|
||||||
|
// int itemCount=mLockLayoutManager.getItemCount();
|
||||||
|
// View item=mLockLayoutManager.getChildAt(position);
|
||||||
|
// item.setBackgroundColor(ContextCompat.getColor(mContext,mOnItemSeletor));
|
||||||
|
// for(int i=0;i<itemCount;i++){
|
||||||
|
// if(i!=position){
|
||||||
|
// mLockLayoutManager.getChildAt(i).setBackgroundColor(Color.TRANSPARENT);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// RecyclerView.LayoutManager mUnLockLayoutManager = holder.mMainRecyclerView.getLayoutManager();
|
||||||
|
// int itemUnLockCount=mUnLockLayoutManager.getItemCount();
|
||||||
|
// View mUnlockItem=mUnLockLayoutManager.getChildAt(position);
|
||||||
|
// mUnlockItem.setBackgroundColor(ContextCompat.getColor(mContext,mOnItemSeletor));
|
||||||
|
// for(int i=0;i<itemUnLockCount;i++){
|
||||||
|
// if(i!=position){
|
||||||
|
// mUnLockLayoutManager.getChildAt(i).setBackgroundColor(Color.TRANSPARENT);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
// if (mOnItemClickListenter != null) {
|
||||||
|
// mUnLockAdapter.setOnItemClickListenter(mOnItemClickListenter);
|
||||||
|
// }
|
||||||
|
// if (mOnItemLongClickListenter != null) {
|
||||||
|
// mUnLockAdapter.setOnItemLongClickListenter(mOnItemLongClickListenter);
|
||||||
|
// }
|
||||||
|
LinearLayoutManager unlockLayoutManager = new LinearLayoutManager(mContext);
|
||||||
|
unlockLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
|
||||||
|
holder.mMainRecyclerView.setLayoutManager(unlockLayoutManager);
|
||||||
|
// holder.mMainRecyclerView.addItemDecoration(new DividerItemDecoration(mContext
|
||||||
|
// , DividerItemDecoration.VERTICAL));
|
||||||
|
holder.mMainRecyclerView.setAdapter(mUnLockAdapter);
|
||||||
|
} else {
|
||||||
|
mUnLockAdapter.notifyDataSetChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemCount() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
class TableViewHolder extends RecyclerView.ViewHolder {
|
||||||
|
RecyclerView mLockRecyclerView;
|
||||||
|
RecyclerView mMainRecyclerView;
|
||||||
|
CustomHorizontalScrollView mScrollView;
|
||||||
|
|
||||||
|
public TableViewHolder(View itemView) {
|
||||||
|
super(itemView);
|
||||||
|
mLockRecyclerView = (RecyclerView) itemView.findViewById(R.id.lock_recyclerview);
|
||||||
|
mMainRecyclerView = (RecyclerView) itemView.findViewById(R.id.main_recyclerview);
|
||||||
|
//解决滑动冲突,只保留最外层RecyclerView的下拉和上拉事件
|
||||||
|
mLockRecyclerView.setFocusable(false);
|
||||||
|
mMainRecyclerView.setFocusable(false);
|
||||||
|
mScrollView = (CustomHorizontalScrollView) itemView.findViewById(R.id.lockScrollView_parent);
|
||||||
|
mScrollView.setOnScrollChangeListener(new CustomHorizontalScrollView.onScrollChangeListener() {
|
||||||
|
@Override
|
||||||
|
public void onScrollChanged(HorizontalScrollView scrollView, int x, int y) {
|
||||||
|
if (mTableViewListener != null) {
|
||||||
|
mTableViewListener.onTableViewScrollChange(x, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onScrollFarLeft(HorizontalScrollView scrollView) {
|
||||||
|
if (mTableViewRangeListener != null) {
|
||||||
|
mTableViewRangeListener.onLeft(scrollView);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onScrollFarRight(HorizontalScrollView scrollView) {
|
||||||
|
if (mTableViewRangeListener != null) {
|
||||||
|
mTableViewRangeListener.onRight(scrollView);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 表格创建完成回调
|
||||||
|
*/
|
||||||
|
public interface OnTableViewCreatedListener {
|
||||||
|
/**
|
||||||
|
* 返回当前横向滚动视图给上个界面
|
||||||
|
*/
|
||||||
|
void onTableViewCreatedCompleted(CustomHorizontalScrollView mScrollView);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Item项被选中监听
|
||||||
|
*/
|
||||||
|
public interface OnItemSelectedListenter {
|
||||||
|
void onItemSelected(View view, int position);
|
||||||
|
}
|
||||||
|
|
||||||
|
//取得每行每列应用高宽
|
||||||
|
public void setColumnMaxWidths(ArrayList<Integer> mColumnMaxWidths) {
|
||||||
|
this.mColumnMaxWidths = mColumnMaxWidths;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRowMaxHeights(ArrayList<Integer> mRowMaxHeights) {
|
||||||
|
this.mRowMaxHeights = mRowMaxHeights;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTextViewSize(int mTextViewSize) {
|
||||||
|
this.mTextViewSize = mTextViewSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFristRowBackGroudColor(int mFristRowBackGroudColor) {
|
||||||
|
this.mFristRowBackGroudColor = mFristRowBackGroudColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTableHeadTextColor(int mTableHeadTextColor) {
|
||||||
|
this.mTableHeadTextColor = mTableHeadTextColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTableContentTextColor(int mTableContentTextColor) {
|
||||||
|
this.mTableContentTextColor = mTableContentTextColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHorizontalScrollView(LockTableView.OnTableViewListener mTableViewListener) {
|
||||||
|
this.mTableViewListener = mTableViewListener;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOnTableViewCreatedListener(OnTableViewCreatedListener mOnTableViewCreatedListener) {
|
||||||
|
this.mOnTableViewCreatedListener = mOnTableViewCreatedListener;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTableViewRangeListener(LockTableView.OnTableViewRangeListener mTableViewRangeListener) {
|
||||||
|
this.mTableViewRangeListener = mTableViewRangeListener;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOnItemClickListenter(LockTableView.OnItemClickListenter mOnItemClickListenter) {
|
||||||
|
this.mOnItemClickListenter = mOnItemClickListenter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOnItemLongClickListenter(LockTableView.OnItemLongClickListenter mOnItemLongClickListenter) {
|
||||||
|
this.mOnItemLongClickListenter = mOnItemLongClickListenter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOnItemSeletor(int mOnItemSeletor) {
|
||||||
|
this.mOnItemSeletor = mOnItemSeletor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCellPadding(int mCellPadding) {
|
||||||
|
this.mCellPadding = mCellPadding;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,376 @@
|
|||||||
|
package com.rmondjone.locktableview;
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.graphics.Color;
|
||||||
|
import android.util.TypedValue;
|
||||||
|
import android.view.Gravity;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.HorizontalScrollView;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
import android.widget.LinearLayout;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.core.content.ContextCompat;
|
||||||
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
import com.xscm.moduleutil.bean.TableCellData;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 说明
|
||||||
|
* 作者 郭翰林
|
||||||
|
* 创建时间 2017/9/17.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class UnLockColumnAdapter extends RecyclerView.Adapter<UnLockColumnAdapter.UnLockViewHolder> {
|
||||||
|
/**
|
||||||
|
* 上下文
|
||||||
|
*/
|
||||||
|
private Context mContext;
|
||||||
|
/**
|
||||||
|
* 表格数据
|
||||||
|
*/
|
||||||
|
private ArrayList<ArrayList<TableCellData>> mTableDatas;
|
||||||
|
/**
|
||||||
|
* 第一行背景颜色
|
||||||
|
*/
|
||||||
|
private int mFristRowBackGroudColor;
|
||||||
|
/**
|
||||||
|
* 表格头部字体颜色
|
||||||
|
*/
|
||||||
|
private int mTableHeadTextColor;
|
||||||
|
/**
|
||||||
|
* 表格内容字体颜色
|
||||||
|
*/
|
||||||
|
private int mTableContentTextColor;
|
||||||
|
/**
|
||||||
|
* 记录每列最大宽度
|
||||||
|
*/
|
||||||
|
private ArrayList<Integer> mColumnMaxWidths = new ArrayList<Integer>();
|
||||||
|
/**
|
||||||
|
* 记录每行最大高度
|
||||||
|
*/
|
||||||
|
private ArrayList<Integer> mRowMaxHeights = new ArrayList<Integer>();
|
||||||
|
/**
|
||||||
|
* 单元格字体大小
|
||||||
|
*/
|
||||||
|
private int mTextViewSize;
|
||||||
|
/**
|
||||||
|
* 是否锁定首行
|
||||||
|
*/
|
||||||
|
private boolean isLockFristRow = true;
|
||||||
|
/**
|
||||||
|
* 是否锁定首列
|
||||||
|
*/
|
||||||
|
private boolean isLockFristColumn = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 单元格内边距
|
||||||
|
*/
|
||||||
|
private int mCellPadding;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Item点击事件
|
||||||
|
*/
|
||||||
|
private LockTableView.OnItemClickListenter mOnItemClickListenter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Item长按事件
|
||||||
|
*/
|
||||||
|
private LockTableView.OnItemLongClickListenter mOnItemLongClickListenter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Item项被选中监听(处理被选中的效果)
|
||||||
|
*/
|
||||||
|
private TableViewAdapter.OnItemSelectedListenter mOnItemSelectedListenter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构造方法
|
||||||
|
*
|
||||||
|
* @param mContext
|
||||||
|
* @param mTableDatas
|
||||||
|
*/
|
||||||
|
public UnLockColumnAdapter(Context mContext, ArrayList<ArrayList<TableCellData>> mTableDatas) {
|
||||||
|
this.mContext = mContext;
|
||||||
|
this.mTableDatas = mTableDatas;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否启用交替行背景
|
||||||
|
*/
|
||||||
|
private boolean isAlternateRowBackground = false;
|
||||||
|
/**
|
||||||
|
* 交替行背景颜色1(透明)
|
||||||
|
*/
|
||||||
|
private int mAlternateRowColor1 = Color.TRANSPARENT;
|
||||||
|
/**
|
||||||
|
* 交替行背景颜色2(#323252)
|
||||||
|
*/
|
||||||
|
private int mAlternateRowColor2 = Color.parseColor("#323252");
|
||||||
|
|
||||||
|
// ... 在构造方法后添加以下方法
|
||||||
|
|
||||||
|
public void setAlternateRowBackground(boolean alternateRowBackground) {
|
||||||
|
isAlternateRowBackground = alternateRowBackground;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAlternateRowColors(int color1, int color2) {
|
||||||
|
mAlternateRowColor1 = color1;
|
||||||
|
mAlternateRowColor2 = color2;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public int getItemCount() {
|
||||||
|
return mTableDatas.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public UnLockViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||||
|
UnLockViewHolder holder = new UnLockViewHolder(LayoutInflater.from(mContext).inflate(R.layout.unlock_item, null));
|
||||||
|
return holder;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBindViewHolder(@NonNull UnLockViewHolder holder, @SuppressLint("RecyclerView") int position) {
|
||||||
|
ArrayList<TableCellData> datas = mTableDatas.get(position);
|
||||||
|
|
||||||
|
|
||||||
|
// 设置交替行背景颜色
|
||||||
|
if (isAlternateRowBackground && !isLockFristRow) {
|
||||||
|
if (position % 2 == 0) {
|
||||||
|
holder.mLinearLayout.setBackgroundColor(mAlternateRowColor1); // 偶数行透明
|
||||||
|
} else {
|
||||||
|
holder.mLinearLayout.setBackgroundColor(mAlternateRowColor2); // 奇数行#323252
|
||||||
|
}
|
||||||
|
} else if (isAlternateRowBackground && isLockFristRow) {
|
||||||
|
// 如果锁定首行,从第二行开始计算交替背景
|
||||||
|
if (position % 2 == 1) {
|
||||||
|
holder.mLinearLayout.setBackgroundColor(mAlternateRowColor1); // 偶数行透明
|
||||||
|
} else {
|
||||||
|
holder.mLinearLayout.setBackgroundColor(mAlternateRowColor2); // 奇数行#323252
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isLockFristRow) {
|
||||||
|
//第一行是锁定的
|
||||||
|
createRowView(holder.mLinearLayout, datas, false, mRowMaxHeights.get(position + 1));
|
||||||
|
} else {
|
||||||
|
if (position == 0) {
|
||||||
|
holder.mLinearLayout.setBackgroundColor(ContextCompat.getColor(mContext, mFristRowBackGroudColor));
|
||||||
|
createRowView(holder.mLinearLayout, datas, true, mRowMaxHeights.get(position));
|
||||||
|
} else {
|
||||||
|
createRowView(holder.mLinearLayout, datas, false, mRowMaxHeights.get(position));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//添加事件
|
||||||
|
// if(mOnItemClickListenter!=null){
|
||||||
|
// holder.mLinearLayout.setOnClickListener(new View.OnClickListener() {
|
||||||
|
// @Override
|
||||||
|
// public void onClick(View v) {
|
||||||
|
// if(mOnItemSelectedListenter!=null){
|
||||||
|
// mOnItemSelectedListenter.onItemSelected(v,position);
|
||||||
|
// }
|
||||||
|
// if(isLockFristRow){
|
||||||
|
// mOnItemClickListenter.onItemClick(v,position+1);
|
||||||
|
// }else{
|
||||||
|
// if(position!=0){
|
||||||
|
// mOnItemClickListenter.onItemClick(v,position);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
// if(mOnItemLongClickListenter!=null){
|
||||||
|
// holder.mLinearLayout.setOnLongClickListener(new View.OnLongClickListener() {
|
||||||
|
// @Override
|
||||||
|
// public boolean onLongClick(View v) {
|
||||||
|
// if(mOnItemSelectedListenter!=null){
|
||||||
|
// mOnItemSelectedListenter.onItemSelected(v,position);
|
||||||
|
// }
|
||||||
|
// if (isLockFristRow){
|
||||||
|
// mOnItemLongClickListenter.onItemLongClick(v,position+1);
|
||||||
|
// }else{
|
||||||
|
// if(position!=0){
|
||||||
|
// mOnItemLongClickListenter.onItemLongClick(v,position);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
//如果没有设置点击事件和长按事件
|
||||||
|
// if(mOnItemClickListenter==null&&mOnItemLongClickListenter==null){
|
||||||
|
// holder.mLinearLayout.setOnClickListener(new View.OnClickListener() {
|
||||||
|
// @Override
|
||||||
|
// public void onClick(View v) {
|
||||||
|
// if(mOnItemSelectedListenter!=null){
|
||||||
|
// mOnItemSelectedListenter.onItemSelected(v,position);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
// holder.mLinearLayout.setOnLongClickListener(new View.OnLongClickListener() {
|
||||||
|
// @Override
|
||||||
|
// public boolean onLongClick(View v) {
|
||||||
|
// if(mOnItemSelectedListenter!=null){
|
||||||
|
// mOnItemSelectedListenter.onItemSelected(v,position);
|
||||||
|
// }
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemViewType(int position) {
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//取得每行每列应用高宽
|
||||||
|
public void setColumnMaxWidths(ArrayList<Integer> mColumnMaxWidths) {
|
||||||
|
this.mColumnMaxWidths = mColumnMaxWidths;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRowMaxHeights(ArrayList<Integer> mRowMaxHeights) {
|
||||||
|
this.mRowMaxHeights = mRowMaxHeights;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTextViewSize(int mTextViewSize) {
|
||||||
|
this.mTextViewSize = mTextViewSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLockFristRow(boolean lockFristRow) {
|
||||||
|
isLockFristRow = lockFristRow;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFristRowBackGroudColor(int mFristRowBackGroudColor) {
|
||||||
|
this.mFristRowBackGroudColor = mFristRowBackGroudColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTableHeadTextColor(int mTableHeadTextColor) {
|
||||||
|
this.mTableHeadTextColor = mTableHeadTextColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTableContentTextColor(int mTableContentTextColor) {
|
||||||
|
this.mTableContentTextColor = mTableContentTextColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLockFristColumn(boolean lockFristColumn) {
|
||||||
|
isLockFristColumn = lockFristColumn;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOnItemClickListenter(LockTableView.OnItemClickListenter mOnItemClickListenter) {
|
||||||
|
this.mOnItemClickListenter = mOnItemClickListenter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOnItemLongClickListenter(LockTableView.OnItemLongClickListenter mOnItemLongClickListenter) {
|
||||||
|
this.mOnItemLongClickListenter = mOnItemLongClickListenter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOnItemSelectedListenter(TableViewAdapter.OnItemSelectedListenter mOnItemSelectedListenter) {
|
||||||
|
this.mOnItemSelectedListenter = mOnItemSelectedListenter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCellPadding(int mCellPadding) {
|
||||||
|
this.mCellPadding = mCellPadding;
|
||||||
|
}
|
||||||
|
|
||||||
|
class UnLockViewHolder extends RecyclerView.ViewHolder {
|
||||||
|
LinearLayout mLinearLayout;
|
||||||
|
|
||||||
|
public UnLockViewHolder(View itemView) {
|
||||||
|
super(itemView);
|
||||||
|
mLinearLayout = (LinearLayout) itemView.findViewById(R.id.unlock_linearlayout);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构造每行数据视图
|
||||||
|
*
|
||||||
|
* @param linearLayout
|
||||||
|
* @param datas
|
||||||
|
* @param isFristRow 是否是第一行
|
||||||
|
*/
|
||||||
|
private void createRowView(LinearLayout linearLayout, List<TableCellData> datas, boolean isFristRow, int mMaxHeight) {
|
||||||
|
//设置LinearLayout
|
||||||
|
linearLayout.removeAllViews();//首先清空LinearLayout,复用会造成重复绘制,使内容超出预期长度
|
||||||
|
for (int i = 0; i < datas.size(); i++) {
|
||||||
|
//根据数据内容决定显示ImageView还是TextView
|
||||||
|
if (datas.get(i).getTitle().equals("1") || datas.get(i).getTitle().equals("0")) {
|
||||||
|
//显示ImageView
|
||||||
|
ImageView imageView = new ImageView(mContext);
|
||||||
|
if (datas.get(i).getTitle().equals("1")) {
|
||||||
|
imageView.setImageResource(com.xscm.moduleutil.R.mipmap.icon_yes);
|
||||||
|
} else {
|
||||||
|
imageView.setImageResource(com.xscm.moduleutil.R.mipmap.icon_no);
|
||||||
|
}
|
||||||
|
|
||||||
|
//设置布局
|
||||||
|
LinearLayout.LayoutParams imageParams = new LinearLayout.LayoutParams(
|
||||||
|
LinearLayout.LayoutParams.WRAP_CONTENT,
|
||||||
|
LinearLayout.LayoutParams.WRAP_CONTENT);
|
||||||
|
imageParams.setMargins(mCellPadding, mCellPadding, mCellPadding, mCellPadding);
|
||||||
|
imageParams.height = DisplayUtil.dip2px(mContext, mMaxHeight);
|
||||||
|
if (isLockFristColumn) {
|
||||||
|
imageParams.width = DisplayUtil.dip2px(mContext, mColumnMaxWidths.get(i+1));
|
||||||
|
} else {
|
||||||
|
imageParams.width = DisplayUtil.dip2px(mContext, mColumnMaxWidths.get(i));
|
||||||
|
}
|
||||||
|
imageView.setLayoutParams(imageParams);
|
||||||
|
imageView.setScaleType(ImageView.ScaleType.CENTER);
|
||||||
|
linearLayout.addView(imageView);
|
||||||
|
} else {
|
||||||
|
//显示TextView
|
||||||
|
TextView textView = new TextView(mContext);
|
||||||
|
if (isFristRow) {
|
||||||
|
textView.setTextColor(ContextCompat.getColor(mContext, mTableHeadTextColor));
|
||||||
|
} else {
|
||||||
|
textView.setTextColor(ContextCompat.getColor(mContext, mTableContentTextColor));
|
||||||
|
}
|
||||||
|
textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, mTextViewSize);
|
||||||
|
textView.setGravity(Gravity.CENTER);
|
||||||
|
textView.setText(datas.get(i).getTitle());
|
||||||
|
// 添加颜色值空值检查
|
||||||
|
String color = datas.get(i).getColor();
|
||||||
|
if (color != null && !color.isEmpty() &&
|
||||||
|
!color.equals("无")) {
|
||||||
|
textView.setTextColor(Color.parseColor(color));
|
||||||
|
}
|
||||||
|
|
||||||
|
//设置布局
|
||||||
|
LinearLayout.LayoutParams textViewParams = new LinearLayout.LayoutParams(
|
||||||
|
LinearLayout.LayoutParams.WRAP_CONTENT,
|
||||||
|
LinearLayout.LayoutParams.WRAP_CONTENT);
|
||||||
|
textViewParams.setMargins(mCellPadding, mCellPadding, mCellPadding, mCellPadding);
|
||||||
|
textViewParams.height = DisplayUtil.dip2px(mContext, mMaxHeight);
|
||||||
|
if (isLockFristColumn) {
|
||||||
|
textViewParams.width = DisplayUtil.dip2px(mContext, mColumnMaxWidths.get(i+1));
|
||||||
|
} else {
|
||||||
|
textViewParams.width = DisplayUtil.dip2px(mContext, mColumnMaxWidths.get(i));
|
||||||
|
}
|
||||||
|
textView.setLayoutParams(textViewParams);
|
||||||
|
linearLayout.addView(textView);
|
||||||
|
}
|
||||||
|
|
||||||
|
// //画分隔线
|
||||||
|
// if (i != datas.size() - 1) {
|
||||||
|
// View splitView = new View(mContext);
|
||||||
|
// ViewGroup.LayoutParams splitViewParmas = new ViewGroup.LayoutParams(DisplayUtil.dip2px(mContext, 1),
|
||||||
|
// ViewGroup.LayoutParams.MATCH_PARENT);
|
||||||
|
// splitView.setLayoutParams(splitViewParmas);
|
||||||
|
// if (isFristRow) {
|
||||||
|
// splitView.setBackgroundColor(ContextCompat.getColor(mContext, R.color.white));
|
||||||
|
// } else {
|
||||||
|
// splitView.setBackgroundColor(ContextCompat.getColor(mContext, R.color.light_gray));
|
||||||
|
// }
|
||||||
|
// linearLayout.addView(splitView);
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
package com.rmondjone.xrecyclerview;
|
||||||
|
|
||||||
|
|
||||||
|
import com.google.android.material.appbar.AppBarLayout;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by jianghejie on 16/6/19.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public abstract class AppBarStateChangeListener implements AppBarLayout.OnOffsetChangedListener {
|
||||||
|
|
||||||
|
public enum State {
|
||||||
|
EXPANDED,
|
||||||
|
COLLAPSED,
|
||||||
|
IDLE
|
||||||
|
}
|
||||||
|
|
||||||
|
private State mCurrentState = State.IDLE;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void onOffsetChanged(AppBarLayout appBarLayout, int i) {
|
||||||
|
if (i == 0) {
|
||||||
|
if (mCurrentState != State.EXPANDED) {
|
||||||
|
onStateChanged(appBarLayout, State.EXPANDED);
|
||||||
|
}
|
||||||
|
mCurrentState = State.EXPANDED;
|
||||||
|
} else if (Math.abs(i) >= appBarLayout.getTotalScrollRange()) {
|
||||||
|
if (mCurrentState != State.COLLAPSED) {
|
||||||
|
onStateChanged(appBarLayout, State.COLLAPSED);
|
||||||
|
}
|
||||||
|
mCurrentState = State.COLLAPSED;
|
||||||
|
} else {
|
||||||
|
if (mCurrentState != State.IDLE) {
|
||||||
|
onStateChanged(appBarLayout, State.IDLE);
|
||||||
|
}
|
||||||
|
mCurrentState = State.IDLE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public abstract void onStateChanged(AppBarLayout appBarLayout, State state);
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,268 @@
|
|||||||
|
package com.rmondjone.xrecyclerview;
|
||||||
|
|
||||||
|
import android.animation.ValueAnimator;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.view.Gravity;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.view.animation.Animation;
|
||||||
|
import android.view.animation.RotateAnimation;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
import android.widget.LinearLayout;
|
||||||
|
import android.widget.ProgressBar;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import com.rmondjone.xrecyclerview.progressindicator.AVLoadingIndicatorView;
|
||||||
|
import com.rmondjone.locktableview.R;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
public class ArrowRefreshHeader extends LinearLayout implements BaseRefreshHeader {
|
||||||
|
|
||||||
|
private LinearLayout mContainer;
|
||||||
|
private ImageView mArrowImageView;
|
||||||
|
private SimpleViewSwitcher mProgressBar;
|
||||||
|
private TextView mStatusTextView;
|
||||||
|
private int mState = STATE_NORMAL;
|
||||||
|
|
||||||
|
private TextView mHeaderTimeView;
|
||||||
|
|
||||||
|
private Animation mRotateUpAnim;
|
||||||
|
private Animation mRotateDownAnim;
|
||||||
|
|
||||||
|
private static final int ROTATE_ANIM_DURATION = 180;
|
||||||
|
|
||||||
|
public int mMeasuredHeight;
|
||||||
|
|
||||||
|
public ArrowRefreshHeader(Context context) {
|
||||||
|
super(context);
|
||||||
|
initView();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param context
|
||||||
|
* @param attrs
|
||||||
|
*/
|
||||||
|
public ArrowRefreshHeader(Context context, AttributeSet attrs) {
|
||||||
|
super(context, attrs);
|
||||||
|
initView();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initView() {
|
||||||
|
// 初始情况,设置下拉刷新view高度为0
|
||||||
|
mContainer = (LinearLayout) LayoutInflater.from(getContext()).inflate(
|
||||||
|
R.layout.listview_header, null);
|
||||||
|
LayoutParams lp = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
|
||||||
|
lp.setMargins(0, 0, 0, 0);
|
||||||
|
this.setLayoutParams(lp);
|
||||||
|
this.setPadding(0, 0, 0, 0);
|
||||||
|
|
||||||
|
addView(mContainer, new LayoutParams(LayoutParams.MATCH_PARENT, 0));
|
||||||
|
setGravity(Gravity.BOTTOM);
|
||||||
|
|
||||||
|
mArrowImageView = (ImageView)findViewById(R.id.listview_header_arrow);
|
||||||
|
mStatusTextView = (TextView)findViewById(R.id.refresh_status_textview);
|
||||||
|
|
||||||
|
//init the progress view
|
||||||
|
mProgressBar = (SimpleViewSwitcher)findViewById(R.id.listview_header_progressbar);
|
||||||
|
AVLoadingIndicatorView progressView = new AVLoadingIndicatorView(getContext());
|
||||||
|
progressView.setIndicatorColor(0xffB5B5B5);
|
||||||
|
progressView.setIndicatorId(ProgressStyle.BallSpinFadeLoader);
|
||||||
|
mProgressBar.setView(progressView);
|
||||||
|
|
||||||
|
|
||||||
|
mRotateUpAnim = new RotateAnimation(0.0f, -180.0f,
|
||||||
|
Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
|
||||||
|
mRotateUpAnim.setDuration(ROTATE_ANIM_DURATION);
|
||||||
|
mRotateUpAnim.setFillAfter(true);
|
||||||
|
mRotateDownAnim = new RotateAnimation(-180.0f, 0.0f,
|
||||||
|
Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
|
||||||
|
mRotateDownAnim.setDuration(ROTATE_ANIM_DURATION);
|
||||||
|
mRotateDownAnim.setFillAfter(true);
|
||||||
|
|
||||||
|
mHeaderTimeView = (TextView)findViewById(R.id.last_refresh_time);
|
||||||
|
measure(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT);
|
||||||
|
mMeasuredHeight = getMeasuredHeight();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setProgressStyle(int style) {
|
||||||
|
if(style == ProgressStyle.SysProgress){
|
||||||
|
mProgressBar.setView(new ProgressBar(getContext(), null, android.R.attr.progressBarStyle));
|
||||||
|
}else{
|
||||||
|
AVLoadingIndicatorView progressView = new AVLoadingIndicatorView(this.getContext());
|
||||||
|
progressView.setIndicatorColor(0xffB5B5B5);
|
||||||
|
progressView.setIndicatorId(style);
|
||||||
|
mProgressBar.setView(progressView);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setArrowImageView(int resid){
|
||||||
|
mArrowImageView.setImageResource(resid);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setState(int state) {
|
||||||
|
if (state == mState) return ;
|
||||||
|
|
||||||
|
if (state == STATE_REFRESHING) { // 显示进度
|
||||||
|
mArrowImageView.clearAnimation();
|
||||||
|
mArrowImageView.setVisibility(View.INVISIBLE);
|
||||||
|
mProgressBar.setVisibility(View.VISIBLE);
|
||||||
|
smoothScrollTo(mMeasuredHeight);
|
||||||
|
} else if(state == STATE_DONE) {
|
||||||
|
mArrowImageView.setVisibility(View.INVISIBLE);
|
||||||
|
mProgressBar.setVisibility(View.INVISIBLE);
|
||||||
|
} else { // 显示箭头图片
|
||||||
|
mArrowImageView.setVisibility(View.VISIBLE);
|
||||||
|
mProgressBar.setVisibility(View.INVISIBLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(state){
|
||||||
|
case STATE_NORMAL:
|
||||||
|
if (mState == STATE_RELEASE_TO_REFRESH) {
|
||||||
|
mArrowImageView.startAnimation(mRotateDownAnim);
|
||||||
|
}
|
||||||
|
if (mState == STATE_REFRESHING) {
|
||||||
|
mArrowImageView.clearAnimation();
|
||||||
|
}
|
||||||
|
mStatusTextView.setText(R.string.listview_header_hint_normal);
|
||||||
|
break;
|
||||||
|
case STATE_RELEASE_TO_REFRESH:
|
||||||
|
if (mState != STATE_RELEASE_TO_REFRESH) {
|
||||||
|
mArrowImageView.clearAnimation();
|
||||||
|
mArrowImageView.startAnimation(mRotateUpAnim);
|
||||||
|
mStatusTextView.setText(R.string.listview_header_hint_release);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case STATE_REFRESHING:
|
||||||
|
mStatusTextView.setText(R.string.refreshing);
|
||||||
|
break;
|
||||||
|
case STATE_DONE:
|
||||||
|
mStatusTextView.setText(R.string.refresh_done);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
|
||||||
|
mState = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getState() {
|
||||||
|
return mState;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void refreshComplete(){
|
||||||
|
mHeaderTimeView.setText(friendlyTime(new Date()));
|
||||||
|
setState(STATE_DONE);
|
||||||
|
new Handler().postDelayed(new Runnable(){
|
||||||
|
public void run() {
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
}, 200);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setVisibleHeight(int height) {
|
||||||
|
if (height < 0) height = 0;
|
||||||
|
LayoutParams lp = (LayoutParams) mContainer .getLayoutParams();
|
||||||
|
lp.height = height;
|
||||||
|
mContainer.setLayoutParams(lp);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getVisibleHeight() {
|
||||||
|
LayoutParams lp = (LayoutParams) mContainer.getLayoutParams();
|
||||||
|
return lp.height;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onMove(float delta) {
|
||||||
|
if(getVisibleHeight() > 0 || delta > 0) {
|
||||||
|
setVisibleHeight((int) delta + getVisibleHeight());
|
||||||
|
if (mState <= STATE_RELEASE_TO_REFRESH) { // 未处于刷新状态,更新箭头
|
||||||
|
if (getVisibleHeight() > mMeasuredHeight) {
|
||||||
|
setState(STATE_RELEASE_TO_REFRESH);
|
||||||
|
}else {
|
||||||
|
setState(STATE_NORMAL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean releaseAction() {
|
||||||
|
boolean isOnRefresh = false;
|
||||||
|
int height = getVisibleHeight();
|
||||||
|
if (height == 0) // not visible.
|
||||||
|
isOnRefresh = false;
|
||||||
|
|
||||||
|
if(getVisibleHeight() > mMeasuredHeight && mState < STATE_REFRESHING){
|
||||||
|
setState(STATE_REFRESHING);
|
||||||
|
isOnRefresh = true;
|
||||||
|
}
|
||||||
|
// refreshing and header isn't shown fully. do nothing.
|
||||||
|
if (mState == STATE_REFRESHING && height <= mMeasuredHeight) {
|
||||||
|
// return false;
|
||||||
|
}
|
||||||
|
if (mState != STATE_REFRESHING) {
|
||||||
|
smoothScrollTo(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mState == STATE_REFRESHING) {
|
||||||
|
int destHeight = mMeasuredHeight;
|
||||||
|
smoothScrollTo(destHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
return isOnRefresh;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reset() {
|
||||||
|
smoothScrollTo(0);
|
||||||
|
new Handler().postDelayed(new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
setState(STATE_NORMAL);
|
||||||
|
}
|
||||||
|
}, 500);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void smoothScrollTo(int destHeight) {
|
||||||
|
ValueAnimator animator = ValueAnimator.ofInt(getVisibleHeight(), destHeight);
|
||||||
|
animator.setDuration(300).start();
|
||||||
|
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
||||||
|
@Override
|
||||||
|
public void onAnimationUpdate(ValueAnimator animation)
|
||||||
|
{
|
||||||
|
setVisibleHeight((int) animation.getAnimatedValue());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
animator.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String friendlyTime(Date time) {
|
||||||
|
//获取time距离当前的秒数
|
||||||
|
int ct = (int)((System.currentTimeMillis() - time.getTime())/1000);
|
||||||
|
|
||||||
|
if(ct == 0) {
|
||||||
|
return "刚刚";
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ct > 0 && ct < 60) {
|
||||||
|
return ct + "秒前";
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ct >= 60 && ct < 3600) {
|
||||||
|
return Math.max(ct / 60,1) + "分钟前";
|
||||||
|
}
|
||||||
|
if(ct >= 3600 && ct < 86400)
|
||||||
|
return ct / 3600 + "小时前";
|
||||||
|
if(ct >= 86400 && ct < 2592000){ //86400 * 30
|
||||||
|
int day = ct / 86400 ;
|
||||||
|
return day + "天前";
|
||||||
|
}
|
||||||
|
if(ct >= 2592000 && ct < 31104000) { //86400 * 30
|
||||||
|
return ct / 2592000 + "月前";
|
||||||
|
}
|
||||||
|
return ct / 31104000 + "年前";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package com.rmondjone.xrecyclerview;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by jianghejie on 15/11/22.
|
||||||
|
*/
|
||||||
|
interface BaseRefreshHeader {
|
||||||
|
|
||||||
|
int STATE_NORMAL = 0;
|
||||||
|
int STATE_RELEASE_TO_REFRESH = 1;
|
||||||
|
int STATE_REFRESHING = 2;
|
||||||
|
int STATE_DONE = 3;
|
||||||
|
|
||||||
|
void onMove(float delta);
|
||||||
|
|
||||||
|
boolean releaseAction();
|
||||||
|
|
||||||
|
void refreshComplete();
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
package com.rmondjone.xrecyclerview;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by jianghejie on 16/6/20.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public interface ItemTouchHelperAdapter {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when an item has been dragged far enough to trigger a move. This is called every time
|
||||||
|
* an item is shifted, and <strong>not</strong> at the end of a "drop" event.<br/>
|
||||||
|
* <br/>
|
||||||
|
* Implementations should call {@link RecyclerView.Adapter#notifyItemMoved(int, int)} after
|
||||||
|
* adjusting the underlying data to reflect this move.
|
||||||
|
*
|
||||||
|
* @param fromPosition The start position of the moved item.
|
||||||
|
* @param toPosition Then resolved position of the moved item.
|
||||||
|
*
|
||||||
|
* @see RecyclerView#getAdapterPositionFor(RecyclerView.ViewHolder)
|
||||||
|
* @see RecyclerView.ViewHolder#getAdapterPosition()
|
||||||
|
*/
|
||||||
|
void onItemMove(int fromPosition, int toPosition);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when an item has been dismissed by a swipe.<br/>
|
||||||
|
* <br/>
|
||||||
|
* Implementations should call {@link RecyclerView.Adapter#notifyItemRemoved(int)} after
|
||||||
|
* adjusting the underlying data to reflect this removal.
|
||||||
|
*
|
||||||
|
* @param position The position of the item dismissed.
|
||||||
|
*
|
||||||
|
* @see RecyclerView#getAdapterPositionFor(RecyclerView.ViewHolder)
|
||||||
|
* @see RecyclerView.ViewHolder#getAdapterPosition()
|
||||||
|
*/
|
||||||
|
void onItemDismiss(int position);
|
||||||
|
}
|
||||||
@@ -0,0 +1,108 @@
|
|||||||
|
package com.rmondjone.xrecyclerview;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by jianghejie on 15/11/22.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import android.annotation.TargetApi;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.graphics.Path;
|
||||||
|
import android.os.Build;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
|
||||||
|
public class JellyView extends View implements BaseRefreshHeader{
|
||||||
|
Path path;
|
||||||
|
|
||||||
|
Paint paint;
|
||||||
|
|
||||||
|
private int minimumHeight = 0;
|
||||||
|
|
||||||
|
private int jellyHeight =0;
|
||||||
|
|
||||||
|
public JellyView(Context context) {
|
||||||
|
super(context);
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
public JellyView(Context context, AttributeSet attrs) {
|
||||||
|
super(context, attrs);
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
public JellyView(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||||
|
super(context, attrs, defStyleAttr);
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
||||||
|
public JellyView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
|
||||||
|
super(context, attrs, defStyleAttr, defStyleRes);
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void init() {
|
||||||
|
if (isInEditMode()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
path = new Path();
|
||||||
|
paint = new Paint();
|
||||||
|
paint.setColor(getContext().getResources().getColor(android.R.color.holo_blue_bright));
|
||||||
|
paint.setAntiAlias(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setJellyColor(int jellyColor) {
|
||||||
|
paint.setColor(jellyColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDraw(Canvas canvas) {
|
||||||
|
super.onDraw(canvas);
|
||||||
|
path.reset();
|
||||||
|
path.lineTo(0, minimumHeight);
|
||||||
|
path.quadTo(getMeasuredWidth() / 2, minimumHeight + jellyHeight, getMeasuredWidth(), minimumHeight);
|
||||||
|
path.lineTo(getMeasuredWidth(), 0);
|
||||||
|
canvas.drawPath(path, paint);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setMinimumHeight(int minimumHeight) {
|
||||||
|
this.minimumHeight = minimumHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setJellyHeight(int ribbonHeight) {
|
||||||
|
this.jellyHeight = ribbonHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMinimumHeight() {
|
||||||
|
return minimumHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getJellyHeight() {
|
||||||
|
return jellyHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void refreshComplete(){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onMove(float delta) {
|
||||||
|
jellyHeight = jellyHeight + (int)delta;
|
||||||
|
Log.i("jellyHeight", "delta = " + delta);
|
||||||
|
this.invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean releaseAction() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,108 @@
|
|||||||
|
package com.rmondjone.xrecyclerview;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.view.Gravity;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.LinearLayout;
|
||||||
|
import android.widget.ProgressBar;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
import com.rmondjone.xrecyclerview.progressindicator.AVLoadingIndicatorView;
|
||||||
|
import com.rmondjone.locktableview.R;
|
||||||
|
|
||||||
|
public class LoadingMoreFooter extends LinearLayout {
|
||||||
|
|
||||||
|
private SimpleViewSwitcher progressCon;
|
||||||
|
public final static int STATE_LOADING = 0;
|
||||||
|
public final static int STATE_COMPLETE = 1;
|
||||||
|
public final static int STATE_NOMORE = 2;
|
||||||
|
private TextView mText;
|
||||||
|
private String loadingHint;
|
||||||
|
private String noMoreHint;
|
||||||
|
private String loadingDoneHint;
|
||||||
|
|
||||||
|
public LoadingMoreFooter(Context context) {
|
||||||
|
super(context);
|
||||||
|
initView();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param context
|
||||||
|
* @param attrs
|
||||||
|
*/
|
||||||
|
public LoadingMoreFooter(Context context, AttributeSet attrs) {
|
||||||
|
super(context, attrs);
|
||||||
|
initView();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLoadingHint(String hint) {
|
||||||
|
loadingHint = hint;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNoMoreHint(String hint) {
|
||||||
|
noMoreHint = hint;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLoadingDoneHint(String hint) {
|
||||||
|
loadingDoneHint = hint;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void initView(){
|
||||||
|
setGravity(Gravity.CENTER);
|
||||||
|
setLayoutParams(new RecyclerView.LayoutParams(
|
||||||
|
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
|
||||||
|
progressCon = new SimpleViewSwitcher(getContext());
|
||||||
|
progressCon.setLayoutParams(new ViewGroup.LayoutParams(
|
||||||
|
ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
|
||||||
|
|
||||||
|
AVLoadingIndicatorView progressView = new AVLoadingIndicatorView(this.getContext());
|
||||||
|
progressView.setIndicatorColor(0xffB5B5B5);
|
||||||
|
progressView.setIndicatorId(ProgressStyle.BallSpinFadeLoader);
|
||||||
|
progressCon.setView(progressView);
|
||||||
|
|
||||||
|
addView(progressCon);
|
||||||
|
mText = new TextView(getContext());
|
||||||
|
mText.setText("正在加载...");
|
||||||
|
loadingHint = (String)getContext().getText(R.string.listview_loading);
|
||||||
|
noMoreHint = (String)getContext().getText(R.string.nomore_loading);
|
||||||
|
loadingDoneHint = (String)getContext().getText(R.string.loading_done);
|
||||||
|
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
|
||||||
|
layoutParams.setMargins( (int)getResources().getDimension(R.dimen.textandiconmargin),0,0,0 );
|
||||||
|
|
||||||
|
mText.setLayoutParams(layoutParams);
|
||||||
|
addView(mText);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setProgressStyle(int style) {
|
||||||
|
if(style == ProgressStyle.SysProgress){
|
||||||
|
progressCon.setView(new ProgressBar(getContext(), null, android.R.attr.progressBarStyle));
|
||||||
|
}else{
|
||||||
|
AVLoadingIndicatorView progressView = new AVLoadingIndicatorView(this.getContext());
|
||||||
|
progressView.setIndicatorColor(0xffB5B5B5);
|
||||||
|
progressView.setIndicatorId(style);
|
||||||
|
progressCon.setView(progressView);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setState(int state) {
|
||||||
|
switch(state) {
|
||||||
|
case STATE_LOADING:
|
||||||
|
progressCon.setVisibility(View.VISIBLE);
|
||||||
|
mText.setText(loadingHint);
|
||||||
|
this.setVisibility(View.VISIBLE);
|
||||||
|
break;
|
||||||
|
case STATE_COMPLETE:
|
||||||
|
mText.setText(loadingDoneHint);
|
||||||
|
this.setVisibility(View.GONE);
|
||||||
|
break;
|
||||||
|
case STATE_NOMORE:
|
||||||
|
mText.setText(noMoreHint);
|
||||||
|
progressCon.setVisibility(View.GONE);
|
||||||
|
this.setVisibility(View.VISIBLE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
package com.rmondjone.xrecyclerview;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by jianghejie on 15/11/23.
|
||||||
|
*/
|
||||||
|
public class ProgressStyle {
|
||||||
|
public static final int SysProgress=-1;
|
||||||
|
public static final int BallPulse=0;
|
||||||
|
public static final int BallGridPulse=1;
|
||||||
|
public static final int BallClipRotate=2;
|
||||||
|
public static final int BallClipRotatePulse=3;
|
||||||
|
public static final int SquareSpin=4;
|
||||||
|
public static final int BallClipRotateMultiple=5;
|
||||||
|
public static final int BallPulseRise=6;
|
||||||
|
public static final int BallRotate=7;
|
||||||
|
public static final int CubeTransition=8;
|
||||||
|
public static final int BallZigZag=9;
|
||||||
|
public static final int BallZigZagDeflect=10;
|
||||||
|
public static final int BallTrianglePath=11;
|
||||||
|
public static final int BallScale=12;
|
||||||
|
public static final int LineScale=13;
|
||||||
|
public static final int LineScaleParty=14;
|
||||||
|
public static final int BallScaleMultiple=15;
|
||||||
|
public static final int BallPulseSync=16;
|
||||||
|
public static final int BallBeat=17;
|
||||||
|
public static final int LineScalePulseOut=18;
|
||||||
|
public static final int LineScalePulseOutRapid=19;
|
||||||
|
public static final int BallScaleRipple=20;
|
||||||
|
public static final int BallScaleRippleMultiple=21;
|
||||||
|
public static final int BallSpinFadeLoader=22;
|
||||||
|
public static final int LineSpinFadeLoader=23;
|
||||||
|
public static final int TriangleSkewSpin=24;
|
||||||
|
public static final int Pacman=25;
|
||||||
|
public static final int BallGridBeat=26;
|
||||||
|
public static final int SemiCircleSpin=27;
|
||||||
|
}
|
||||||
@@ -0,0 +1,88 @@
|
|||||||
|
package com.rmondjone.xrecyclerview;
|
||||||
|
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Color;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
import androidx.recyclerview.widget.ItemTouchHelper;
|
||||||
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by jianghejie on 16/6/20.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class SimpleItemTouchHelperCallback extends ItemTouchHelper.Callback {
|
||||||
|
|
||||||
|
public static final float ALPHA_FULL = 1.0f;
|
||||||
|
|
||||||
|
private final ItemTouchHelperAdapter mAdapter;
|
||||||
|
private XRecyclerView mXrecyclerView;
|
||||||
|
|
||||||
|
public SimpleItemTouchHelperCallback(ItemTouchHelperAdapter adapter, XRecyclerView recyclerView) {
|
||||||
|
mAdapter = adapter;
|
||||||
|
this.mXrecyclerView = recyclerView;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isLongPressDragEnabled() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isItemViewSwipeEnabled() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
|
||||||
|
// Enable drag and swipe in both directions
|
||||||
|
final int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
|
||||||
|
final int swipeFlags = ItemTouchHelper.START | ItemTouchHelper.END;
|
||||||
|
return makeMovementFlags(dragFlags, swipeFlags);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder source, RecyclerView.ViewHolder target) {
|
||||||
|
if (source.getItemViewType() != target.getItemViewType()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// Notify the adapter of the move
|
||||||
|
mAdapter.onItemMove(source.getAdapterPosition(), target.getAdapterPosition());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSwiped(RecyclerView.ViewHolder viewHolder, int i) {
|
||||||
|
// Notify the adapter of the dismissal
|
||||||
|
mAdapter.onItemDismiss(viewHolder.getAdapterPosition());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
|
||||||
|
super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
|
||||||
|
|
||||||
|
// Fade out the view as it is swiped out of the parent's bounds
|
||||||
|
if (actionState == ItemTouchHelper.ACTION_STATE_SWIPE) {
|
||||||
|
View itemView = viewHolder.itemView;
|
||||||
|
final float alpha = ALPHA_FULL - Math.abs(dX) / (float) itemView.getWidth();
|
||||||
|
itemView.setAlpha(alpha);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
|
||||||
|
if (actionState != ItemTouchHelper.ACTION_STATE_IDLE) {
|
||||||
|
// Let the view holder know that this item is being moved or dragged
|
||||||
|
viewHolder.itemView.setBackgroundColor(Color.LTGRAY);
|
||||||
|
}
|
||||||
|
|
||||||
|
super.onSelectedChanged(viewHolder, actionState);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
|
||||||
|
super.clearView(recyclerView, viewHolder);
|
||||||
|
viewHolder.itemView.setAlpha(ALPHA_FULL);
|
||||||
|
viewHolder.itemView.setBackgroundColor(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
package com.rmondjone.xrecyclerview;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by jianghejie on 15/11/22.
|
||||||
|
*/
|
||||||
|
public class SimpleViewSwitcher extends ViewGroup {
|
||||||
|
|
||||||
|
public SimpleViewSwitcher(Context context) {
|
||||||
|
super(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SimpleViewSwitcher(Context context, AttributeSet attrs) {
|
||||||
|
this(context, attrs, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SimpleViewSwitcher(Context context, AttributeSet attrs, int defStyle) {
|
||||||
|
super(context, attrs, defStyle);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||||
|
int childCount = this.getChildCount();
|
||||||
|
int maxHeight = 0;
|
||||||
|
int maxWidth = 0;
|
||||||
|
for (int i = 0; i < childCount; i++) {
|
||||||
|
View child = this.getChildAt(i);
|
||||||
|
this.measureChild(child, widthMeasureSpec, heightMeasureSpec);
|
||||||
|
int cw = child.getMeasuredWidth();
|
||||||
|
// int ch = child.getMeasuredHeight();
|
||||||
|
maxWidth = child.getMeasuredWidth();
|
||||||
|
maxHeight = child.getMeasuredHeight();
|
||||||
|
}
|
||||||
|
setMeasuredDimension(maxWidth, maxHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onLayout(boolean changed, int l, int t, int r, int b) {
|
||||||
|
final int count = getChildCount();
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
final View child = getChildAt(i);
|
||||||
|
if (child.getVisibility() != View.GONE) {
|
||||||
|
child.layout(0, 0, r - l, b - t);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setView(View view) {
|
||||||
|
if (this.getChildCount() != 0){
|
||||||
|
this.removeViewAt(0);
|
||||||
|
}
|
||||||
|
this.addView(view,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,775 @@
|
|||||||
|
package com.rmondjone.xrecyclerview;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Rect;
|
||||||
|
import android.graphics.drawable.Drawable;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.MotionEvent;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.view.ViewParent;
|
||||||
|
|
||||||
|
import androidx.coordinatorlayout.widget.CoordinatorLayout;
|
||||||
|
import androidx.recyclerview.widget.GridLayoutManager;
|
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
import androidx.recyclerview.widget.StaggeredGridLayoutManager;
|
||||||
|
|
||||||
|
import com.google.android.material.appbar.AppBarLayout;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class XRecyclerView extends RecyclerView {
|
||||||
|
private boolean isLoadingData = false;
|
||||||
|
private boolean isNoMore = false;
|
||||||
|
private int mRefreshProgressStyle = ProgressStyle.SysProgress;
|
||||||
|
private int mLoadingMoreProgressStyle = ProgressStyle.SysProgress;
|
||||||
|
private ArrayList<View> mHeaderViews = new ArrayList<>();
|
||||||
|
private WrapAdapter mWrapAdapter;
|
||||||
|
private float mLastY = -1;
|
||||||
|
private static final float DRAG_RATE = 3;
|
||||||
|
private LoadingListener mLoadingListener;
|
||||||
|
private ArrowRefreshHeader mRefreshHeader;
|
||||||
|
private boolean pullRefreshEnabled = true;
|
||||||
|
private boolean loadingMoreEnabled = true;
|
||||||
|
//下面的ItemViewType是保留值(ReservedItemViewType),如果用户的adapter与它们重复将会强制抛出异常。不过为了简化,我们检测到重复时对用户的提示是ItemViewType必须小于10000
|
||||||
|
private static final int TYPE_REFRESH_HEADER = 10000;//设置一个很大的数字,尽可能避免和用户的adapter冲突
|
||||||
|
private static final int TYPE_FOOTER = 10001;
|
||||||
|
private static final int HEADER_INIT_INDEX = 10002;
|
||||||
|
private static List<Integer> sHeaderTypes = new ArrayList<>();//每个header必须有不同的type,不然滚动的时候顺序会变化
|
||||||
|
private int mPageCount = 0;
|
||||||
|
//adapter没有数据的时候显示,类似于listView的emptyView
|
||||||
|
private View mEmptyView;
|
||||||
|
private View mFootView;
|
||||||
|
private final RecyclerView.AdapterDataObserver mDataObserver = new DataObserver();
|
||||||
|
private AppBarStateChangeListener.State appbarState = AppBarStateChangeListener.State.EXPANDED;
|
||||||
|
|
||||||
|
public XRecyclerView(Context context) {
|
||||||
|
this(context, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public XRecyclerView(Context context, AttributeSet attrs) {
|
||||||
|
this(context, attrs, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public XRecyclerView(Context context, AttributeSet attrs, int defStyle) {
|
||||||
|
super(context, attrs, defStyle);
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void init() {
|
||||||
|
if (pullRefreshEnabled) {
|
||||||
|
mRefreshHeader = new ArrowRefreshHeader(getContext());
|
||||||
|
mRefreshHeader.setProgressStyle(mRefreshProgressStyle);
|
||||||
|
}
|
||||||
|
LoadingMoreFooter footView = new LoadingMoreFooter(getContext());
|
||||||
|
footView.setProgressStyle(mLoadingMoreProgressStyle);
|
||||||
|
mFootView = footView;
|
||||||
|
mFootView.setVisibility(GONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFootViewText(String loading, String noMore) {
|
||||||
|
if (mFootView instanceof LoadingMoreFooter) {
|
||||||
|
((LoadingMoreFooter) mFootView).setLoadingHint(loading);
|
||||||
|
((LoadingMoreFooter) mFootView).setNoMoreHint(noMore);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addHeaderView(View view) {
|
||||||
|
sHeaderTypes.add(HEADER_INIT_INDEX + mHeaderViews.size());
|
||||||
|
mHeaderViews.add(view);
|
||||||
|
if (mWrapAdapter != null) {
|
||||||
|
mWrapAdapter.notifyDataSetChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//根据header的ViewType判断是哪个header
|
||||||
|
private View getHeaderViewByType(int itemType) {
|
||||||
|
if (!isHeaderType(itemType)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return mHeaderViews.get(itemType - HEADER_INIT_INDEX);
|
||||||
|
}
|
||||||
|
|
||||||
|
//判断一个type是否为HeaderType
|
||||||
|
private boolean isHeaderType(int itemViewType) {
|
||||||
|
return mHeaderViews.size() > 0 && sHeaderTypes.contains(itemViewType);
|
||||||
|
}
|
||||||
|
|
||||||
|
//判断是否是XRecyclerView保留的itemViewType
|
||||||
|
private boolean isReservedItemViewType(int itemViewType) {
|
||||||
|
if (itemViewType == TYPE_REFRESH_HEADER || itemViewType == TYPE_FOOTER || sHeaderTypes.contains(itemViewType)) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFootView(final View view) {
|
||||||
|
mFootView = view;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void loadMoreComplete() {
|
||||||
|
isLoadingData = false;
|
||||||
|
if (mFootView instanceof LoadingMoreFooter) {
|
||||||
|
((LoadingMoreFooter) mFootView).setState(LoadingMoreFooter.STATE_COMPLETE);
|
||||||
|
} else {
|
||||||
|
mFootView.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNoMore(boolean noMore) {
|
||||||
|
isLoadingData = false;
|
||||||
|
isNoMore = noMore;
|
||||||
|
if (mFootView instanceof LoadingMoreFooter) {
|
||||||
|
((LoadingMoreFooter) mFootView).setState(isNoMore ? LoadingMoreFooter.STATE_NOMORE : LoadingMoreFooter.STATE_COMPLETE);
|
||||||
|
} else {
|
||||||
|
mFootView.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void refresh() {
|
||||||
|
if (pullRefreshEnabled && mLoadingListener != null) {
|
||||||
|
mRefreshHeader.setState(ArrowRefreshHeader.STATE_REFRESHING);
|
||||||
|
mLoadingListener.onRefresh();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reset() {
|
||||||
|
setNoMore(false);
|
||||||
|
loadMoreComplete();
|
||||||
|
refreshComplete();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void refreshComplete() {
|
||||||
|
mRefreshHeader.refreshComplete();
|
||||||
|
setNoMore(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRefreshHeader(ArrowRefreshHeader refreshHeader) {
|
||||||
|
mRefreshHeader = refreshHeader;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPullRefreshEnabled(boolean enabled) {
|
||||||
|
pullRefreshEnabled = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLoadingMoreEnabled(boolean enabled) {
|
||||||
|
loadingMoreEnabled = enabled;
|
||||||
|
if (!enabled) {
|
||||||
|
if (mFootView instanceof LoadingMoreFooter) {
|
||||||
|
((LoadingMoreFooter) mFootView).setState(LoadingMoreFooter.STATE_COMPLETE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRefreshProgressStyle(int style) {
|
||||||
|
mRefreshProgressStyle = style;
|
||||||
|
if (mRefreshHeader != null) {
|
||||||
|
mRefreshHeader.setProgressStyle(style);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLoadingMoreProgressStyle(int style) {
|
||||||
|
mLoadingMoreProgressStyle = style;
|
||||||
|
if (mFootView instanceof LoadingMoreFooter) {
|
||||||
|
((LoadingMoreFooter) mFootView).setProgressStyle(style);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setArrowImageView(int resId) {
|
||||||
|
if (mRefreshHeader != null) {
|
||||||
|
mRefreshHeader.setArrowImageView(resId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEmptyView(View emptyView) {
|
||||||
|
this.mEmptyView = emptyView;
|
||||||
|
mDataObserver.onChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
public View getEmptyView() {
|
||||||
|
return mEmptyView;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setAdapter(Adapter adapter) {
|
||||||
|
mWrapAdapter = new WrapAdapter(adapter);
|
||||||
|
super.setAdapter(mWrapAdapter);
|
||||||
|
adapter.registerAdapterDataObserver(mDataObserver);
|
||||||
|
mDataObserver.onChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
//避免用户自己调用getAdapter() 引起的ClassCastException
|
||||||
|
@Override
|
||||||
|
public Adapter getAdapter() {
|
||||||
|
if (mWrapAdapter != null)
|
||||||
|
return mWrapAdapter.getOriginalAdapter();
|
||||||
|
else
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setLayoutManager(LayoutManager layout) {
|
||||||
|
super.setLayoutManager(layout);
|
||||||
|
if (mWrapAdapter != null) {
|
||||||
|
if (layout instanceof GridLayoutManager) {
|
||||||
|
final GridLayoutManager gridManager = ((GridLayoutManager) layout);
|
||||||
|
gridManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
|
||||||
|
@Override
|
||||||
|
public int getSpanSize(int position) {
|
||||||
|
return (mWrapAdapter.isHeader(position) || mWrapAdapter.isFooter(position) || mWrapAdapter.isRefreshHeader(position))
|
||||||
|
? gridManager.getSpanCount() : 1;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onScrollStateChanged(int state) {
|
||||||
|
super.onScrollStateChanged(state);
|
||||||
|
if (state == RecyclerView.SCROLL_STATE_IDLE && mLoadingListener != null && !isLoadingData && loadingMoreEnabled) {
|
||||||
|
LayoutManager layoutManager = getLayoutManager();
|
||||||
|
int lastVisibleItemPosition;
|
||||||
|
if (layoutManager instanceof GridLayoutManager) {
|
||||||
|
lastVisibleItemPosition = ((GridLayoutManager) layoutManager).findLastVisibleItemPosition();
|
||||||
|
} else if (layoutManager instanceof StaggeredGridLayoutManager) {
|
||||||
|
int[] into = new int[((StaggeredGridLayoutManager) layoutManager).getSpanCount()];
|
||||||
|
((StaggeredGridLayoutManager) layoutManager).findLastVisibleItemPositions(into);
|
||||||
|
lastVisibleItemPosition = findMax(into);
|
||||||
|
} else {
|
||||||
|
lastVisibleItemPosition = ((LinearLayoutManager) layoutManager).findLastVisibleItemPosition();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (layoutManager.getChildCount() > 0
|
||||||
|
&& lastVisibleItemPosition >= layoutManager.getItemCount() - 1
|
||||||
|
//因为我的控件里layoutManager.getItemCount()永远等于1(item),layoutManager.getChildCount()
|
||||||
|
//永远等于2(刷新头和item),所以这个条件永远不成立,永远调不了上拉加载事件,需要注释掉
|
||||||
|
//&& layoutManager.getItemCount() > layoutManager.getChildCount()
|
||||||
|
&& !isNoMore
|
||||||
|
&& mRefreshHeader.getState() < ArrowRefreshHeader.STATE_REFRESHING
|
||||||
|
//只有当更多底部视图显示在页面上才开始进行加载更多数据
|
||||||
|
&&lastVisibleItemPosition>=2) {
|
||||||
|
isLoadingData = true;
|
||||||
|
if (mFootView instanceof LoadingMoreFooter) {
|
||||||
|
((LoadingMoreFooter) mFootView).setState(LoadingMoreFooter.STATE_LOADING);
|
||||||
|
} else {
|
||||||
|
mFootView.setVisibility(View.VISIBLE);
|
||||||
|
}
|
||||||
|
mLoadingListener.onLoadMore();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onTouchEvent(MotionEvent ev) {
|
||||||
|
if (mLastY == -1) {
|
||||||
|
mLastY = ev.getRawY();
|
||||||
|
}
|
||||||
|
switch (ev.getAction()) {
|
||||||
|
case MotionEvent.ACTION_DOWN:
|
||||||
|
mLastY = ev.getRawY();
|
||||||
|
break;
|
||||||
|
case MotionEvent.ACTION_MOVE:
|
||||||
|
final float deltaY = ev.getRawY() - mLastY;
|
||||||
|
mLastY = ev.getRawY();
|
||||||
|
if (isOnTop() && pullRefreshEnabled && appbarState == AppBarStateChangeListener.State.EXPANDED) {
|
||||||
|
mRefreshHeader.onMove(deltaY / DRAG_RATE);
|
||||||
|
if (mRefreshHeader.getVisibleHeight() > 0 && mRefreshHeader.getState() < ArrowRefreshHeader.STATE_REFRESHING) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
mLastY = -1; // reset
|
||||||
|
if (isOnTop() && pullRefreshEnabled && appbarState == AppBarStateChangeListener.State.EXPANDED) {
|
||||||
|
if (mRefreshHeader.releaseAction()) {
|
||||||
|
if (mLoadingListener != null) {
|
||||||
|
mLoadingListener.onRefresh();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return super.onTouchEvent(ev);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int findMax(int[] lastPositions) {
|
||||||
|
int max = lastPositions[0];
|
||||||
|
for (int value : lastPositions) {
|
||||||
|
if (value > max) {
|
||||||
|
max = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return max;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isOnTop() {
|
||||||
|
if (mRefreshHeader.getParent() != null) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class DataObserver extends RecyclerView.AdapterDataObserver {
|
||||||
|
@Override
|
||||||
|
public void onChanged() {
|
||||||
|
if (mWrapAdapter != null) {
|
||||||
|
mWrapAdapter.notifyDataSetChanged();
|
||||||
|
}
|
||||||
|
if (mWrapAdapter != null && mEmptyView != null) {
|
||||||
|
int emptyCount = 1 + mWrapAdapter.getHeadersCount();
|
||||||
|
if (loadingMoreEnabled) {
|
||||||
|
emptyCount++;
|
||||||
|
}
|
||||||
|
if (mWrapAdapter.getItemCount() == emptyCount) {
|
||||||
|
mEmptyView.setVisibility(View.VISIBLE);
|
||||||
|
XRecyclerView.this.setVisibility(View.GONE);
|
||||||
|
} else {
|
||||||
|
|
||||||
|
mEmptyView.setVisibility(View.GONE);
|
||||||
|
XRecyclerView.this.setVisibility(View.VISIBLE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onItemRangeInserted(int positionStart, int itemCount) {
|
||||||
|
mWrapAdapter.notifyItemRangeInserted(positionStart, itemCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onItemRangeChanged(int positionStart, int itemCount) {
|
||||||
|
mWrapAdapter.notifyItemRangeChanged(positionStart, itemCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onItemRangeChanged(int positionStart, int itemCount, Object payload) {
|
||||||
|
mWrapAdapter.notifyItemRangeChanged(positionStart, itemCount, payload);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onItemRangeRemoved(int positionStart, int itemCount) {
|
||||||
|
mWrapAdapter.notifyItemRangeRemoved(positionStart, itemCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) {
|
||||||
|
mWrapAdapter.notifyItemMoved(fromPosition, toPosition);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
;
|
||||||
|
|
||||||
|
private class WrapAdapter extends RecyclerView.Adapter<ViewHolder> {
|
||||||
|
|
||||||
|
private RecyclerView.Adapter adapter;
|
||||||
|
|
||||||
|
public WrapAdapter(RecyclerView.Adapter adapter) {
|
||||||
|
this.adapter = adapter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RecyclerView.Adapter getOriginalAdapter() {
|
||||||
|
return this.adapter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isHeader(int position) {
|
||||||
|
return position >= 1 && position < mHeaderViews.size() + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isFooter(int position) {
|
||||||
|
if (loadingMoreEnabled) {
|
||||||
|
return position == getItemCount() - 1;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isRefreshHeader(int position) {
|
||||||
|
return position == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getHeadersCount() {
|
||||||
|
return mHeaderViews.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||||
|
if (viewType == TYPE_REFRESH_HEADER) {
|
||||||
|
return new SimpleViewHolder(mRefreshHeader);
|
||||||
|
} else if (isHeaderType(viewType)) {
|
||||||
|
return new SimpleViewHolder(getHeaderViewByType(viewType));
|
||||||
|
} else if (viewType == TYPE_FOOTER) {
|
||||||
|
return new SimpleViewHolder(mFootView);
|
||||||
|
}
|
||||||
|
return adapter.onCreateViewHolder(parent, viewType);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
|
||||||
|
if (isHeader(position) || isRefreshHeader(position)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int adjPosition = position - (getHeadersCount() + 1);
|
||||||
|
int adapterCount;
|
||||||
|
if (adapter != null) {
|
||||||
|
adapterCount = adapter.getItemCount();
|
||||||
|
if (adjPosition < adapterCount) {
|
||||||
|
adapter.onBindViewHolder(holder, adjPosition);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// some times we need to override this
|
||||||
|
@Override
|
||||||
|
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position, List<Object> payloads) {
|
||||||
|
if (isHeader(position) || isRefreshHeader(position)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int adjPosition = position - (getHeadersCount() + 1);
|
||||||
|
int adapterCount;
|
||||||
|
if (adapter != null) {
|
||||||
|
adapterCount = adapter.getItemCount();
|
||||||
|
if (adjPosition < adapterCount) {
|
||||||
|
if (payloads.isEmpty()) {
|
||||||
|
adapter.onBindViewHolder(holder, adjPosition);
|
||||||
|
} else {
|
||||||
|
adapter.onBindViewHolder(holder, adjPosition, payloads);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemCount() {
|
||||||
|
if (loadingMoreEnabled) {
|
||||||
|
if (adapter != null) {
|
||||||
|
return getHeadersCount() + adapter.getItemCount() + 2;
|
||||||
|
} else {
|
||||||
|
return getHeadersCount() + 2;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (adapter != null) {
|
||||||
|
return getHeadersCount() + adapter.getItemCount() + 1;
|
||||||
|
} else {
|
||||||
|
return getHeadersCount() + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemViewType(int position) {
|
||||||
|
int adjPosition = position - (getHeadersCount() + 1);
|
||||||
|
if (isRefreshHeader(position)) {
|
||||||
|
return TYPE_REFRESH_HEADER;
|
||||||
|
}
|
||||||
|
if (isHeader(position)) {
|
||||||
|
position = position - 1;
|
||||||
|
return sHeaderTypes.get(position);
|
||||||
|
}
|
||||||
|
if (isFooter(position)) {
|
||||||
|
return TYPE_FOOTER;
|
||||||
|
}
|
||||||
|
int adapterCount;
|
||||||
|
if (adapter != null) {
|
||||||
|
adapterCount = adapter.getItemCount();
|
||||||
|
if (adjPosition < adapterCount) {
|
||||||
|
int type = adapter.getItemViewType(adjPosition);
|
||||||
|
if (isReservedItemViewType(type)) {
|
||||||
|
throw new IllegalStateException("XRecyclerView require itemViewType in adapter should be less than 10000 ");
|
||||||
|
}
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getItemId(int position) {
|
||||||
|
if (adapter != null && position >= getHeadersCount() + 1) {
|
||||||
|
int adjPosition = position - (getHeadersCount() + 1);
|
||||||
|
if (adjPosition < adapter.getItemCount()) {
|
||||||
|
return adapter.getItemId(adjPosition);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
|
||||||
|
super.onAttachedToRecyclerView(recyclerView);
|
||||||
|
RecyclerView.LayoutManager manager = recyclerView.getLayoutManager();
|
||||||
|
if (manager instanceof GridLayoutManager) {
|
||||||
|
final GridLayoutManager gridManager = ((GridLayoutManager) manager);
|
||||||
|
gridManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
|
||||||
|
@Override
|
||||||
|
public int getSpanSize(int position) {
|
||||||
|
return (isHeader(position) || isFooter(position) || isRefreshHeader(position))
|
||||||
|
? gridManager.getSpanCount() : 1;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
adapter.onAttachedToRecyclerView(recyclerView);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDetachedFromRecyclerView(RecyclerView recyclerView) {
|
||||||
|
adapter.onDetachedFromRecyclerView(recyclerView);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onViewAttachedToWindow(RecyclerView.ViewHolder holder) {
|
||||||
|
super.onViewAttachedToWindow(holder);
|
||||||
|
ViewGroup.LayoutParams lp = holder.itemView.getLayoutParams();
|
||||||
|
if (lp != null
|
||||||
|
&& lp instanceof StaggeredGridLayoutManager.LayoutParams
|
||||||
|
&& (isHeader(holder.getLayoutPosition()) || isRefreshHeader(holder.getLayoutPosition()) || isFooter(holder.getLayoutPosition()))) {
|
||||||
|
StaggeredGridLayoutManager.LayoutParams p = (StaggeredGridLayoutManager.LayoutParams) lp;
|
||||||
|
p.setFullSpan(true);
|
||||||
|
}
|
||||||
|
adapter.onViewAttachedToWindow(holder);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onViewDetachedFromWindow(RecyclerView.ViewHolder holder) {
|
||||||
|
adapter.onViewDetachedFromWindow(holder);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onViewRecycled(RecyclerView.ViewHolder holder) {
|
||||||
|
adapter.onViewRecycled(holder);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onFailedToRecycleView(RecyclerView.ViewHolder holder) {
|
||||||
|
return adapter.onFailedToRecycleView(holder);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void unregisterAdapterDataObserver(AdapterDataObserver observer) {
|
||||||
|
adapter.unregisterAdapterDataObserver(observer);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void registerAdapterDataObserver(AdapterDataObserver observer) {
|
||||||
|
adapter.registerAdapterDataObserver(observer);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class SimpleViewHolder extends RecyclerView.ViewHolder {
|
||||||
|
public SimpleViewHolder(View itemView) {
|
||||||
|
super(itemView);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLoadingListener(LoadingListener listener) {
|
||||||
|
mLoadingListener = listener;
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface LoadingListener {
|
||||||
|
|
||||||
|
void onRefresh();
|
||||||
|
|
||||||
|
void onLoadMore();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onAttachedToWindow() {
|
||||||
|
super.onAttachedToWindow();
|
||||||
|
//解决和CollapsingToolbarLayout冲突的问题
|
||||||
|
AppBarLayout appBarLayout = null;
|
||||||
|
ViewParent p = getParent();
|
||||||
|
while (p != null) {
|
||||||
|
if (p instanceof CoordinatorLayout) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
p = p.getParent();
|
||||||
|
}
|
||||||
|
if (p instanceof CoordinatorLayout) {
|
||||||
|
CoordinatorLayout coordinatorLayout = (CoordinatorLayout) p;
|
||||||
|
final int childCount = coordinatorLayout.getChildCount();
|
||||||
|
for (int i = childCount - 1; i >= 0; i--) {
|
||||||
|
final View child = coordinatorLayout.getChildAt(i);
|
||||||
|
if (child instanceof AppBarLayout) {
|
||||||
|
appBarLayout = (AppBarLayout) child;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (appBarLayout != null) {
|
||||||
|
appBarLayout.addOnOffsetChangedListener(new AppBarStateChangeListener() {
|
||||||
|
@Override
|
||||||
|
public void onStateChanged(AppBarLayout appBarLayout, State state) {
|
||||||
|
appbarState = state;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class DividerItemDecoration extends RecyclerView.ItemDecoration {
|
||||||
|
|
||||||
|
private Drawable mDivider;
|
||||||
|
private int mOrientation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sole constructor. Takes in a {@link Drawable} to be used as the interior
|
||||||
|
* divider.
|
||||||
|
*
|
||||||
|
* @param divider A divider {@code Drawable} to be drawn on the RecyclerView
|
||||||
|
*/
|
||||||
|
public DividerItemDecoration(Drawable divider) {
|
||||||
|
mDivider = divider;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Draws horizontal or vertical dividers onto the parent RecyclerView.
|
||||||
|
*
|
||||||
|
* @param canvas The {@link Canvas} onto which dividers will be drawn
|
||||||
|
* @param parent The RecyclerView onto which dividers are being added
|
||||||
|
* @param state The current RecyclerView.State of the RecyclerView
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void onDraw(Canvas canvas, RecyclerView parent, RecyclerView.State state) {
|
||||||
|
if (mOrientation == LinearLayoutManager.HORIZONTAL) {
|
||||||
|
drawHorizontalDividers(canvas, parent);
|
||||||
|
} else if (mOrientation == LinearLayoutManager.VERTICAL) {
|
||||||
|
drawVerticalDividers(canvas, parent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines the size and location of offsets between items in the parent
|
||||||
|
* RecyclerView.
|
||||||
|
*
|
||||||
|
* @param outRect The {@link Rect} of offsets to be added around the child
|
||||||
|
* view
|
||||||
|
* @param view The child view to be decorated with an offset
|
||||||
|
* @param parent The RecyclerView onto which dividers are being added
|
||||||
|
* @param state The current RecyclerView.State of the RecyclerView
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
|
||||||
|
super.getItemOffsets(outRect, view, parent, state);
|
||||||
|
|
||||||
|
if (parent.getChildAdapterPosition(view) <= mWrapAdapter.getHeadersCount() + 1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mOrientation = ((LinearLayoutManager) parent.getLayoutManager()).getOrientation();
|
||||||
|
if (mOrientation == LinearLayoutManager.HORIZONTAL) {
|
||||||
|
outRect.left = mDivider.getIntrinsicWidth();
|
||||||
|
} else if (mOrientation == LinearLayoutManager.VERTICAL) {
|
||||||
|
outRect.top = mDivider.getIntrinsicHeight();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds dividers to a RecyclerView with a LinearLayoutManager or its
|
||||||
|
* subclass oriented horizontally.
|
||||||
|
*
|
||||||
|
* @param canvas The {@link Canvas} onto which horizontal dividers will be
|
||||||
|
* drawn
|
||||||
|
* @param parent The RecyclerView onto which horizontal dividers are being
|
||||||
|
* added
|
||||||
|
*/
|
||||||
|
private void drawHorizontalDividers(Canvas canvas, RecyclerView parent) {
|
||||||
|
int parentTop = parent.getPaddingTop();
|
||||||
|
int parentBottom = parent.getHeight() - parent.getPaddingBottom();
|
||||||
|
|
||||||
|
int childCount = parent.getChildCount();
|
||||||
|
for (int i = 0; i < childCount - 1; i++) {
|
||||||
|
View child = parent.getChildAt(i);
|
||||||
|
|
||||||
|
RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
|
||||||
|
|
||||||
|
int parentLeft = child.getRight() + params.rightMargin;
|
||||||
|
int parentRight = parentLeft + mDivider.getIntrinsicWidth();
|
||||||
|
|
||||||
|
mDivider.setBounds(parentLeft, parentTop, parentRight, parentBottom);
|
||||||
|
mDivider.draw(canvas);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds dividers to a RecyclerView with a LinearLayoutManager or its
|
||||||
|
* subclass oriented vertically.
|
||||||
|
*
|
||||||
|
* @param canvas The {@link Canvas} onto which vertical dividers will be
|
||||||
|
* drawn
|
||||||
|
* @param parent The RecyclerView onto which vertical dividers are being
|
||||||
|
* added
|
||||||
|
*/
|
||||||
|
private void drawVerticalDividers(Canvas canvas, RecyclerView parent) {
|
||||||
|
int parentLeft = parent.getPaddingLeft();
|
||||||
|
int parentRight = parent.getWidth() - parent.getPaddingRight();
|
||||||
|
|
||||||
|
int childCount = parent.getChildCount();
|
||||||
|
for (int i = 0; i < childCount - 1; i++) {
|
||||||
|
View child = parent.getChildAt(i);
|
||||||
|
|
||||||
|
RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
|
||||||
|
|
||||||
|
int parentTop = child.getBottom() + params.bottomMargin;
|
||||||
|
int parentBottom = parentTop + mDivider.getIntrinsicHeight();
|
||||||
|
|
||||||
|
mDivider.setBounds(parentLeft, parentTop, parentRight, parentBottom);
|
||||||
|
mDivider.draw(canvas);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* add by LinGuanHong below
|
||||||
|
*/
|
||||||
|
private int scrollDyCounter = 0;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void scrollToPosition(int position) {
|
||||||
|
super.scrollToPosition(position);
|
||||||
|
/** if we scroll to position 0, the scrollDyCounter should be reset */
|
||||||
|
if (position == 0) {
|
||||||
|
scrollDyCounter = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onScrolled(int dx, int dy) {
|
||||||
|
super.onScrolled(dx, dy);
|
||||||
|
if (scrollAlphaChangeListener == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int height = scrollAlphaChangeListener.setLimitHeight();
|
||||||
|
scrollDyCounter = scrollDyCounter + dy;
|
||||||
|
if (scrollDyCounter <= 0) {
|
||||||
|
scrollAlphaChangeListener.onAlphaChange(0);
|
||||||
|
} else if (scrollDyCounter <= height && scrollDyCounter > 0) {
|
||||||
|
float scale = (float) scrollDyCounter / height; /** 255/height = x/255 */
|
||||||
|
float alpha = (255 * scale);
|
||||||
|
scrollAlphaChangeListener.onAlphaChange((int) alpha);
|
||||||
|
} else {
|
||||||
|
scrollAlphaChangeListener.onAlphaChange(255);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private ScrollAlphaChangeListener scrollAlphaChangeListener;
|
||||||
|
|
||||||
|
public void setScrollAlphaChangeListener(
|
||||||
|
ScrollAlphaChangeListener scrollAlphaChangeListener
|
||||||
|
) {
|
||||||
|
this.scrollAlphaChangeListener = scrollAlphaChangeListener;
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface ScrollAlphaChangeListener {
|
||||||
|
void onAlphaChange(int alpha);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* you can handle the alpha insert it
|
||||||
|
*/
|
||||||
|
int setLimitHeight(); /** set a height for the begging of the alpha start to change */
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,365 @@
|
|||||||
|
package com.rmondjone.xrecyclerview.progressindicator;
|
||||||
|
|
||||||
|
import android.annotation.TargetApi;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.res.TypedArray;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Color;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.os.Build;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
import androidx.annotation.IntDef;
|
||||||
|
import com.rmondjone.xrecyclerview.progressindicator.indicator.BallBeatIndicator;
|
||||||
|
import com.rmondjone.xrecyclerview.progressindicator.indicator.BallClipRotateIndicator;
|
||||||
|
import com.rmondjone.xrecyclerview.progressindicator.indicator.BallClipRotateMultipleIndicator;
|
||||||
|
import com.rmondjone.xrecyclerview.progressindicator.indicator.BallClipRotatePulseIndicator;
|
||||||
|
import com.rmondjone.xrecyclerview.progressindicator.indicator.BallGridBeatIndicator;
|
||||||
|
import com.rmondjone.xrecyclerview.progressindicator.indicator.BallGridPulseIndicator;
|
||||||
|
import com.rmondjone.xrecyclerview.progressindicator.indicator.BallPulseIndicator;
|
||||||
|
import com.rmondjone.xrecyclerview.progressindicator.indicator.BallPulseRiseIndicator;
|
||||||
|
import com.rmondjone.xrecyclerview.progressindicator.indicator.BallPulseSyncIndicator;
|
||||||
|
import com.rmondjone.xrecyclerview.progressindicator.indicator.BallRotateIndicator;
|
||||||
|
import com.rmondjone.xrecyclerview.progressindicator.indicator.BallScaleIndicator;
|
||||||
|
import com.rmondjone.xrecyclerview.progressindicator.indicator.BallScaleMultipleIndicator;
|
||||||
|
import com.rmondjone.xrecyclerview.progressindicator.indicator.BallScaleRippleIndicator;
|
||||||
|
import com.rmondjone.xrecyclerview.progressindicator.indicator.BallScaleRippleMultipleIndicator;
|
||||||
|
import com.rmondjone.xrecyclerview.progressindicator.indicator.BallSpinFadeLoaderIndicator;
|
||||||
|
import com.rmondjone.xrecyclerview.progressindicator.indicator.BallTrianglePathIndicator;
|
||||||
|
import com.rmondjone.xrecyclerview.progressindicator.indicator.BallZigZagDeflectIndicator;
|
||||||
|
import com.rmondjone.xrecyclerview.progressindicator.indicator.BallZigZagIndicator;
|
||||||
|
import com.rmondjone.xrecyclerview.progressindicator.indicator.BaseIndicatorController;
|
||||||
|
import com.rmondjone.xrecyclerview.progressindicator.indicator.CubeTransitionIndicator;
|
||||||
|
import com.rmondjone.xrecyclerview.progressindicator.indicator.LineScaleIndicator;
|
||||||
|
import com.rmondjone.xrecyclerview.progressindicator.indicator.LineScalePartyIndicator;
|
||||||
|
import com.rmondjone.xrecyclerview.progressindicator.indicator.LineScalePulseOutIndicator;
|
||||||
|
import com.rmondjone.xrecyclerview.progressindicator.indicator.LineScalePulseOutRapidIndicator;
|
||||||
|
import com.rmondjone.xrecyclerview.progressindicator.indicator.LineSpinFadeLoaderIndicator;
|
||||||
|
import com.rmondjone.xrecyclerview.progressindicator.indicator.PacmanIndicator;
|
||||||
|
import com.rmondjone.xrecyclerview.progressindicator.indicator.SemiCircleSpinIndicator;
|
||||||
|
import com.rmondjone.xrecyclerview.progressindicator.indicator.SquareSpinIndicator;
|
||||||
|
import com.rmondjone.xrecyclerview.progressindicator.indicator.TriangleSkewSpinIndicator;
|
||||||
|
import com.rmondjone.locktableview.R;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Jack on 2015/10/15
|
||||||
|
*
|
||||||
|
.BallPulse,
|
||||||
|
.BallGridPulse,
|
||||||
|
.BallClipRotate,
|
||||||
|
.BallClipRotatePulse,
|
||||||
|
.SquareSpin,
|
||||||
|
.BallClipRotateMultiple,
|
||||||
|
.BallPulseRise,
|
||||||
|
.BallRotate,
|
||||||
|
.CubeTransition,
|
||||||
|
.BallZigZag,
|
||||||
|
.BallZigZagDeflect,
|
||||||
|
.BallTrianglePath,
|
||||||
|
.BallScale,
|
||||||
|
.LineScale,
|
||||||
|
.LineScaleParty,
|
||||||
|
.BallScaleMultiple,
|
||||||
|
.BallPulseSync,
|
||||||
|
.BallBeat,
|
||||||
|
.LineScalePulseOut,
|
||||||
|
.LineScalePulseOutRapid,
|
||||||
|
.BallScaleRipple,
|
||||||
|
.BallScaleRippleMultiple,
|
||||||
|
.BallSpinFadeLoader,
|
||||||
|
.LineSpinFadeLoader,
|
||||||
|
.TriangleSkewSpin,
|
||||||
|
.Pacman,
|
||||||
|
.BallGridBeat,
|
||||||
|
.SemiCircleSpin
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class AVLoadingIndicatorView extends View{
|
||||||
|
//indicators
|
||||||
|
public static final int BallPulse=0;
|
||||||
|
public static final int BallGridPulse=1;
|
||||||
|
public static final int BallClipRotate=2;
|
||||||
|
public static final int BallClipRotatePulse=3;
|
||||||
|
public static final int SquareSpin=4;
|
||||||
|
public static final int BallClipRotateMultiple=5;
|
||||||
|
public static final int BallPulseRise=6;
|
||||||
|
public static final int BallRotate=7;
|
||||||
|
public static final int CubeTransition=8;
|
||||||
|
public static final int BallZigZag=9;
|
||||||
|
public static final int BallZigZagDeflect=10;
|
||||||
|
public static final int BallTrianglePath=11;
|
||||||
|
public static final int BallScale=12;
|
||||||
|
public static final int LineScale=13;
|
||||||
|
public static final int LineScaleParty=14;
|
||||||
|
public static final int BallScaleMultiple=15;
|
||||||
|
public static final int BallPulseSync=16;
|
||||||
|
public static final int BallBeat=17;
|
||||||
|
public static final int LineScalePulseOut=18;
|
||||||
|
public static final int LineScalePulseOutRapid=19;
|
||||||
|
public static final int BallScaleRipple=20;
|
||||||
|
public static final int BallScaleRippleMultiple=21;
|
||||||
|
public static final int BallSpinFadeLoader=22;
|
||||||
|
public static final int LineSpinFadeLoader=23;
|
||||||
|
public static final int TriangleSkewSpin=24;
|
||||||
|
public static final int Pacman=25;
|
||||||
|
public static final int BallGridBeat=26;
|
||||||
|
public static final int SemiCircleSpin=27;
|
||||||
|
|
||||||
|
|
||||||
|
@IntDef(flag = true,
|
||||||
|
value = {
|
||||||
|
BallPulse,
|
||||||
|
BallGridPulse,
|
||||||
|
BallClipRotate,
|
||||||
|
BallClipRotatePulse,
|
||||||
|
SquareSpin,
|
||||||
|
BallClipRotateMultiple,
|
||||||
|
BallPulseRise,
|
||||||
|
BallRotate,
|
||||||
|
CubeTransition,
|
||||||
|
BallZigZag,
|
||||||
|
BallZigZagDeflect,
|
||||||
|
BallTrianglePath,
|
||||||
|
BallScale,
|
||||||
|
LineScale,
|
||||||
|
LineScaleParty,
|
||||||
|
BallScaleMultiple,
|
||||||
|
BallPulseSync,
|
||||||
|
BallBeat,
|
||||||
|
LineScalePulseOut,
|
||||||
|
LineScalePulseOutRapid,
|
||||||
|
BallScaleRipple,
|
||||||
|
BallScaleRippleMultiple,
|
||||||
|
BallSpinFadeLoader,
|
||||||
|
LineSpinFadeLoader,
|
||||||
|
TriangleSkewSpin,
|
||||||
|
Pacman,
|
||||||
|
BallGridBeat,
|
||||||
|
SemiCircleSpin
|
||||||
|
})
|
||||||
|
public @interface Indicator{}
|
||||||
|
|
||||||
|
//Sizes (with defaults in DP)
|
||||||
|
public static final int DEFAULT_SIZE=30;
|
||||||
|
|
||||||
|
//attrs
|
||||||
|
int mIndicatorId;
|
||||||
|
int mIndicatorColor;
|
||||||
|
|
||||||
|
Paint mPaint;
|
||||||
|
|
||||||
|
BaseIndicatorController mIndicatorController;
|
||||||
|
|
||||||
|
private boolean mHasAnimation;
|
||||||
|
|
||||||
|
public AVLoadingIndicatorView(Context context) {
|
||||||
|
super(context);
|
||||||
|
init(null, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public AVLoadingIndicatorView(Context context, AttributeSet attrs) {
|
||||||
|
super(context, attrs);
|
||||||
|
init(attrs, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public AVLoadingIndicatorView(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||||
|
super(context, attrs, defStyleAttr);
|
||||||
|
init(attrs, defStyleAttr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
||||||
|
public AVLoadingIndicatorView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
|
||||||
|
super(context, attrs, defStyleAttr, defStyleRes);
|
||||||
|
init(attrs, defStyleAttr);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void init(AttributeSet attrs, int defStyle) {
|
||||||
|
TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.AVLoadingIndicatorView);
|
||||||
|
mIndicatorId=a.getInt(R.styleable.AVLoadingIndicatorView_indicator, BallPulse);
|
||||||
|
mIndicatorColor=a.getColor(R.styleable.AVLoadingIndicatorView_indicator_color, Color.WHITE);
|
||||||
|
a.recycle();
|
||||||
|
mPaint=new Paint();
|
||||||
|
mPaint.setColor(mIndicatorColor);
|
||||||
|
mPaint.setStyle(Paint.Style.FILL);
|
||||||
|
mPaint.setAntiAlias(true);
|
||||||
|
applyIndicator();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIndicatorId(int indicatorId){
|
||||||
|
mIndicatorId = indicatorId;
|
||||||
|
applyIndicator();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIndicatorColor(int color){
|
||||||
|
mIndicatorColor = color;
|
||||||
|
mPaint.setColor(mIndicatorColor);
|
||||||
|
this.invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void applyIndicator(){
|
||||||
|
switch (mIndicatorId){
|
||||||
|
case BallPulse:
|
||||||
|
mIndicatorController=new BallPulseIndicator();
|
||||||
|
break;
|
||||||
|
case BallGridPulse:
|
||||||
|
mIndicatorController=new BallGridPulseIndicator();
|
||||||
|
break;
|
||||||
|
case BallClipRotate:
|
||||||
|
mIndicatorController=new BallClipRotateIndicator();
|
||||||
|
break;
|
||||||
|
case BallClipRotatePulse:
|
||||||
|
mIndicatorController=new BallClipRotatePulseIndicator();
|
||||||
|
break;
|
||||||
|
case SquareSpin:
|
||||||
|
mIndicatorController=new SquareSpinIndicator();
|
||||||
|
break;
|
||||||
|
case BallClipRotateMultiple:
|
||||||
|
mIndicatorController=new BallClipRotateMultipleIndicator();
|
||||||
|
break;
|
||||||
|
case BallPulseRise:
|
||||||
|
mIndicatorController=new BallPulseRiseIndicator();
|
||||||
|
break;
|
||||||
|
case BallRotate:
|
||||||
|
mIndicatorController=new BallRotateIndicator();
|
||||||
|
break;
|
||||||
|
case CubeTransition:
|
||||||
|
mIndicatorController=new CubeTransitionIndicator();
|
||||||
|
break;
|
||||||
|
case BallZigZag:
|
||||||
|
mIndicatorController=new BallZigZagIndicator();
|
||||||
|
break;
|
||||||
|
case BallZigZagDeflect:
|
||||||
|
mIndicatorController=new BallZigZagDeflectIndicator();
|
||||||
|
break;
|
||||||
|
case BallTrianglePath:
|
||||||
|
mIndicatorController=new BallTrianglePathIndicator();
|
||||||
|
break;
|
||||||
|
case BallScale:
|
||||||
|
mIndicatorController=new BallScaleIndicator();
|
||||||
|
break;
|
||||||
|
case LineScale:
|
||||||
|
mIndicatorController=new LineScaleIndicator();
|
||||||
|
break;
|
||||||
|
case LineScaleParty:
|
||||||
|
mIndicatorController=new LineScalePartyIndicator();
|
||||||
|
break;
|
||||||
|
case BallScaleMultiple:
|
||||||
|
mIndicatorController=new BallScaleMultipleIndicator();
|
||||||
|
break;
|
||||||
|
case BallPulseSync:
|
||||||
|
mIndicatorController=new BallPulseSyncIndicator();
|
||||||
|
break;
|
||||||
|
case BallBeat:
|
||||||
|
mIndicatorController=new BallBeatIndicator();
|
||||||
|
break;
|
||||||
|
case LineScalePulseOut:
|
||||||
|
mIndicatorController=new LineScalePulseOutIndicator();
|
||||||
|
break;
|
||||||
|
case LineScalePulseOutRapid:
|
||||||
|
mIndicatorController=new LineScalePulseOutRapidIndicator();
|
||||||
|
break;
|
||||||
|
case BallScaleRipple:
|
||||||
|
mIndicatorController=new BallScaleRippleIndicator();
|
||||||
|
break;
|
||||||
|
case BallScaleRippleMultiple:
|
||||||
|
mIndicatorController=new BallScaleRippleMultipleIndicator();
|
||||||
|
break;
|
||||||
|
case BallSpinFadeLoader:
|
||||||
|
mIndicatorController=new BallSpinFadeLoaderIndicator();
|
||||||
|
break;
|
||||||
|
case LineSpinFadeLoader:
|
||||||
|
mIndicatorController=new LineSpinFadeLoaderIndicator();
|
||||||
|
break;
|
||||||
|
case TriangleSkewSpin:
|
||||||
|
mIndicatorController=new TriangleSkewSpinIndicator();
|
||||||
|
break;
|
||||||
|
case Pacman:
|
||||||
|
mIndicatorController=new PacmanIndicator();
|
||||||
|
break;
|
||||||
|
case BallGridBeat:
|
||||||
|
mIndicatorController=new BallGridBeatIndicator();
|
||||||
|
break;
|
||||||
|
case SemiCircleSpin:
|
||||||
|
mIndicatorController=new SemiCircleSpinIndicator();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
mIndicatorController.setTarget(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||||
|
int width = measureDimension(dp2px(DEFAULT_SIZE), widthMeasureSpec);
|
||||||
|
int height = measureDimension(dp2px(DEFAULT_SIZE), heightMeasureSpec);
|
||||||
|
setMeasuredDimension(width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int measureDimension(int defaultSize,int measureSpec){
|
||||||
|
int result = defaultSize;
|
||||||
|
int specMode = MeasureSpec.getMode(measureSpec);
|
||||||
|
int specSize = MeasureSpec.getSize(measureSpec);
|
||||||
|
if (specMode == MeasureSpec.EXACTLY) {
|
||||||
|
result = specSize;
|
||||||
|
} else if (specMode == MeasureSpec.AT_MOST) {
|
||||||
|
result = Math.min(defaultSize, specSize);
|
||||||
|
} else {
|
||||||
|
result = defaultSize;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDraw(Canvas canvas) {
|
||||||
|
super.onDraw(canvas);
|
||||||
|
drawIndicator(canvas);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
|
||||||
|
super.onLayout(changed, left, top, right, bottom);
|
||||||
|
if (!mHasAnimation){
|
||||||
|
mHasAnimation=true;
|
||||||
|
applyAnimation();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setVisibility(int v) {
|
||||||
|
if (getVisibility() != v) {
|
||||||
|
super.setVisibility(v);
|
||||||
|
if (v == GONE || v == INVISIBLE) {
|
||||||
|
mIndicatorController.setAnimationStatus(BaseIndicatorController.AnimStatus.END);
|
||||||
|
} else {
|
||||||
|
mIndicatorController.setAnimationStatus(BaseIndicatorController.AnimStatus.START);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDetachedFromWindow() {
|
||||||
|
super.onDetachedFromWindow();
|
||||||
|
mIndicatorController.setAnimationStatus(BaseIndicatorController.AnimStatus.CANCEL);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onAttachedToWindow() {
|
||||||
|
super.onAttachedToWindow();
|
||||||
|
mIndicatorController.setAnimationStatus(BaseIndicatorController.AnimStatus.START);
|
||||||
|
}
|
||||||
|
|
||||||
|
void drawIndicator(Canvas canvas){
|
||||||
|
mIndicatorController.draw(canvas, mPaint);
|
||||||
|
}
|
||||||
|
|
||||||
|
void applyAnimation(){
|
||||||
|
mIndicatorController.initAnimation();
|
||||||
|
}
|
||||||
|
|
||||||
|
private int dp2px(int dpValue) {
|
||||||
|
return (int) getContext().getResources().getDisplayMetrics().density * dpValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
package com.rmondjone.xrecyclerview.progressindicator.indicator;
|
||||||
|
|
||||||
|
import android.animation.Animator;
|
||||||
|
import android.animation.ValueAnimator;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Jack on 2015/10/19.
|
||||||
|
*/
|
||||||
|
public class BallBeatIndicator extends com.rmondjone.xrecyclerview.progressindicator.indicator.BaseIndicatorController {
|
||||||
|
|
||||||
|
public static final float SCALE=1.0f;
|
||||||
|
|
||||||
|
public static final int ALPHA=255;
|
||||||
|
|
||||||
|
private float[] scaleFloats=new float[]{SCALE,
|
||||||
|
SCALE,
|
||||||
|
SCALE};
|
||||||
|
|
||||||
|
int[] alphas=new int[]{ALPHA,
|
||||||
|
ALPHA,
|
||||||
|
ALPHA,};
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(Canvas canvas, Paint paint) {
|
||||||
|
float circleSpacing=4;
|
||||||
|
float radius=(getWidth()-circleSpacing*2)/6;
|
||||||
|
float x = getWidth()/ 2-(radius*2+circleSpacing);
|
||||||
|
float y=getHeight() / 2;
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
canvas.save();
|
||||||
|
float translateX=x+(radius*2)*i+circleSpacing*i;
|
||||||
|
canvas.translate(translateX, y);
|
||||||
|
canvas.scale(scaleFloats[i], scaleFloats[i]);
|
||||||
|
paint.setAlpha(alphas[i]);
|
||||||
|
canvas.drawCircle(0, 0, radius, paint);
|
||||||
|
canvas.restore();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Animator> createAnimation() {
|
||||||
|
List<Animator> animators=new ArrayList<>();
|
||||||
|
int[] delays=new int[]{350,0,350};
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
final int index=i;
|
||||||
|
ValueAnimator scaleAnim=ValueAnimator.ofFloat(1,0.75f,1);
|
||||||
|
scaleAnim.setDuration(700);
|
||||||
|
scaleAnim.setRepeatCount(-1);
|
||||||
|
scaleAnim.setStartDelay(delays[i]);
|
||||||
|
scaleAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
||||||
|
@Override
|
||||||
|
public void onAnimationUpdate(ValueAnimator animation) {
|
||||||
|
scaleFloats[index] = (float) animation.getAnimatedValue();
|
||||||
|
postInvalidate();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
scaleAnim.start();
|
||||||
|
|
||||||
|
ValueAnimator alphaAnim=ValueAnimator.ofInt(255,51,255);
|
||||||
|
alphaAnim.setDuration(700);
|
||||||
|
alphaAnim.setRepeatCount(-1);
|
||||||
|
alphaAnim.setStartDelay(delays[i]);
|
||||||
|
alphaAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
||||||
|
@Override
|
||||||
|
public void onAnimationUpdate(ValueAnimator animation) {
|
||||||
|
alphas[index] = (int) animation.getAnimatedValue();
|
||||||
|
postInvalidate();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
alphaAnim.start();
|
||||||
|
animators.add(scaleAnim);
|
||||||
|
animators.add(alphaAnim);
|
||||||
|
}
|
||||||
|
return animators;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
package com.rmondjone.xrecyclerview.progressindicator.indicator;
|
||||||
|
|
||||||
|
import android.animation.Animator;
|
||||||
|
import android.animation.ValueAnimator;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.graphics.RectF;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Jack on 2015/10/16.
|
||||||
|
*/
|
||||||
|
public class BallClipRotateIndicator extends BaseIndicatorController {
|
||||||
|
|
||||||
|
float scaleFloat=1,degrees;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(Canvas canvas, Paint paint) {
|
||||||
|
paint.setStyle(Paint.Style.STROKE);
|
||||||
|
paint.setStrokeWidth(3);
|
||||||
|
|
||||||
|
float circleSpacing=12;
|
||||||
|
float x = (getWidth()) / 2;
|
||||||
|
float y=(getHeight()) / 2;
|
||||||
|
canvas.translate(x, y);
|
||||||
|
canvas.scale(scaleFloat, scaleFloat);
|
||||||
|
canvas.rotate(degrees);
|
||||||
|
RectF rectF=new RectF(-x+circleSpacing,-y+circleSpacing,0+x-circleSpacing,0+y-circleSpacing);
|
||||||
|
canvas.drawArc(rectF, -45, 270, false, paint);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Animator> createAnimation() {
|
||||||
|
List<Animator> animators=new ArrayList<>();
|
||||||
|
ValueAnimator scaleAnim=ValueAnimator.ofFloat(1,0.6f,0.5f,1);
|
||||||
|
scaleAnim.setDuration(750);
|
||||||
|
scaleAnim.setRepeatCount(-1);
|
||||||
|
scaleAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
||||||
|
@Override
|
||||||
|
public void onAnimationUpdate(ValueAnimator animation) {
|
||||||
|
scaleFloat = (float) animation.getAnimatedValue();
|
||||||
|
postInvalidate();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
scaleAnim.start();
|
||||||
|
|
||||||
|
ValueAnimator rotateAnim=ValueAnimator.ofFloat(0,180,360);
|
||||||
|
rotateAnim.setDuration(750);
|
||||||
|
rotateAnim.setRepeatCount(-1);
|
||||||
|
rotateAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
||||||
|
@Override
|
||||||
|
public void onAnimationUpdate(ValueAnimator animation) {
|
||||||
|
degrees = (float) animation.getAnimatedValue();
|
||||||
|
postInvalidate();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
rotateAnim.start();
|
||||||
|
animators.add(scaleAnim);
|
||||||
|
animators.add(rotateAnim);
|
||||||
|
return animators;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,85 @@
|
|||||||
|
package com.rmondjone.xrecyclerview.progressindicator.indicator;
|
||||||
|
|
||||||
|
import android.animation.Animator;
|
||||||
|
import android.animation.ValueAnimator;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.graphics.RectF;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Jack on 2015/10/17.
|
||||||
|
*/
|
||||||
|
public class BallClipRotateMultipleIndicator extends BaseIndicatorController{
|
||||||
|
|
||||||
|
float scaleFloat=1,degrees;
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(Canvas canvas, Paint paint) {
|
||||||
|
paint.setStrokeWidth(3);
|
||||||
|
paint.setStyle(Paint.Style.STROKE);
|
||||||
|
|
||||||
|
float circleSpacing=12;
|
||||||
|
float x=getWidth()/2;
|
||||||
|
float y=getHeight()/2;
|
||||||
|
|
||||||
|
canvas.save();
|
||||||
|
|
||||||
|
canvas.translate(x, y);
|
||||||
|
canvas.scale(scaleFloat, scaleFloat);
|
||||||
|
canvas.rotate(degrees);
|
||||||
|
|
||||||
|
//draw two big arc
|
||||||
|
float[] bStartAngles=new float[]{135,-45};
|
||||||
|
for (int i = 0; i < 2; i++) {
|
||||||
|
RectF rectF=new RectF(-x+circleSpacing,-y+circleSpacing,x-circleSpacing,y-circleSpacing);
|
||||||
|
canvas.drawArc(rectF, bStartAngles[i], 90, false, paint);
|
||||||
|
}
|
||||||
|
|
||||||
|
canvas.restore();
|
||||||
|
canvas.translate(x, y);
|
||||||
|
canvas.scale(scaleFloat, scaleFloat);
|
||||||
|
canvas.rotate(-degrees);
|
||||||
|
//draw two small arc
|
||||||
|
float[] sStartAngles=new float[]{225,45};
|
||||||
|
for (int i = 0; i < 2; i++) {
|
||||||
|
RectF rectF=new RectF(-x/1.8f+circleSpacing,-y/1.8f+circleSpacing,x/1.8f-circleSpacing,y/1.8f-circleSpacing);
|
||||||
|
canvas.drawArc(rectF, sStartAngles[i], 90, false, paint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Animator> createAnimation() {
|
||||||
|
List<Animator> animators=new ArrayList<>();
|
||||||
|
ValueAnimator scaleAnim=ValueAnimator.ofFloat(1,0.6f,1);
|
||||||
|
scaleAnim.setDuration(1000);
|
||||||
|
scaleAnim.setRepeatCount(-1);
|
||||||
|
scaleAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
||||||
|
@Override
|
||||||
|
public void onAnimationUpdate(ValueAnimator animation) {
|
||||||
|
scaleFloat = (float) animation.getAnimatedValue();
|
||||||
|
postInvalidate();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
scaleAnim.start();
|
||||||
|
|
||||||
|
ValueAnimator rotateAnim=ValueAnimator.ofFloat(0, 180,360);
|
||||||
|
rotateAnim.setDuration(1000);
|
||||||
|
rotateAnim.setRepeatCount(-1);
|
||||||
|
rotateAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
||||||
|
@Override
|
||||||
|
public void onAnimationUpdate(ValueAnimator animation) {
|
||||||
|
degrees = (float) animation.getAnimatedValue();
|
||||||
|
postInvalidate();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
rotateAnim.start();
|
||||||
|
animators.add(scaleAnim);
|
||||||
|
animators.add(rotateAnim);
|
||||||
|
return animators;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,94 @@
|
|||||||
|
package com.rmondjone.xrecyclerview.progressindicator.indicator;
|
||||||
|
|
||||||
|
import android.animation.Animator;
|
||||||
|
import android.animation.ValueAnimator;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.graphics.RectF;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Jack on 2015/10/16.
|
||||||
|
*/
|
||||||
|
public class BallClipRotatePulseIndicator extends BaseIndicatorController {
|
||||||
|
|
||||||
|
float scaleFloat1,scaleFloat2,degrees;
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(Canvas canvas, Paint paint) {
|
||||||
|
float circleSpacing=12;
|
||||||
|
float x=getWidth()/2;
|
||||||
|
float y=getHeight()/2;
|
||||||
|
|
||||||
|
//draw fill circle
|
||||||
|
canvas.save();
|
||||||
|
canvas.translate(x, y);
|
||||||
|
canvas.scale(scaleFloat1, scaleFloat1);
|
||||||
|
paint.setStyle(Paint.Style.FILL);
|
||||||
|
canvas.drawCircle(0, 0, x / 2.5f, paint);
|
||||||
|
|
||||||
|
canvas.restore();
|
||||||
|
|
||||||
|
canvas.translate(x, y);
|
||||||
|
canvas.scale(scaleFloat2, scaleFloat2);
|
||||||
|
canvas.rotate(degrees);
|
||||||
|
|
||||||
|
paint.setStrokeWidth(3);
|
||||||
|
paint.setStyle(Paint.Style.STROKE);
|
||||||
|
|
||||||
|
//draw two arc
|
||||||
|
float[] startAngles=new float[]{225,45};
|
||||||
|
for (int i = 0; i < 2; i++) {
|
||||||
|
RectF rectF=new RectF(-x+circleSpacing,-y+circleSpacing,x-circleSpacing,y-circleSpacing);
|
||||||
|
canvas.drawArc(rectF, startAngles[i], 90, false, paint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Animator> createAnimation() {
|
||||||
|
ValueAnimator scaleAnim=ValueAnimator.ofFloat(1,0.3f,1);
|
||||||
|
scaleAnim.setDuration(1000);
|
||||||
|
scaleAnim.setRepeatCount(-1);
|
||||||
|
scaleAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
||||||
|
@Override
|
||||||
|
public void onAnimationUpdate(ValueAnimator animation) {
|
||||||
|
scaleFloat1 = (float) animation.getAnimatedValue();
|
||||||
|
postInvalidate();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
scaleAnim.start();
|
||||||
|
|
||||||
|
ValueAnimator scaleAnim2=ValueAnimator.ofFloat(1,0.6f,1);
|
||||||
|
scaleAnim2.setDuration(1000);
|
||||||
|
scaleAnim2.setRepeatCount(-1);
|
||||||
|
scaleAnim2.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
||||||
|
@Override
|
||||||
|
public void onAnimationUpdate(ValueAnimator animation) {
|
||||||
|
scaleFloat2 = (float) animation.getAnimatedValue();
|
||||||
|
postInvalidate();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
scaleAnim2.start();
|
||||||
|
|
||||||
|
ValueAnimator rotateAnim=ValueAnimator.ofFloat(0, 180,360);
|
||||||
|
rotateAnim.setDuration(1000);
|
||||||
|
rotateAnim.setRepeatCount(-1);
|
||||||
|
rotateAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
||||||
|
@Override
|
||||||
|
public void onAnimationUpdate(ValueAnimator animation) {
|
||||||
|
degrees = (float) animation.getAnimatedValue();
|
||||||
|
postInvalidate();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
rotateAnim.start();
|
||||||
|
List<Animator> animators=new ArrayList<>();
|
||||||
|
animators.add(scaleAnim);
|
||||||
|
animators.add(scaleAnim2);
|
||||||
|
animators.add(rotateAnim);
|
||||||
|
return animators;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,76 @@
|
|||||||
|
package com.rmondjone.xrecyclerview.progressindicator.indicator;
|
||||||
|
|
||||||
|
import android.animation.Animator;
|
||||||
|
import android.animation.ValueAnimator;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Jack on 2015/10/20.
|
||||||
|
*/
|
||||||
|
public class BallGridBeatIndicator extends BaseIndicatorController {
|
||||||
|
|
||||||
|
public static final int ALPHA=255;
|
||||||
|
|
||||||
|
int[] alphas=new int[]{ALPHA,
|
||||||
|
ALPHA,
|
||||||
|
ALPHA,
|
||||||
|
ALPHA,
|
||||||
|
ALPHA,
|
||||||
|
ALPHA,
|
||||||
|
ALPHA,
|
||||||
|
ALPHA,
|
||||||
|
ALPHA};
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(Canvas canvas, Paint paint) {
|
||||||
|
float circleSpacing=4;
|
||||||
|
float radius=(getWidth()-circleSpacing*4)/6;
|
||||||
|
float x = getWidth()/ 2-(radius*2+circleSpacing);
|
||||||
|
float y = getWidth()/ 2-(radius*2+circleSpacing);
|
||||||
|
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
for (int j = 0; j < 3; j++) {
|
||||||
|
canvas.save();
|
||||||
|
float translateX=x+(radius*2)*j+circleSpacing*j;
|
||||||
|
float translateY=y+(radius*2)*i+circleSpacing*i;
|
||||||
|
canvas.translate(translateX, translateY);
|
||||||
|
paint.setAlpha(alphas[3 * i + j]);
|
||||||
|
canvas.drawCircle(0, 0, radius, paint);
|
||||||
|
canvas.restore();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Animator> createAnimation() {
|
||||||
|
List<Animator> animators=new ArrayList<>();
|
||||||
|
|
||||||
|
int[] durations={960, 930, 1190, 1130, 1340, 940, 1200, 820, 1190};
|
||||||
|
int[] delays= {360, 400, 680, 410, 710, -150, -120, 10, 320};
|
||||||
|
|
||||||
|
for (int i = 0; i < 9; i++) {
|
||||||
|
final int index=i;
|
||||||
|
ValueAnimator alphaAnim=ValueAnimator.ofInt(255, 168,255);
|
||||||
|
alphaAnim.setDuration(durations[i]);
|
||||||
|
alphaAnim.setRepeatCount(-1);
|
||||||
|
alphaAnim.setStartDelay(delays[i]);
|
||||||
|
alphaAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
||||||
|
@Override
|
||||||
|
public void onAnimationUpdate(ValueAnimator animation) {
|
||||||
|
alphas[index] = (int) animation.getAnimatedValue();
|
||||||
|
postInvalidate();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
alphaAnim.start();
|
||||||
|
animators.add(alphaAnim);
|
||||||
|
}
|
||||||
|
return animators;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,103 @@
|
|||||||
|
package com.rmondjone.xrecyclerview.progressindicator.indicator;
|
||||||
|
|
||||||
|
import android.animation.Animator;
|
||||||
|
import android.animation.ValueAnimator;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Jack on 2015/10/16.
|
||||||
|
*/
|
||||||
|
public class BallGridPulseIndicator extends BaseIndicatorController{
|
||||||
|
|
||||||
|
public static final int ALPHA=255;
|
||||||
|
|
||||||
|
public static final float SCALE=1.0f;
|
||||||
|
|
||||||
|
int[] alphas=new int[]{ALPHA,
|
||||||
|
ALPHA,
|
||||||
|
ALPHA,
|
||||||
|
ALPHA,
|
||||||
|
ALPHA,
|
||||||
|
ALPHA,
|
||||||
|
ALPHA,
|
||||||
|
ALPHA,
|
||||||
|
ALPHA};
|
||||||
|
|
||||||
|
float[] scaleFloats=new float[]{SCALE,
|
||||||
|
SCALE,
|
||||||
|
SCALE,
|
||||||
|
SCALE,
|
||||||
|
SCALE,
|
||||||
|
SCALE,
|
||||||
|
SCALE,
|
||||||
|
SCALE,
|
||||||
|
SCALE};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(Canvas canvas, Paint paint) {
|
||||||
|
float circleSpacing=4;
|
||||||
|
float radius=(getWidth()-circleSpacing*4)/6;
|
||||||
|
float x = getWidth()/ 2-(radius*2+circleSpacing);
|
||||||
|
float y = getWidth()/ 2-(radius*2+circleSpacing);
|
||||||
|
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
for (int j = 0; j < 3; j++) {
|
||||||
|
canvas.save();
|
||||||
|
float translateX=x+(radius*2)*j+circleSpacing*j;
|
||||||
|
float translateY=y+(radius*2)*i+circleSpacing*i;
|
||||||
|
canvas.translate(translateX, translateY);
|
||||||
|
canvas.scale(scaleFloats[3 * i + j], scaleFloats[3 * i + j]);
|
||||||
|
paint.setAlpha(alphas[3 * i + j]);
|
||||||
|
canvas.drawCircle(0, 0, radius, paint);
|
||||||
|
canvas.restore();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Animator> createAnimation() {
|
||||||
|
List<Animator> animators=new ArrayList<>();
|
||||||
|
int[] durations={720, 1020, 1280, 1420, 1450, 1180, 870, 1450, 1060};
|
||||||
|
int[] delays= {-60, 250, -170, 480, 310, 30, 460, 780, 450};
|
||||||
|
|
||||||
|
for (int i = 0; i < 9; i++) {
|
||||||
|
final int index=i;
|
||||||
|
ValueAnimator scaleAnim=ValueAnimator.ofFloat(1,0.5f,1);
|
||||||
|
scaleAnim.setDuration(durations[i]);
|
||||||
|
scaleAnim.setRepeatCount(-1);
|
||||||
|
scaleAnim.setStartDelay(delays[i]);
|
||||||
|
scaleAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
||||||
|
@Override
|
||||||
|
public void onAnimationUpdate(ValueAnimator animation) {
|
||||||
|
scaleFloats[index] = (float) animation.getAnimatedValue();
|
||||||
|
postInvalidate();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
scaleAnim.start();
|
||||||
|
|
||||||
|
ValueAnimator alphaAnim=ValueAnimator.ofInt(255, 210, 122, 255);
|
||||||
|
alphaAnim.setDuration(durations[i]);
|
||||||
|
alphaAnim.setRepeatCount(-1);
|
||||||
|
alphaAnim.setStartDelay(delays[i]);
|
||||||
|
alphaAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
||||||
|
@Override
|
||||||
|
public void onAnimationUpdate(ValueAnimator animation) {
|
||||||
|
alphas[index] = (int) animation.getAnimatedValue();
|
||||||
|
postInvalidate();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
alphaAnim.start();
|
||||||
|
animators.add(scaleAnim);
|
||||||
|
animators.add(alphaAnim);
|
||||||
|
}
|
||||||
|
return animators;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
package com.rmondjone.xrecyclerview.progressindicator.indicator;
|
||||||
|
|
||||||
|
import android.animation.Animator;
|
||||||
|
import android.animation.ValueAnimator;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Jack on 2015/10/16.
|
||||||
|
*/
|
||||||
|
public class BallPulseIndicator extends BaseIndicatorController{
|
||||||
|
|
||||||
|
public static final float SCALE=1.0f;
|
||||||
|
|
||||||
|
//scale x ,y
|
||||||
|
private float[] scaleFloats=new float[]{SCALE,
|
||||||
|
SCALE,
|
||||||
|
SCALE};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(Canvas canvas, Paint paint) {
|
||||||
|
float circleSpacing=4;
|
||||||
|
float radius=(Math.min(getWidth(),getHeight())-circleSpacing*2)/6;
|
||||||
|
float x = getWidth()/ 2-(radius*2+circleSpacing);
|
||||||
|
float y=getHeight() / 2;
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
canvas.save();
|
||||||
|
float translateX=x+(radius*2)*i+circleSpacing*i;
|
||||||
|
canvas.translate(translateX, y);
|
||||||
|
canvas.scale(scaleFloats[i], scaleFloats[i]);
|
||||||
|
canvas.drawCircle(0, 0, radius, paint);
|
||||||
|
canvas.restore();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Animator> createAnimation() {
|
||||||
|
List<Animator> animators=new ArrayList<>();
|
||||||
|
int[] delays=new int[]{120,240,360};
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
final int index=i;
|
||||||
|
|
||||||
|
ValueAnimator scaleAnim=ValueAnimator.ofFloat(1,0.3f,1);
|
||||||
|
|
||||||
|
scaleAnim.setDuration(750);
|
||||||
|
scaleAnim.setRepeatCount(-1);
|
||||||
|
scaleAnim.setStartDelay(delays[i]);
|
||||||
|
|
||||||
|
scaleAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
||||||
|
@Override
|
||||||
|
public void onAnimationUpdate(ValueAnimator animation) {
|
||||||
|
scaleFloats[index] = (float) animation.getAnimatedValue();
|
||||||
|
postInvalidate();
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
scaleAnim.start();
|
||||||
|
animators.add(scaleAnim);
|
||||||
|
}
|
||||||
|
return animators;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
package com.rmondjone.xrecyclerview.progressindicator.indicator;
|
||||||
|
|
||||||
|
import android.animation.Animator;
|
||||||
|
import android.animation.ObjectAnimator;
|
||||||
|
import android.animation.PropertyValuesHolder;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.view.animation.LinearInterpolator;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Jack on 2015/10/17.
|
||||||
|
*/
|
||||||
|
public class BallPulseRiseIndicator extends BaseIndicatorController{
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(Canvas canvas, Paint paint) {
|
||||||
|
float radius=getWidth()/10;
|
||||||
|
canvas.drawCircle(getWidth()/4,radius*2,radius,paint);
|
||||||
|
canvas.drawCircle(getWidth()*3/4,radius*2,radius,paint);
|
||||||
|
|
||||||
|
canvas.drawCircle(radius,getHeight()-2*radius,radius,paint);
|
||||||
|
canvas.drawCircle(getWidth()/2,getHeight()-2*radius,radius,paint);
|
||||||
|
canvas.drawCircle(getWidth()-radius,getHeight()-2*radius,radius,paint);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Animator> createAnimation() {
|
||||||
|
PropertyValuesHolder rotation6=PropertyValuesHolder.ofFloat("rotationX",0,360);
|
||||||
|
ObjectAnimator animator=ObjectAnimator.ofPropertyValuesHolder(getTarget(), rotation6);
|
||||||
|
animator.setInterpolator(new LinearInterpolator());
|
||||||
|
animator.setRepeatCount(-1);
|
||||||
|
animator.setDuration(1500);
|
||||||
|
animator.start();
|
||||||
|
List<Animator> animators=new ArrayList<>();
|
||||||
|
animators.add(animator);
|
||||||
|
return animators;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
package com.rmondjone.xrecyclerview.progressindicator.indicator;
|
||||||
|
|
||||||
|
import android.animation.Animator;
|
||||||
|
import android.animation.ValueAnimator;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Jack on 2015/10/19.
|
||||||
|
*/
|
||||||
|
public class BallPulseSyncIndicator extends BaseIndicatorController {
|
||||||
|
|
||||||
|
float[] translateYFloats=new float[3];
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(Canvas canvas, Paint paint) {
|
||||||
|
float circleSpacing=4;
|
||||||
|
float radius=(getWidth()-circleSpacing*2)/6;
|
||||||
|
float x = getWidth()/ 2-(radius*2+circleSpacing);
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
canvas.save();
|
||||||
|
float translateX=x+(radius*2)*i+circleSpacing*i;
|
||||||
|
canvas.translate(translateX, translateYFloats[i]);
|
||||||
|
canvas.drawCircle(0, 0, radius, paint);
|
||||||
|
canvas.restore();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Animator> createAnimation() {
|
||||||
|
List<Animator> animators=new ArrayList<>();
|
||||||
|
float circleSpacing=4;
|
||||||
|
float radius=(getWidth()-circleSpacing*2)/6;
|
||||||
|
int[] delays=new int[]{70,140,210};
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
final int index=i;
|
||||||
|
ValueAnimator scaleAnim=ValueAnimator.ofFloat(getHeight()/2,getHeight()/2-radius*2,getHeight()/2);
|
||||||
|
scaleAnim.setDuration(600);
|
||||||
|
scaleAnim.setRepeatCount(-1);
|
||||||
|
scaleAnim.setStartDelay(delays[i]);
|
||||||
|
scaleAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
||||||
|
@Override
|
||||||
|
public void onAnimationUpdate(ValueAnimator animation) {
|
||||||
|
translateYFloats[index] = (float) animation.getAnimatedValue();
|
||||||
|
postInvalidate();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
scaleAnim.start();
|
||||||
|
animators.add(scaleAnim);
|
||||||
|
}
|
||||||
|
return animators;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
package com.rmondjone.xrecyclerview.progressindicator.indicator;
|
||||||
|
|
||||||
|
import android.animation.Animator;
|
||||||
|
import android.animation.ObjectAnimator;
|
||||||
|
import android.animation.ValueAnimator;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Jack on 2015/10/17.
|
||||||
|
*/
|
||||||
|
public class BallRotateIndicator extends BaseIndicatorController{
|
||||||
|
|
||||||
|
float scaleFloat=0.5f;
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(Canvas canvas, Paint paint) {
|
||||||
|
float radius=getWidth()/10;
|
||||||
|
float x = getWidth()/ 2;
|
||||||
|
float y=getHeight()/2;
|
||||||
|
|
||||||
|
canvas.save();
|
||||||
|
canvas.translate(x - radius * 2 - radius, y);
|
||||||
|
canvas.scale(scaleFloat, scaleFloat);
|
||||||
|
canvas.drawCircle(0, 0, radius, paint);
|
||||||
|
canvas.restore();
|
||||||
|
|
||||||
|
canvas.save();
|
||||||
|
canvas.translate(x, y);
|
||||||
|
canvas.scale(scaleFloat, scaleFloat);
|
||||||
|
canvas.drawCircle(0, 0, radius, paint);
|
||||||
|
canvas.restore();
|
||||||
|
|
||||||
|
canvas.save();
|
||||||
|
canvas.translate(x + radius * 2 + radius, y);
|
||||||
|
canvas.scale(scaleFloat, scaleFloat);
|
||||||
|
canvas.drawCircle(0,0,radius, paint);
|
||||||
|
canvas.restore();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Animator> createAnimation() {
|
||||||
|
List<Animator> animators=new ArrayList<>();
|
||||||
|
ValueAnimator scaleAnim=ValueAnimator.ofFloat(0.5f,1,0.5f);
|
||||||
|
scaleAnim.setDuration(1000);
|
||||||
|
scaleAnim.setRepeatCount(-1);
|
||||||
|
scaleAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
||||||
|
@Override
|
||||||
|
public void onAnimationUpdate(ValueAnimator animation) {
|
||||||
|
scaleFloat = (float) animation.getAnimatedValue();
|
||||||
|
postInvalidate();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
scaleAnim.start();
|
||||||
|
|
||||||
|
ObjectAnimator rotateAnim=ObjectAnimator.ofFloat(getTarget(),"rotation",0,180,360);
|
||||||
|
rotateAnim.setDuration(1000);
|
||||||
|
rotateAnim.setRepeatCount(-1);
|
||||||
|
rotateAnim.start();
|
||||||
|
|
||||||
|
animators.add(scaleAnim);
|
||||||
|
animators.add(rotateAnim);
|
||||||
|
return animators;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
package com.rmondjone.xrecyclerview.progressindicator.indicator;
|
||||||
|
|
||||||
|
import android.animation.Animator;
|
||||||
|
import android.animation.ValueAnimator;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.view.animation.LinearInterpolator;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Jack on 2015/10/19.
|
||||||
|
*/
|
||||||
|
public class BallScaleIndicator extends BaseIndicatorController {
|
||||||
|
|
||||||
|
float scale=1;
|
||||||
|
int alpha=255;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(Canvas canvas, Paint paint) {
|
||||||
|
float circleSpacing=4;
|
||||||
|
paint.setAlpha(alpha);
|
||||||
|
canvas.scale(scale,scale,getWidth()/2,getHeight()/2);
|
||||||
|
paint.setAlpha(alpha);
|
||||||
|
canvas.drawCircle(getWidth()/2,getHeight()/2,getWidth()/2-circleSpacing,paint);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Animator> createAnimation() {
|
||||||
|
List<Animator> animators=new ArrayList<>();
|
||||||
|
ValueAnimator scaleAnim=ValueAnimator.ofFloat(0,1);
|
||||||
|
scaleAnim.setInterpolator(new LinearInterpolator());
|
||||||
|
scaleAnim.setDuration(1000);
|
||||||
|
scaleAnim.setRepeatCount(-1);
|
||||||
|
scaleAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
||||||
|
@Override
|
||||||
|
public void onAnimationUpdate(ValueAnimator animation) {
|
||||||
|
scale = (float) animation.getAnimatedValue();
|
||||||
|
postInvalidate();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
scaleAnim.start();
|
||||||
|
|
||||||
|
ValueAnimator alphaAnim=ValueAnimator.ofInt(255, 0);
|
||||||
|
alphaAnim.setInterpolator(new LinearInterpolator());
|
||||||
|
alphaAnim.setDuration(1000);
|
||||||
|
alphaAnim.setRepeatCount(-1);
|
||||||
|
alphaAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
||||||
|
@Override
|
||||||
|
public void onAnimationUpdate(ValueAnimator animation) {
|
||||||
|
alpha = (int) animation.getAnimatedValue();
|
||||||
|
postInvalidate();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
alphaAnim.start();
|
||||||
|
animators.add(scaleAnim);
|
||||||
|
animators.add(alphaAnim);
|
||||||
|
return animators;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
package com.rmondjone.xrecyclerview.progressindicator.indicator;
|
||||||
|
|
||||||
|
import android.animation.Animator;
|
||||||
|
import android.animation.ValueAnimator;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.view.animation.LinearInterpolator;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Jack on 2015/10/19.
|
||||||
|
*/
|
||||||
|
public class BallScaleMultipleIndicator extends BaseIndicatorController {
|
||||||
|
|
||||||
|
float[] scaleFloats=new float[]{1,1,1};
|
||||||
|
int[] alphaInts=new int[]{255,255,255};
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(Canvas canvas, Paint paint) {
|
||||||
|
float circleSpacing=4;
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
paint.setAlpha(alphaInts[i]);
|
||||||
|
canvas.scale(scaleFloats[i],scaleFloats[i],getWidth()/2,getHeight()/2);
|
||||||
|
canvas.drawCircle(getWidth()/2,getHeight()/2,getWidth()/2-circleSpacing,paint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Animator> createAnimation() {
|
||||||
|
List<Animator> animators=new ArrayList<>();
|
||||||
|
long[] delays=new long[]{0, 200, 400};
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
final int index=i;
|
||||||
|
ValueAnimator scaleAnim=ValueAnimator.ofFloat(0,1);
|
||||||
|
scaleAnim.setInterpolator(new LinearInterpolator());
|
||||||
|
scaleAnim.setDuration(1000);
|
||||||
|
scaleAnim.setRepeatCount(-1);
|
||||||
|
scaleAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
||||||
|
@Override
|
||||||
|
public void onAnimationUpdate(ValueAnimator animation) {
|
||||||
|
scaleFloats[index] = (float) animation.getAnimatedValue();
|
||||||
|
postInvalidate();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
scaleAnim.setStartDelay(delays[i]);
|
||||||
|
scaleAnim.start();
|
||||||
|
|
||||||
|
ValueAnimator alphaAnim=ValueAnimator.ofInt(255,0);
|
||||||
|
alphaAnim.setInterpolator(new LinearInterpolator());
|
||||||
|
alphaAnim.setDuration(1000);
|
||||||
|
alphaAnim.setRepeatCount(-1);
|
||||||
|
alphaAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
||||||
|
@Override
|
||||||
|
public void onAnimationUpdate(ValueAnimator animation) {
|
||||||
|
alphaInts[index] = (int) animation.getAnimatedValue();
|
||||||
|
postInvalidate();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
scaleAnim.setStartDelay(delays[i]);
|
||||||
|
alphaAnim.start();
|
||||||
|
|
||||||
|
animators.add(scaleAnim);
|
||||||
|
animators.add(alphaAnim);
|
||||||
|
}
|
||||||
|
return animators;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
package com.rmondjone.xrecyclerview.progressindicator.indicator;
|
||||||
|
|
||||||
|
import android.animation.Animator;
|
||||||
|
import android.animation.ValueAnimator;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.view.animation.LinearInterpolator;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Jack on 2015/10/19.
|
||||||
|
*/
|
||||||
|
public class BallScaleRippleIndicator extends BallScaleIndicator {
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(Canvas canvas, Paint paint) {
|
||||||
|
paint.setStyle(Paint.Style.STROKE);
|
||||||
|
paint.setStrokeWidth(3);
|
||||||
|
super.draw(canvas, paint);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Animator> createAnimation() {
|
||||||
|
List<Animator> animators=new ArrayList<>();
|
||||||
|
ValueAnimator scaleAnim=ValueAnimator.ofFloat(0,1);
|
||||||
|
scaleAnim.setInterpolator(new LinearInterpolator());
|
||||||
|
scaleAnim.setDuration(1000);
|
||||||
|
scaleAnim.setRepeatCount(-1);
|
||||||
|
scaleAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
||||||
|
@Override
|
||||||
|
public void onAnimationUpdate(ValueAnimator animation) {
|
||||||
|
scale = (float) animation.getAnimatedValue();
|
||||||
|
postInvalidate();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
scaleAnim.start();
|
||||||
|
|
||||||
|
ValueAnimator alphaAnim=ValueAnimator.ofInt(0, 255);
|
||||||
|
alphaAnim.setInterpolator(new LinearInterpolator());
|
||||||
|
alphaAnim.setDuration(1000);
|
||||||
|
alphaAnim.setRepeatCount(-1);
|
||||||
|
alphaAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
||||||
|
@Override
|
||||||
|
public void onAnimationUpdate(ValueAnimator animation) {
|
||||||
|
alpha = (int) animation.getAnimatedValue();
|
||||||
|
postInvalidate();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
alphaAnim.start();
|
||||||
|
|
||||||
|
animators.add(scaleAnim);
|
||||||
|
animators.add(alphaAnim);
|
||||||
|
return animators;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
package com.rmondjone.xrecyclerview.progressindicator.indicator;
|
||||||
|
|
||||||
|
import android.animation.Animator;
|
||||||
|
import android.animation.ValueAnimator;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.view.animation.LinearInterpolator;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Jack on 2015/10/19.
|
||||||
|
*/
|
||||||
|
public class BallScaleRippleMultipleIndicator extends BallScaleMultipleIndicator{
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(Canvas canvas, Paint paint) {
|
||||||
|
paint.setStyle(Paint.Style.STROKE);
|
||||||
|
paint.setStrokeWidth(3);
|
||||||
|
super.draw(canvas, paint);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Animator> createAnimation() {
|
||||||
|
List<Animator> animators=new ArrayList<>();
|
||||||
|
long[] delays=new long[]{0, 200, 400};
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
final int index=i;
|
||||||
|
ValueAnimator scaleAnim=ValueAnimator.ofFloat(0,1);
|
||||||
|
scaleAnim.setInterpolator(new LinearInterpolator());
|
||||||
|
scaleAnim.setDuration(1000);
|
||||||
|
scaleAnim.setRepeatCount(-1);
|
||||||
|
scaleAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
||||||
|
@Override
|
||||||
|
public void onAnimationUpdate(ValueAnimator animation) {
|
||||||
|
scaleFloats[index] = (float) animation.getAnimatedValue();
|
||||||
|
postInvalidate();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
scaleAnim.setStartDelay(delays[i]);
|
||||||
|
scaleAnim.start();
|
||||||
|
|
||||||
|
ValueAnimator alphaAnim=ValueAnimator.ofInt(0,255);
|
||||||
|
scaleAnim.setInterpolator(new LinearInterpolator());
|
||||||
|
alphaAnim.setDuration(1000);
|
||||||
|
alphaAnim.setRepeatCount(-1);
|
||||||
|
alphaAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
||||||
|
@Override
|
||||||
|
public void onAnimationUpdate(ValueAnimator animation) {
|
||||||
|
alphaInts[index] = (int) animation.getAnimatedValue();
|
||||||
|
postInvalidate();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
scaleAnim.setStartDelay(delays[i]);
|
||||||
|
alphaAnim.start();
|
||||||
|
|
||||||
|
animators.add(scaleAnim);
|
||||||
|
animators.add(alphaAnim);
|
||||||
|
}
|
||||||
|
return animators;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,116 @@
|
|||||||
|
package com.rmondjone.xrecyclerview.progressindicator.indicator;
|
||||||
|
|
||||||
|
import android.animation.Animator;
|
||||||
|
import android.animation.ValueAnimator;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Jack on 2015/10/20.
|
||||||
|
*/
|
||||||
|
public class BallSpinFadeLoaderIndicator extends BaseIndicatorController {
|
||||||
|
|
||||||
|
public static final float SCALE=1.0f;
|
||||||
|
|
||||||
|
public static final int ALPHA=255;
|
||||||
|
|
||||||
|
float[] scaleFloats=new float[]{SCALE,
|
||||||
|
SCALE,
|
||||||
|
SCALE,
|
||||||
|
SCALE,
|
||||||
|
SCALE,
|
||||||
|
SCALE,
|
||||||
|
SCALE,
|
||||||
|
SCALE};
|
||||||
|
|
||||||
|
int[] alphas=new int[]{ALPHA,
|
||||||
|
ALPHA,
|
||||||
|
ALPHA,
|
||||||
|
ALPHA,
|
||||||
|
ALPHA,
|
||||||
|
ALPHA,
|
||||||
|
ALPHA,
|
||||||
|
ALPHA};
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(Canvas canvas, Paint paint) {
|
||||||
|
float radius=getWidth()/10;
|
||||||
|
for (int i = 0; i < 8; i++) {
|
||||||
|
canvas.save();
|
||||||
|
Point point=circleAt(getWidth(),getHeight(),getWidth()/2-radius,i*(Math.PI/4));
|
||||||
|
canvas.translate(point.x,point.y);
|
||||||
|
canvas.scale(scaleFloats[i],scaleFloats[i]);
|
||||||
|
paint.setAlpha(alphas[i]);
|
||||||
|
canvas.drawCircle(0,0,radius,paint);
|
||||||
|
canvas.restore();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 圆O的圆心为(a,b),半径为R,点A与到X轴的为角α.
|
||||||
|
*则点A的坐标为(a+R*cosα,b+R*sinα)
|
||||||
|
* @param width
|
||||||
|
* @param height
|
||||||
|
* @param radius
|
||||||
|
* @param angle
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
Point circleAt(int width,int height,float radius,double angle){
|
||||||
|
float x= (float) (width/2+radius*(Math.cos(angle)));
|
||||||
|
float y= (float) (height/2+radius*(Math.sin(angle)));
|
||||||
|
return new Point(x,y);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Animator> createAnimation() {
|
||||||
|
List<Animator> animators=new ArrayList<>();
|
||||||
|
int[] delays= {0, 120, 240, 360, 480, 600, 720, 780, 840};
|
||||||
|
for (int i = 0; i < 8; i++) {
|
||||||
|
final int index=i;
|
||||||
|
ValueAnimator scaleAnim=ValueAnimator.ofFloat(1,0.4f,1);
|
||||||
|
scaleAnim.setDuration(1000);
|
||||||
|
scaleAnim.setRepeatCount(-1);
|
||||||
|
scaleAnim.setStartDelay(delays[i]);
|
||||||
|
scaleAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
||||||
|
@Override
|
||||||
|
public void onAnimationUpdate(ValueAnimator animation) {
|
||||||
|
scaleFloats[index] = (float) animation.getAnimatedValue();
|
||||||
|
postInvalidate();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
scaleAnim.start();
|
||||||
|
|
||||||
|
ValueAnimator alphaAnim=ValueAnimator.ofInt(255, 77, 255);
|
||||||
|
alphaAnim.setDuration(1000);
|
||||||
|
alphaAnim.setRepeatCount(-1);
|
||||||
|
alphaAnim.setStartDelay(delays[i]);
|
||||||
|
alphaAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
||||||
|
@Override
|
||||||
|
public void onAnimationUpdate(ValueAnimator animation) {
|
||||||
|
alphas[index] = (int) animation.getAnimatedValue();
|
||||||
|
postInvalidate();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
alphaAnim.start();
|
||||||
|
animators.add(scaleAnim);
|
||||||
|
animators.add(alphaAnim);
|
||||||
|
}
|
||||||
|
return animators;
|
||||||
|
}
|
||||||
|
|
||||||
|
final class Point{
|
||||||
|
public float x;
|
||||||
|
public float y;
|
||||||
|
|
||||||
|
public Point(float x, float y){
|
||||||
|
this.x=x;
|
||||||
|
this.y=y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
package com.rmondjone.xrecyclerview.progressindicator.indicator;
|
||||||
|
|
||||||
|
import android.animation.Animator;
|
||||||
|
import android.animation.ValueAnimator;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.view.animation.LinearInterpolator;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Jack on 2015/10/19.
|
||||||
|
*/
|
||||||
|
public class BallTrianglePathIndicator extends BaseIndicatorController {
|
||||||
|
|
||||||
|
float[] translateX=new float[3],translateY=new float[3];
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(Canvas canvas, Paint paint) {
|
||||||
|
paint.setStrokeWidth(3);
|
||||||
|
paint.setStyle(Paint.Style.STROKE);
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
canvas.save();
|
||||||
|
canvas.translate(translateX[i], translateY[i]);
|
||||||
|
canvas.drawCircle(0, 0, getWidth() / 10, paint);
|
||||||
|
canvas.restore();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Animator> createAnimation() {
|
||||||
|
List<Animator> animators=new ArrayList<>();
|
||||||
|
float startX=getWidth()/5;
|
||||||
|
float startY=getWidth()/5;
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
final int index=i;
|
||||||
|
ValueAnimator translateXAnim=ValueAnimator.ofFloat(getWidth()/2,getWidth()-startX,startX,getWidth()/2);
|
||||||
|
if (i==1){
|
||||||
|
translateXAnim=ValueAnimator.ofFloat(getWidth()-startX,startX,getWidth()/2,getWidth()-startX);
|
||||||
|
}else if (i==2){
|
||||||
|
translateXAnim=ValueAnimator.ofFloat(startX,getWidth()/2,getWidth()-startX,startX);
|
||||||
|
}
|
||||||
|
ValueAnimator translateYAnim=ValueAnimator.ofFloat(startY,getHeight()-startY,getHeight()-startY,startY);
|
||||||
|
if (i==1){
|
||||||
|
translateYAnim=ValueAnimator.ofFloat(getHeight()-startY,getHeight()-startY,startY,getHeight()-startY);
|
||||||
|
}else if (i==2){
|
||||||
|
translateYAnim=ValueAnimator.ofFloat(getHeight()-startY,startY,getHeight()-startY,getHeight()-startY);
|
||||||
|
}
|
||||||
|
|
||||||
|
translateXAnim.setDuration(2000);
|
||||||
|
translateXAnim.setInterpolator(new LinearInterpolator());
|
||||||
|
translateXAnim.setRepeatCount(-1);
|
||||||
|
translateXAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
||||||
|
@Override
|
||||||
|
public void onAnimationUpdate(ValueAnimator animation) {
|
||||||
|
translateX [index]= (float) animation.getAnimatedValue();
|
||||||
|
postInvalidate();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
translateXAnim.start();
|
||||||
|
|
||||||
|
translateYAnim.setDuration(2000);
|
||||||
|
translateYAnim.setInterpolator(new LinearInterpolator());
|
||||||
|
translateYAnim.setRepeatCount(-1);
|
||||||
|
translateYAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
||||||
|
@Override
|
||||||
|
public void onAnimationUpdate(ValueAnimator animation) {
|
||||||
|
translateY [index]= (float) animation.getAnimatedValue();
|
||||||
|
postInvalidate();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
translateYAnim.start();
|
||||||
|
|
||||||
|
animators.add(translateXAnim);
|
||||||
|
animators.add(translateYAnim);
|
||||||
|
}
|
||||||
|
return animators;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
package com.rmondjone.xrecyclerview.progressindicator.indicator;
|
||||||
|
|
||||||
|
|
||||||
|
import android.animation.Animator;
|
||||||
|
import android.animation.ValueAnimator;
|
||||||
|
import android.view.animation.LinearInterpolator;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Jack on 2015/10/19.
|
||||||
|
*/
|
||||||
|
public class BallZigZagDeflectIndicator extends BallZigZagIndicator {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Animator> createAnimation() {
|
||||||
|
List<Animator> animators=new ArrayList<>();
|
||||||
|
float startX=getWidth()/6;
|
||||||
|
float startY=getWidth()/6;
|
||||||
|
for (int i = 0; i < 2; i++) {
|
||||||
|
final int index=i;
|
||||||
|
ValueAnimator translateXAnim=ValueAnimator.ofFloat(startX,getWidth()-startX,startX,getWidth()-startX,startX);
|
||||||
|
if (i==1){
|
||||||
|
translateXAnim=ValueAnimator.ofFloat(getWidth()-startX,startX,getWidth()-startX,startX,getWidth()-startX);
|
||||||
|
}
|
||||||
|
ValueAnimator translateYAnim=ValueAnimator.ofFloat(startY,startY,getHeight()-startY,getHeight()-startY,startY);
|
||||||
|
if (i==1){
|
||||||
|
translateYAnim=ValueAnimator.ofFloat(getHeight()-startY,getHeight()-startY,startY,startY,getHeight()-startY);
|
||||||
|
}
|
||||||
|
|
||||||
|
translateXAnim.setDuration(2000);
|
||||||
|
translateXAnim.setInterpolator(new LinearInterpolator());
|
||||||
|
translateXAnim.setRepeatCount(-1);
|
||||||
|
translateXAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
||||||
|
@Override
|
||||||
|
public void onAnimationUpdate(ValueAnimator animation) {
|
||||||
|
translateX [index]= (float) animation.getAnimatedValue();
|
||||||
|
postInvalidate();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
translateXAnim.start();
|
||||||
|
|
||||||
|
translateYAnim.setDuration(2000);
|
||||||
|
translateYAnim.setInterpolator(new LinearInterpolator());
|
||||||
|
translateYAnim.setRepeatCount(-1);
|
||||||
|
translateYAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
||||||
|
@Override
|
||||||
|
public void onAnimationUpdate(ValueAnimator animation) {
|
||||||
|
translateY [index]= (float) animation.getAnimatedValue();
|
||||||
|
postInvalidate();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
translateYAnim.start();
|
||||||
|
|
||||||
|
animators.add(translateXAnim);
|
||||||
|
animators.add(translateYAnim);
|
||||||
|
}
|
||||||
|
return animators;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,75 @@
|
|||||||
|
package com.rmondjone.xrecyclerview.progressindicator.indicator;
|
||||||
|
|
||||||
|
import android.animation.Animator;
|
||||||
|
import android.animation.ValueAnimator;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.view.animation.LinearInterpolator;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Jack on 2015/10/19.
|
||||||
|
*/
|
||||||
|
public class BallZigZagIndicator extends BaseIndicatorController {
|
||||||
|
|
||||||
|
float[] translateX=new float[2],translateY=new float[2];
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(Canvas canvas, Paint paint) {
|
||||||
|
for (int i = 0; i < 2; i++) {
|
||||||
|
canvas.save();
|
||||||
|
canvas.translate(translateX[i], translateY[i]);
|
||||||
|
canvas.drawCircle(0, 0, getWidth() / 10, paint);
|
||||||
|
canvas.restore();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Animator> createAnimation() {
|
||||||
|
List<Animator> animators=new ArrayList<>();
|
||||||
|
float startX=getWidth()/6;
|
||||||
|
float startY=getWidth()/6;
|
||||||
|
for (int i = 0; i < 2; i++) {
|
||||||
|
final int index=i;
|
||||||
|
ValueAnimator translateXAnim=ValueAnimator.ofFloat(startX,getWidth()-startX,getWidth()/2,startX);
|
||||||
|
if (i==1){
|
||||||
|
translateXAnim=ValueAnimator.ofFloat(getWidth()-startX,startX,getWidth()/2,getWidth()-startX);
|
||||||
|
}
|
||||||
|
ValueAnimator translateYAnim=ValueAnimator.ofFloat(startY,startY,getHeight()/2,startY);
|
||||||
|
if (i==1){
|
||||||
|
translateYAnim=ValueAnimator.ofFloat(getHeight()-startY,getHeight()-startY,getHeight()/2,getHeight()-startY);
|
||||||
|
}
|
||||||
|
|
||||||
|
translateXAnim.setDuration(1000);
|
||||||
|
translateXAnim.setInterpolator(new LinearInterpolator());
|
||||||
|
translateXAnim.setRepeatCount(-1);
|
||||||
|
translateXAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
||||||
|
@Override
|
||||||
|
public void onAnimationUpdate(ValueAnimator animation) {
|
||||||
|
translateX[index] = (float) animation.getAnimatedValue();
|
||||||
|
postInvalidate();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
translateXAnim.start();
|
||||||
|
|
||||||
|
translateYAnim.setDuration(1000);
|
||||||
|
translateYAnim.setInterpolator(new LinearInterpolator());
|
||||||
|
translateYAnim.setRepeatCount(-1);
|
||||||
|
translateYAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
||||||
|
@Override
|
||||||
|
public void onAnimationUpdate(ValueAnimator animation) {
|
||||||
|
translateY[index] = (float) animation.getAnimatedValue();
|
||||||
|
postInvalidate();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
translateYAnim.start();
|
||||||
|
animators.add(translateXAnim);
|
||||||
|
animators.add(translateYAnim);
|
||||||
|
}
|
||||||
|
return animators;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,99 @@
|
|||||||
|
package com.rmondjone.xrecyclerview.progressindicator.indicator;
|
||||||
|
|
||||||
|
import android.animation.Animator;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.view.View;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Jack on 2015/10/15.
|
||||||
|
*/
|
||||||
|
public abstract class BaseIndicatorController {
|
||||||
|
|
||||||
|
|
||||||
|
private View mTarget;
|
||||||
|
|
||||||
|
private List<Animator> mAnimators;
|
||||||
|
|
||||||
|
|
||||||
|
public void setTarget(View target){
|
||||||
|
this.mTarget=target;
|
||||||
|
}
|
||||||
|
|
||||||
|
public View getTarget(){
|
||||||
|
return mTarget;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public int getWidth(){
|
||||||
|
return mTarget.getWidth();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getHeight(){
|
||||||
|
return mTarget.getHeight();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void postInvalidate(){
|
||||||
|
mTarget.postInvalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* draw indicator
|
||||||
|
* @param canvas
|
||||||
|
* @param paint
|
||||||
|
*/
|
||||||
|
public abstract void draw(Canvas canvas,Paint paint);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* create animation or animations
|
||||||
|
*/
|
||||||
|
public abstract List<Animator> createAnimation();
|
||||||
|
|
||||||
|
public void initAnimation(){
|
||||||
|
mAnimators=createAnimation();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* make animation to start or end when target
|
||||||
|
* view was be Visible or Gone or Invisible.
|
||||||
|
* make animation to cancel when target view
|
||||||
|
* be onDetachedFromWindow.
|
||||||
|
* @param animStatus
|
||||||
|
*/
|
||||||
|
public void setAnimationStatus(AnimStatus animStatus){
|
||||||
|
if (mAnimators==null){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int count=mAnimators.size();
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
Animator animator=mAnimators.get(i);
|
||||||
|
boolean isRunning=animator.isRunning();
|
||||||
|
switch (animStatus){
|
||||||
|
case START:
|
||||||
|
if (!isRunning){
|
||||||
|
animator.start();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case END:
|
||||||
|
if (isRunning){
|
||||||
|
animator.end();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case CANCEL:
|
||||||
|
if (isRunning){
|
||||||
|
animator.cancel();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public enum AnimStatus{
|
||||||
|
START,END,CANCEL
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,110 @@
|
|||||||
|
package com.rmondjone.xrecyclerview.progressindicator.indicator;
|
||||||
|
|
||||||
|
import android.animation.Animator;
|
||||||
|
import android.animation.ValueAnimator;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.graphics.RectF;
|
||||||
|
import android.view.animation.LinearInterpolator;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Jack on 2015/10/18.
|
||||||
|
*/
|
||||||
|
public class CubeTransitionIndicator extends BaseIndicatorController {
|
||||||
|
|
||||||
|
float[] translateX=new float[2],translateY=new float[2];
|
||||||
|
float degrees,scaleFloat=1.0f;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(Canvas canvas, Paint paint) {
|
||||||
|
float rWidth=getWidth()/5;
|
||||||
|
float rHeight=getHeight()/5;
|
||||||
|
for (int i = 0; i < 2; i++) {
|
||||||
|
canvas.save();
|
||||||
|
canvas.translate(translateX[i], translateY[i]);
|
||||||
|
canvas.rotate(degrees);
|
||||||
|
canvas.scale(scaleFloat,scaleFloat);
|
||||||
|
RectF rectF=new RectF(-rWidth/2,-rHeight/2,rWidth/2,rHeight/2);
|
||||||
|
canvas.drawRect(rectF,paint);
|
||||||
|
canvas.restore();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Animator> createAnimation() {
|
||||||
|
List<Animator> animators=new ArrayList<>();
|
||||||
|
float startX=getWidth()/5;
|
||||||
|
float startY=getHeight()/5;
|
||||||
|
for (int i = 0; i < 2; i++) {
|
||||||
|
final int index=i;
|
||||||
|
translateX[index]=startX;
|
||||||
|
ValueAnimator translationXAnim=ValueAnimator.ofFloat(startX,getWidth()-startX,getWidth()-startX, startX,startX);
|
||||||
|
if (i==1){
|
||||||
|
translationXAnim=ValueAnimator.ofFloat(getWidth()-startX,startX,startX, getWidth()-startX,getWidth()-startX);
|
||||||
|
}
|
||||||
|
translationXAnim.setInterpolator(new LinearInterpolator());
|
||||||
|
translationXAnim.setDuration(1600);
|
||||||
|
translationXAnim.setRepeatCount(-1);
|
||||||
|
translationXAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
||||||
|
@Override
|
||||||
|
public void onAnimationUpdate(ValueAnimator animation) {
|
||||||
|
translateX[index] = (float) animation.getAnimatedValue();
|
||||||
|
postInvalidate();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
translationXAnim.start();
|
||||||
|
translateY[index]=startY;
|
||||||
|
ValueAnimator translationYAnim=ValueAnimator.ofFloat(startY,startY,getHeight()-startY,getHeight()- startY,startY);
|
||||||
|
if (i==1){
|
||||||
|
translationYAnim=ValueAnimator.ofFloat(getHeight()-startY,getHeight()-startY,startY,startY,getHeight()-startY);
|
||||||
|
}
|
||||||
|
translationYAnim.setDuration(1600);
|
||||||
|
translationYAnim.setInterpolator(new LinearInterpolator());
|
||||||
|
translationYAnim.setRepeatCount(-1);
|
||||||
|
translationYAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
||||||
|
@Override
|
||||||
|
public void onAnimationUpdate(ValueAnimator animation) {
|
||||||
|
translateY[index] = (float) animation.getAnimatedValue();
|
||||||
|
postInvalidate();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
translationYAnim.start();
|
||||||
|
|
||||||
|
animators.add(translationXAnim);
|
||||||
|
animators.add(translationYAnim);
|
||||||
|
}
|
||||||
|
|
||||||
|
ValueAnimator scaleAnim=ValueAnimator.ofFloat(1,0.5f,1,0.5f,1);
|
||||||
|
scaleAnim.setDuration(1600);
|
||||||
|
scaleAnim.setInterpolator(new LinearInterpolator());
|
||||||
|
scaleAnim.setRepeatCount(-1);
|
||||||
|
scaleAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
||||||
|
@Override
|
||||||
|
public void onAnimationUpdate(ValueAnimator animation) {
|
||||||
|
scaleFloat = (float) animation.getAnimatedValue();
|
||||||
|
postInvalidate();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
scaleAnim.start();
|
||||||
|
|
||||||
|
ValueAnimator rotateAnim=ValueAnimator.ofFloat(0,180,360,1.5f*360,2*360);
|
||||||
|
rotateAnim.setDuration(1600);
|
||||||
|
rotateAnim.setInterpolator(new LinearInterpolator());
|
||||||
|
rotateAnim.setRepeatCount(-1);
|
||||||
|
rotateAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
||||||
|
@Override
|
||||||
|
public void onAnimationUpdate(ValueAnimator animation) {
|
||||||
|
degrees = (float) animation.getAnimatedValue();
|
||||||
|
postInvalidate();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
rotateAnim.start();
|
||||||
|
|
||||||
|
animators.add(scaleAnim);
|
||||||
|
animators.add(rotateAnim);
|
||||||
|
return animators;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
package com.rmondjone.xrecyclerview.progressindicator.indicator;
|
||||||
|
|
||||||
|
import android.animation.Animator;
|
||||||
|
import android.animation.ValueAnimator;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.graphics.RectF;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Jack on 2015/10/19.
|
||||||
|
*/
|
||||||
|
public class LineScaleIndicator extends BaseIndicatorController {
|
||||||
|
|
||||||
|
public static final float SCALE=1.0f;
|
||||||
|
|
||||||
|
float[] scaleYFloats=new float[]{SCALE,
|
||||||
|
SCALE,
|
||||||
|
SCALE,
|
||||||
|
SCALE,
|
||||||
|
SCALE,};
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(Canvas canvas, Paint paint) {
|
||||||
|
float translateX=getWidth()/11;
|
||||||
|
float translateY=getHeight()/2;
|
||||||
|
for (int i = 0; i < 5; i++) {
|
||||||
|
canvas.save();
|
||||||
|
canvas.translate((2 + i * 2) * translateX - translateX / 2, translateY);
|
||||||
|
canvas.scale(SCALE, scaleYFloats[i]);
|
||||||
|
RectF rectF=new RectF(-translateX/2,-getHeight()/2.5f,translateX/2,getHeight()/2.5f);
|
||||||
|
canvas.drawRoundRect(rectF, 5, 5, paint);
|
||||||
|
canvas.restore();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Animator> createAnimation() {
|
||||||
|
List<Animator> animators=new ArrayList<>();
|
||||||
|
long[] delays=new long[]{100,200,300,400,500};
|
||||||
|
for (int i = 0; i < 5; i++) {
|
||||||
|
final int index=i;
|
||||||
|
ValueAnimator scaleAnim=ValueAnimator.ofFloat(1, 0.4f, 1);
|
||||||
|
scaleAnim.setDuration(1000);
|
||||||
|
scaleAnim.setRepeatCount(-1);
|
||||||
|
scaleAnim.setStartDelay(delays[i]);
|
||||||
|
scaleAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
||||||
|
@Override
|
||||||
|
public void onAnimationUpdate(ValueAnimator animation) {
|
||||||
|
scaleYFloats[index] = (float) animation.getAnimatedValue();
|
||||||
|
postInvalidate();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
scaleAnim.start();
|
||||||
|
animators.add(scaleAnim);
|
||||||
|
}
|
||||||
|
return animators;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
package com.rmondjone.xrecyclerview.progressindicator.indicator;
|
||||||
|
|
||||||
|
import android.animation.Animator;
|
||||||
|
import android.animation.ValueAnimator;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.graphics.RectF;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Jack on 2015/10/19.
|
||||||
|
*/
|
||||||
|
public class LineScalePartyIndicator extends BaseIndicatorController {
|
||||||
|
|
||||||
|
public static final float SCALE=1.0f;
|
||||||
|
|
||||||
|
float[] scaleFloats=new float[]{SCALE,
|
||||||
|
SCALE,
|
||||||
|
SCALE,
|
||||||
|
SCALE,
|
||||||
|
SCALE,};
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(Canvas canvas, Paint paint) {
|
||||||
|
float translateX=getWidth()/9;
|
||||||
|
float translateY=getHeight()/2;
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
canvas.save();
|
||||||
|
canvas.translate((2 + i * 2) * translateX - translateX / 2, translateY);
|
||||||
|
canvas.scale(scaleFloats[i], scaleFloats[i]);
|
||||||
|
RectF rectF=new RectF(-translateX/2,-getHeight()/2.5f,translateX/2,getHeight()/2.5f);
|
||||||
|
canvas.drawRoundRect(rectF,5,5,paint);
|
||||||
|
canvas.restore();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Animator> createAnimation() {
|
||||||
|
List<Animator> animators=new ArrayList<>();
|
||||||
|
long[] durations=new long[]{1260, 430, 1010, 730};
|
||||||
|
long[] delays=new long[]{770, 290, 280, 740};
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
final int index=i;
|
||||||
|
ValueAnimator scaleAnim=ValueAnimator.ofFloat(1,0.4f,1);
|
||||||
|
scaleAnim.setDuration(durations[i]);
|
||||||
|
scaleAnim.setRepeatCount(-1);
|
||||||
|
scaleAnim.setStartDelay(delays[i]);
|
||||||
|
scaleAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
||||||
|
@Override
|
||||||
|
public void onAnimationUpdate(ValueAnimator animation) {
|
||||||
|
scaleFloats[index] = (float) animation.getAnimatedValue();
|
||||||
|
postInvalidate();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
scaleAnim.start();
|
||||||
|
animators.add(scaleAnim);
|
||||||
|
}
|
||||||
|
return animators;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
package com.rmondjone.xrecyclerview.progressindicator.indicator;
|
||||||
|
|
||||||
|
import android.animation.Animator;
|
||||||
|
import android.animation.ValueAnimator;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Jack on 2015/10/19.
|
||||||
|
*/
|
||||||
|
public class LineScalePulseOutIndicator extends LineScaleIndicator {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Animator> createAnimation() {
|
||||||
|
List<Animator> animators=new ArrayList<>();
|
||||||
|
long[] delays=new long[]{500,250,0,250,500};
|
||||||
|
for (int i = 0; i < 5; i++) {
|
||||||
|
final int index=i;
|
||||||
|
ValueAnimator scaleAnim=ValueAnimator.ofFloat(1,0.3f,1);
|
||||||
|
scaleAnim.setDuration(900);
|
||||||
|
scaleAnim.setRepeatCount(-1);
|
||||||
|
scaleAnim.setStartDelay(delays[i]);
|
||||||
|
scaleAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
||||||
|
@Override
|
||||||
|
public void onAnimationUpdate(ValueAnimator animation) {
|
||||||
|
scaleYFloats[index] = (float) animation.getAnimatedValue();
|
||||||
|
postInvalidate();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
scaleAnim.start();
|
||||||
|
animators.add(scaleAnim);
|
||||||
|
}
|
||||||
|
return animators;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
package com.rmondjone.xrecyclerview.progressindicator.indicator;
|
||||||
|
|
||||||
|
import android.animation.Animator;
|
||||||
|
import android.animation.ValueAnimator;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Jack on 2015/10/19.
|
||||||
|
*/
|
||||||
|
public class LineScalePulseOutRapidIndicator extends LineScaleIndicator {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Animator> createAnimation() {
|
||||||
|
List<Animator> animators=new ArrayList<>();
|
||||||
|
long[] delays=new long[]{400,200,0,200,400};
|
||||||
|
for (int i = 0; i < 5; i++) {
|
||||||
|
final int index=i;
|
||||||
|
ValueAnimator scaleAnim=ValueAnimator.ofFloat(1,0.4f,1);
|
||||||
|
scaleAnim.setDuration(1000);
|
||||||
|
scaleAnim.setRepeatCount(-1);
|
||||||
|
scaleAnim.setStartDelay(delays[i]);
|
||||||
|
scaleAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
||||||
|
@Override
|
||||||
|
public void onAnimationUpdate(ValueAnimator animation) {
|
||||||
|
scaleYFloats[index] = (float) animation.getAnimatedValue();
|
||||||
|
postInvalidate();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
scaleAnim.start();
|
||||||
|
animators.add(scaleAnim);
|
||||||
|
}
|
||||||
|
return animators;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
package com.rmondjone.xrecyclerview.progressindicator.indicator;
|
||||||
|
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.graphics.RectF;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Jack on 2015/10/24.
|
||||||
|
* Email:81813780@qq.com
|
||||||
|
*/
|
||||||
|
public class LineSpinFadeLoaderIndicator extends BallSpinFadeLoaderIndicator {
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(Canvas canvas, Paint paint) {
|
||||||
|
float radius=getWidth()/10;
|
||||||
|
for (int i = 0; i < 8; i++) {
|
||||||
|
canvas.save();
|
||||||
|
Point point=circleAt(getWidth(),getHeight(),getWidth()/2.5f-radius,i*(Math.PI/4));
|
||||||
|
canvas.translate(point.x, point.y);
|
||||||
|
canvas.scale(scaleFloats[i], scaleFloats[i]);
|
||||||
|
canvas.rotate(i*45);
|
||||||
|
paint.setAlpha(alphas[i]);
|
||||||
|
RectF rectF=new RectF(-radius,-radius/1.5f,1.5f*radius,radius/1.5f);
|
||||||
|
canvas.drawRoundRect(rectF,5,5,paint);
|
||||||
|
canvas.restore();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,119 @@
|
|||||||
|
package com.rmondjone.xrecyclerview.progressindicator.indicator;
|
||||||
|
|
||||||
|
import android.animation.Animator;
|
||||||
|
import android.animation.ValueAnimator;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.graphics.RectF;
|
||||||
|
import android.view.animation.LinearInterpolator;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Jack on 2015/10/16.
|
||||||
|
*/
|
||||||
|
public class PacmanIndicator extends BaseIndicatorController{
|
||||||
|
|
||||||
|
private float translateX;
|
||||||
|
|
||||||
|
private int alpha;
|
||||||
|
|
||||||
|
private float degrees1,degrees2;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(Canvas canvas, Paint paint) {
|
||||||
|
drawPacman(canvas,paint);
|
||||||
|
drawCircle(canvas,paint);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void drawPacman(Canvas canvas,Paint paint){
|
||||||
|
float x=getWidth()/2;
|
||||||
|
float y=getHeight()/2;
|
||||||
|
|
||||||
|
canvas.save();
|
||||||
|
|
||||||
|
canvas.translate(x, y);
|
||||||
|
canvas.rotate(degrees1);
|
||||||
|
paint.setAlpha(255);
|
||||||
|
RectF rectF1=new RectF(-x/1.7f,-y/1.7f,x/1.7f,y/1.7f);
|
||||||
|
canvas.drawArc(rectF1, 0, 270, true, paint);
|
||||||
|
|
||||||
|
canvas.restore();
|
||||||
|
|
||||||
|
canvas.save();
|
||||||
|
canvas.translate(x, y);
|
||||||
|
canvas.rotate(degrees2);
|
||||||
|
paint.setAlpha(255);
|
||||||
|
RectF rectF2=new RectF(-x/1.7f,-y/1.7f,x/1.7f,y/1.7f);
|
||||||
|
canvas.drawArc(rectF2,90,270,true,paint);
|
||||||
|
canvas.restore();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void drawCircle(Canvas canvas, Paint paint) {
|
||||||
|
float radius=getWidth()/11;
|
||||||
|
paint.setAlpha(alpha);
|
||||||
|
canvas.drawCircle(translateX, getHeight() / 2, radius, paint);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Animator> createAnimation() {
|
||||||
|
List<Animator> animators=new ArrayList<>();
|
||||||
|
float startT=getWidth()/11;
|
||||||
|
ValueAnimator translationAnim=ValueAnimator.ofFloat(getWidth()-startT,getWidth()/2);
|
||||||
|
translationAnim.setDuration(650);
|
||||||
|
translationAnim.setInterpolator(new LinearInterpolator());
|
||||||
|
translationAnim.setRepeatCount(-1);
|
||||||
|
translationAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
||||||
|
@Override
|
||||||
|
public void onAnimationUpdate(ValueAnimator animation) {
|
||||||
|
translateX = (float) animation.getAnimatedValue();
|
||||||
|
postInvalidate();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
translationAnim.start();
|
||||||
|
|
||||||
|
ValueAnimator alphaAnim=ValueAnimator.ofInt(255,122);
|
||||||
|
alphaAnim.setDuration(650);
|
||||||
|
alphaAnim.setRepeatCount(-1);
|
||||||
|
alphaAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
||||||
|
@Override
|
||||||
|
public void onAnimationUpdate(ValueAnimator animation) {
|
||||||
|
alpha = (int) animation.getAnimatedValue();
|
||||||
|
postInvalidate();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
alphaAnim.start();
|
||||||
|
|
||||||
|
ValueAnimator rotateAnim1=ValueAnimator.ofFloat(0, 45, 0);
|
||||||
|
rotateAnim1.setDuration(650);
|
||||||
|
rotateAnim1.setRepeatCount(-1);
|
||||||
|
rotateAnim1.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
||||||
|
@Override
|
||||||
|
public void onAnimationUpdate(ValueAnimator animation) {
|
||||||
|
degrees1 = (float) animation.getAnimatedValue();
|
||||||
|
postInvalidate();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
rotateAnim1.start();
|
||||||
|
|
||||||
|
ValueAnimator rotateAnim2=ValueAnimator.ofFloat(0,-45,0);
|
||||||
|
rotateAnim2.setDuration(650);
|
||||||
|
rotateAnim2.setRepeatCount(-1);
|
||||||
|
rotateAnim2.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
||||||
|
@Override
|
||||||
|
public void onAnimationUpdate(ValueAnimator animation) {
|
||||||
|
degrees2 = (float) animation.getAnimatedValue();
|
||||||
|
postInvalidate();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
rotateAnim2.start();
|
||||||
|
|
||||||
|
animators.add(translationAnim);
|
||||||
|
animators.add(alphaAnim);
|
||||||
|
animators.add(rotateAnim1);
|
||||||
|
animators.add(rotateAnim2);
|
||||||
|
return animators;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
package com.rmondjone.xrecyclerview.progressindicator.indicator;
|
||||||
|
|
||||||
|
import android.animation.Animator;
|
||||||
|
import android.animation.ObjectAnimator;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.graphics.RectF;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Jack on 2015/10/20.
|
||||||
|
*/
|
||||||
|
public class SemiCircleSpinIndicator extends BaseIndicatorController {
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(Canvas canvas, Paint paint) {
|
||||||
|
RectF rectF=new RectF(0,0,getWidth(),getHeight());
|
||||||
|
canvas.drawArc(rectF,-60,120,false,paint);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Animator> createAnimation() {
|
||||||
|
List<Animator> animators=new ArrayList<>();
|
||||||
|
ObjectAnimator rotateAnim=ObjectAnimator.ofFloat(getTarget(),"rotation",0,180,360);
|
||||||
|
rotateAnim.setDuration(600);
|
||||||
|
rotateAnim.setRepeatCount(-1);
|
||||||
|
rotateAnim.start();
|
||||||
|
animators.add(rotateAnim);
|
||||||
|
return animators;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
package com.rmondjone.xrecyclerview.progressindicator.indicator;
|
||||||
|
|
||||||
|
import android.animation.Animator;
|
||||||
|
import android.animation.ObjectAnimator;
|
||||||
|
import android.animation.PropertyValuesHolder;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.graphics.RectF;
|
||||||
|
import android.view.animation.LinearInterpolator;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Jack on 2015/10/16.
|
||||||
|
*/
|
||||||
|
public class SquareSpinIndicator extends BaseIndicatorController {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(Canvas canvas, Paint paint) {
|
||||||
|
canvas.drawRect(new RectF(getWidth()/5,getHeight()/5,getWidth()*4/5,getHeight()*4/5),paint);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Animator> createAnimation() {
|
||||||
|
List<Animator> animators=new ArrayList<>();
|
||||||
|
PropertyValuesHolder rotation5=PropertyValuesHolder.ofFloat("rotationX",0,180,180,0,0);
|
||||||
|
PropertyValuesHolder rotation6=PropertyValuesHolder.ofFloat("rotationY",0,0,180,180,0);
|
||||||
|
ObjectAnimator animator=ObjectAnimator.ofPropertyValuesHolder(getTarget(), rotation6,rotation5);
|
||||||
|
animator.setInterpolator(new LinearInterpolator());
|
||||||
|
animator.setRepeatCount(-1);
|
||||||
|
animator.setDuration(2500);
|
||||||
|
animator.start();
|
||||||
|
animators.add(animator);
|
||||||
|
return animators;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
package com.rmondjone.xrecyclerview.progressindicator.indicator;
|
||||||
|
|
||||||
|
import android.animation.Animator;
|
||||||
|
import android.animation.ObjectAnimator;
|
||||||
|
import android.animation.PropertyValuesHolder;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.graphics.Path;
|
||||||
|
import android.view.animation.LinearInterpolator;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Jack on 2015/10/20.
|
||||||
|
*/
|
||||||
|
public class TriangleSkewSpinIndicator extends BaseIndicatorController {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(Canvas canvas, Paint paint) {
|
||||||
|
Path path=new Path();
|
||||||
|
path.moveTo(getWidth()/5,getHeight()*4/5);
|
||||||
|
path.lineTo(getWidth()*4/5, getHeight()*4/5);
|
||||||
|
path.lineTo(getWidth()/2,getHeight()/5);
|
||||||
|
path.close();
|
||||||
|
canvas.drawPath(path, paint);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Animator> createAnimation() {
|
||||||
|
List<Animator> animators=new ArrayList<>();
|
||||||
|
PropertyValuesHolder rotation5=PropertyValuesHolder.ofFloat("rotationX",0,180,180,0,0);
|
||||||
|
PropertyValuesHolder rotation6=PropertyValuesHolder.ofFloat("rotationY",0,0,180,180,0);
|
||||||
|
|
||||||
|
ObjectAnimator animator=ObjectAnimator.ofPropertyValuesHolder(getTarget(), rotation6,rotation5);
|
||||||
|
animator.setInterpolator(new LinearInterpolator());
|
||||||
|
animator.setRepeatCount(-1);
|
||||||
|
animator.setDuration(2500);
|
||||||
|
animator.start();
|
||||||
|
|
||||||
|
animators.add(animator);
|
||||||
|
return animators;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
BIN
locktableview/src/main/res/drawable/ic_loading_rotate.png
Normal file
|
After Width: | Height: | Size: 444 B |
BIN
locktableview/src/main/res/drawable/ic_pulltorefresh_arrow.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
locktableview/src/main/res/drawable/iconfont_downgrey.png
Normal file
|
After Width: | Height: | Size: 486 B |
BIN
locktableview/src/main/res/drawable/loading_01.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
locktableview/src/main/res/drawable/loading_02.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
locktableview/src/main/res/drawable/loading_03.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
locktableview/src/main/res/drawable/loading_04.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
locktableview/src/main/res/drawable/loading_05.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
locktableview/src/main/res/drawable/loading_06.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
locktableview/src/main/res/drawable/loading_07.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
locktableview/src/main/res/drawable/loading_08.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
locktableview/src/main/res/drawable/loading_09.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
locktableview/src/main/res/drawable/loading_10.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
locktableview/src/main/res/drawable/loading_11.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
locktableview/src/main/res/drawable/loading_12.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
16
locktableview/src/main/res/drawable/progressbar.xml
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<animation-list android:oneshot="false"
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item android:duration="100" android:drawable="@drawable/loading_01" />
|
||||||
|
<item android:duration="100" android:drawable="@drawable/loading_02" />
|
||||||
|
<item android:duration="100" android:drawable="@drawable/loading_03" />
|
||||||
|
<item android:duration="100" android:drawable="@drawable/loading_04" />
|
||||||
|
<item android:duration="100" android:drawable="@drawable/loading_05" />
|
||||||
|
<item android:duration="100" android:drawable="@drawable/loading_06" />
|
||||||
|
<item android:duration="100" android:drawable="@drawable/loading_07" />
|
||||||
|
<item android:duration="100" android:drawable="@drawable/loading_08" />
|
||||||
|
<item android:duration="100" android:drawable="@drawable/loading_09" />
|
||||||
|
<item android:duration="100" android:drawable="@drawable/loading_10" />
|
||||||
|
<item android:duration="100" android:drawable="@drawable/loading_11" />
|
||||||
|
<item android:duration="100" android:drawable="@drawable/loading_12" />
|
||||||
|
</animation-list>
|
||||||
3
locktableview/src/main/res/drawable/progressloading.xml
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<animated-rotate android:drawable="@drawable/ic_loading_rotate" android:pivotX="50.0%" android:pivotY="50.0%"
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android" />
|
||||||
21
locktableview/src/main/res/layout/listview_footer.xml
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="center"
|
||||||
|
android:padding="3dp">
|
||||||
|
<ProgressBar
|
||||||
|
android:id="@+id/listview_foot_progress"
|
||||||
|
android:layout_width="30dip"
|
||||||
|
android:layout_height="30dip"
|
||||||
|
/>
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/listview_foot_more"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="center"
|
||||||
|
android:padding="5dp"
|
||||||
|
android:text="加载中..."/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
70
locktableview/src/main/res/layout/listview_header.xml
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="bottom" >
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:id="@+id/listview_header_content"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="80dp"
|
||||||
|
android:paddingTop="10dip"
|
||||||
|
>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:minWidth="100dip"
|
||||||
|
android:layout_centerInParent="true"
|
||||||
|
android:gravity="center"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:id="@+id/listview_header_text">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/refresh_status_textview"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/listview_header_hint_normal" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:visibility="gone"
|
||||||
|
android:layout_marginTop="3dp" >
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/listview_header_last_time"
|
||||||
|
android:textSize="12sp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/last_refresh_time"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textSize="12sp" />
|
||||||
|
</LinearLayout>
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/listview_header_arrow"
|
||||||
|
android:layout_width="20dp"
|
||||||
|
android:layout_height="40dp"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
android:layout_marginLeft="35dp"
|
||||||
|
android:layout_marginRight="10dp"
|
||||||
|
android:layout_toLeftOf="@id/listview_header_text"
|
||||||
|
android:src="@drawable/ic_pulltorefresh_arrow" />
|
||||||
|
|
||||||
|
<com.rmondjone.xrecyclerview.SimpleViewSwitcher
|
||||||
|
android:id="@+id/listview_header_progressbar"
|
||||||
|
android:layout_width="30dip"
|
||||||
|
android:layout_height="30dip"
|
||||||
|
android:layout_toLeftOf="@id/listview_header_text"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
android:layout_marginLeft="40dp"
|
||||||
|
android:layout_marginRight="10dp"
|
||||||
|
android:visibility="invisible" />
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
18
locktableview/src/main/res/layout/lock_item.xml
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:orientation="vertical" android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
>
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/lock_linearlayout"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
<TextView
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:gravity="center"
|
||||||
|
android:id="@+id/lock_text"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content" />
|
||||||
|
</LinearLayout>
|
||||||
|
</LinearLayout>
|
||||||
34
locktableview/src/main/res/layout/locktablecontentview.xml
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
<?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">
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/lock_recyclerview"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
</androidx.recyclerview.widget.RecyclerView>
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="1dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="@color/light_gray"
|
||||||
|
android:visibility="gone"/>
|
||||||
|
|
||||||
|
<com.rmondjone.locktableview.CustomHorizontalScrollView
|
||||||
|
android:scrollbars="none"
|
||||||
|
android:id="@+id/lockScrollView_parent"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/main_recyclerview"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
</androidx.recyclerview.widget.RecyclerView>
|
||||||
|
|
||||||
|
</com.rmondjone.locktableview.CustomHorizontalScrollView>
|
||||||
|
</LinearLayout>
|
||||||
61
locktableview/src/main/res/layout/locktableview.xml
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="@color/transparent"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/lockHeadView"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="@color/table_head"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/lockHeadView_Text"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="center"
|
||||||
|
android:textColor="@color/beijin" />
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="1dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="@color/transparent" />
|
||||||
|
|
||||||
|
<com.rmondjone.locktableview.CustomHorizontalScrollView
|
||||||
|
android:id="@+id/lockHeadView_ScrollView"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:scrollbars="none">
|
||||||
|
|
||||||
|
</com.rmondjone.locktableview.CustomHorizontalScrollView>
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/unLockHeadView"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="@color/table_head"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:visibility="gone">
|
||||||
|
|
||||||
|
<com.rmondjone.locktableview.CustomHorizontalScrollView
|
||||||
|
android:id="@+id/unlockHeadView_ScrollView"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:scrollbars="none">
|
||||||
|
|
||||||
|
</com.rmondjone.locktableview.CustomHorizontalScrollView>
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<com.rmondjone.xrecyclerview.XRecyclerView
|
||||||
|
android:id="@+id/table_scrollView"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
</com.rmondjone.xrecyclerview.XRecyclerView>
|
||||||
|
</LinearLayout>
|
||||||
73
locktableview/src/main/res/layout/pull_to_refresh_head.xml
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="fill_parent"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:id="@+id/head_contentLayout"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="fill_parent"
|
||||||
|
android:paddingTop="10dip"
|
||||||
|
android:paddingBottom="15dip">
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="fill_parent"
|
||||||
|
android:layout_alignParentLeft="true"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
android:layout_marginLeft="30dip"
|
||||||
|
android:layout_marginRight="20dip">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/head_arrowImageView"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:src="@drawable/ic_pulltorefresh_arrow" />
|
||||||
|
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="fill_parent"
|
||||||
|
android:layout_alignParentLeft="true"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
android:layout_marginLeft="100dip"
|
||||||
|
android:layout_marginRight="10dip">
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/head_progressBar"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:src="@drawable/progressbar"
|
||||||
|
android:visibility="gone"
|
||||||
|
/>
|
||||||
|
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_centerInParent="true"
|
||||||
|
android:gravity="center_horizontal"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/head_tipsTextView"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/listview_header_hint_normal"
|
||||||
|
android:textColor="#000000"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/head_lastUpdatedTextView"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textColor="#000000"
|
||||||
|
android:textSize="10sp" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
14
locktableview/src/main/res/layout/unlock_item.xml
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:orientation="vertical" android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/unlock_linearlayout"
|
||||||
|
android:gravity="center"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
</LinearLayout>
|
||||||
|
</LinearLayout>
|
||||||
10
locktableview/src/main/res/values-zh/strings.xml
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<resources>
|
||||||
|
<string name="listview_header_hint_normal">下拉刷新</string>
|
||||||
|
<string name="listview_header_hint_release">释放立即刷新</string>
|
||||||
|
<string name="listview_loading">正在加载...</string>
|
||||||
|
<string name="nomore_loading">数据已全部加载结束</string>
|
||||||
|
<string name="refreshing">正在刷新...</string>
|
||||||
|
<string name="refresh_done">刷新完成</string>
|
||||||
|
<string name="loading_done">加载完成</string>
|
||||||
|
<string name="listview_header_last_time">上次更新时间:</string>
|
||||||
|
</resources>
|
||||||
38
locktableview/src/main/res/values/attrs.xml
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
|
||||||
|
<declare-styleable name="AVLoadingIndicatorView">
|
||||||
|
<attr name="indicator">
|
||||||
|
<flag name="BallPulse" value="0"/>
|
||||||
|
<flag name="BallGridPulse" value="1"/>
|
||||||
|
<flag name="BallClipRotate" value="2"/>
|
||||||
|
<flag name="BallClipRotatePulse" value="3"/>
|
||||||
|
<flag name="SquareSpin" value="4"/>
|
||||||
|
<flag name="BallClipRotateMultiple" value="5"/>
|
||||||
|
<flag name="BallPulseRise" value="6"/>
|
||||||
|
<flag name="BallRotate" value="7"/>
|
||||||
|
<flag name="CubeTransition" value="8"/>
|
||||||
|
<flag name="BallZigZag" value="9"/>
|
||||||
|
<flag name="BallZigZagDeflect" value="10"/>
|
||||||
|
<flag name="BallTrianglePath" value="11"/>
|
||||||
|
<flag name="BallScale" value="12"/>
|
||||||
|
<flag name="LineScale" value="13"/>
|
||||||
|
<flag name="LineScaleParty" value="14"/>
|
||||||
|
<flag name="BallScaleMultiple" value="15"/>
|
||||||
|
<flag name="BallPulseSync" value="16"/>
|
||||||
|
<flag name="BallBeat" value="17"/>
|
||||||
|
<flag name="LineScalePulseOut" value="18"/>
|
||||||
|
<flag name="LineScalePulseOutRapid" value="19"/>
|
||||||
|
<flag name="BallScaleRipple" value="20"/>
|
||||||
|
<flag name="BallScaleRippleMultiple" value="21"/>
|
||||||
|
<flag name="BallSpinFadeLoader" value="22"/>
|
||||||
|
<flag name="LineSpinFadeLoader" value="23"/>
|
||||||
|
<flag name="TriangleSkewSpin" value="24"/>
|
||||||
|
<flag name="Pacman" value="25"/>
|
||||||
|
<flag name="BallGridBeat" value="26"/>
|
||||||
|
<flag name="SemiCircleSpin" value="27"/>
|
||||||
|
</attr>
|
||||||
|
<attr name="indicator_color" format="color"/>
|
||||||
|
</declare-styleable>
|
||||||
|
|
||||||
|
</resources>
|
||||||
56
locktableview/src/main/res/values/colors.xml
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
|
||||||
|
<!-- 颜色 -->
|
||||||
|
<color name="color_hei_8">#00000000</color>
|
||||||
|
<color name="forget_pwd">#334E6C</color>
|
||||||
|
<color name="table_head">#E5EFFE</color>
|
||||||
|
<color name="black">#FF000000</color>
|
||||||
|
<color name="white">#FFFFFFFF</color>
|
||||||
|
<color name="light_gray">#e6e6e6</color>
|
||||||
|
<color name="light_gray2">#fafafa</color>
|
||||||
|
<color name="deep_gray">#555555</color>
|
||||||
|
<color name="deep_red">#FF0033</color>
|
||||||
|
<color name="light_yellow2">#ADD8E6</color>
|
||||||
|
<color name="border_color">#817F80</color>
|
||||||
|
<color name="blue">#0000ff</color>
|
||||||
|
<color name="transparent">#00000000</color>
|
||||||
|
<color name="green">#0F0</color>
|
||||||
|
<color name="red">#FF0000</color>
|
||||||
|
<color name="jt1">#DDDDDD</color>
|
||||||
|
<color name="first">#b8b8b8</color>
|
||||||
|
<color name="first_dianji">#0cb9f5</color>
|
||||||
|
<color name="beijin">#2c8fd3</color>
|
||||||
|
<color name="orange">#ffa500</color>
|
||||||
|
<color name="tv_textblackcolor">#000000</color>
|
||||||
|
<color name="calendar_background">#e3eef4</color>
|
||||||
|
<color name="selection">#b1dce2ff</color>
|
||||||
|
<color name="calendar_zhe_day">#faedda</color>
|
||||||
|
<color name="event_center">#ff6bd697</color>
|
||||||
|
<color name="noMonth">#c0c0c0</color>
|
||||||
|
<color name="text_6">#FFf3feff</color>
|
||||||
|
<color name="text_7">#FFfff1f2</color>
|
||||||
|
<color name="Text">#603b07</color>
|
||||||
|
<color name="lv_cacheColorHint">#00000000</color>
|
||||||
|
<color name="ll_background_10501">#31abfe</color>
|
||||||
|
<color name="list_item_click">#76c120</color>
|
||||||
|
<color name="white_bg_10531M">#ffffffff</color>
|
||||||
|
<color name="txtToDay">#EE4000</color>
|
||||||
|
<color name="green_bg_10531M">#fff2f9ec</color>
|
||||||
|
<color name="ll_graybg">#EDEDE4</color>
|
||||||
|
<color name="search_editbg">#E8E8E8</color>
|
||||||
|
<color name="text_color">#ff434343</color>
|
||||||
|
<color name="review_bac">#FAFAFA</color>
|
||||||
|
<color name="review_pep">#3C70A6</color>
|
||||||
|
<color name="review_time">#C3C4C9</color>
|
||||||
|
<color name="review_content">#262B31</color>
|
||||||
|
<color name="horizontal_divider">#CED7DF</color>
|
||||||
|
<color name="comment_text">#7B7B7B</color>
|
||||||
|
<color name="comment_text_bottom">#949494</color>
|
||||||
|
<color name="horizontal_toutiao">#1989E0</color>
|
||||||
|
<color name="tabtitle_color">#CFEDF9</color>
|
||||||
|
<color name="tabitem_color1">#FFFFFF</color>
|
||||||
|
<color name="tabitem_color2">#F7F8F9</color>
|
||||||
|
<color name="dashline_color">#C2C0C2</color>
|
||||||
|
|
||||||
|
</resources>
|
||||||
4
locktableview/src/main/res/values/dimens.xml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
<resources>
|
||||||
|
<!-- Default screen margins, per the Android Design guidelines. -->
|
||||||
|
<dimen name="textandiconmargin">10dp</dimen>
|
||||||
|
</resources>
|
||||||
10
locktableview/src/main/res/values/strings.xml
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<resources>
|
||||||
|
<string name="listview_header_hint_normal">pull to refresh</string>
|
||||||
|
<string name="listview_header_hint_release">release to start refresh</string>
|
||||||
|
<string name="listview_loading">loading...</string>
|
||||||
|
<string name="nomore_loading">no more to be loaded</string>
|
||||||
|
<string name="refreshing">refreshing...</string>
|
||||||
|
<string name="refresh_done">refresh done</string>
|
||||||
|
<string name="loading_done">loading done</string>
|
||||||
|
<string name="listview_header_last_time">last update:</string>
|
||||||
|
</resources>
|
||||||
@@ -18,11 +18,7 @@ import com.xscm.modulelogin.present.ImproveInfoPresenter;
|
|||||||
import com.xscm.modulemain.activity.MainActivity;
|
import com.xscm.modulemain.activity.MainActivity;
|
||||||
import com.xscm.moduleutil.activity.BaseMvpActivity;
|
import com.xscm.moduleutil.activity.BaseMvpActivity;
|
||||||
import com.xscm.moduleutil.bean.UserBean;
|
import com.xscm.moduleutil.bean.UserBean;
|
||||||
import com.xscm.moduleutil.utils.DateSelectDialog;
|
import com.xscm.moduleutil.utils.*;
|
||||||
import com.xscm.moduleutil.utils.GlideEngine;
|
|
||||||
import com.xscm.moduleutil.utils.ImageLoader;
|
|
||||||
import com.xscm.moduleutil.utils.ImageUtils;
|
|
||||||
import com.xscm.moduleutil.utils.SpUtil;
|
|
||||||
import com.xscm.moduleutil.widget.Constants;
|
import com.xscm.moduleutil.widget.Constants;
|
||||||
|
|
||||||
|
|
||||||
@@ -201,6 +197,7 @@ public class ImproveInfoActivity extends BaseMvpActivity<ImproveInfoPresenter, A
|
|||||||
.setSelectorUIStyle(new PictureSelectorStyle())
|
.setSelectorUIStyle(new PictureSelectorStyle())
|
||||||
.isGif(false)
|
.isGif(false)
|
||||||
.setImageEngine(GlideEngine.createGlideEngine())
|
.setImageEngine(GlideEngine.createGlideEngine())
|
||||||
|
.setPermissionDescriptionListener(PermissionDescriptionHelper.createListener())
|
||||||
.setMaxSelectNum(1)
|
.setMaxSelectNum(1)
|
||||||
.isPreviewImage(true)
|
.isPreviewImage(true)
|
||||||
.isDisplayCamera(false)
|
.isDisplayCamera(false)
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tool="http://schemas.android.com/tools">
|
||||||
|
|
||||||
<data>
|
<data>
|
||||||
|
|
||||||
@@ -216,7 +217,7 @@
|
|||||||
android:background="@drawable/bg_r100_hui"
|
android:background="@drawable/bg_r100_hui"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:singleLine="true"
|
android:singleLine="true"
|
||||||
android:text="2001"
|
tool:text="2001"
|
||||||
android:textColor="@color/black"
|
android:textColor="@color/black"
|
||||||
android:textSize="16sp"
|
android:textSize="16sp"
|
||||||
android:textStyle="bold" />
|
android:textStyle="bold" />
|
||||||
@@ -241,7 +242,7 @@
|
|||||||
android:background="@drawable/bg_r100_hui"
|
android:background="@drawable/bg_r100_hui"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:singleLine="true"
|
android:singleLine="true"
|
||||||
android:text="12"
|
tool:text="12"
|
||||||
android:textColor="@color/black"
|
android:textColor="@color/black"
|
||||||
android:textSize="16sp"
|
android:textSize="16sp"
|
||||||
android:textStyle="bold" />
|
android:textStyle="bold" />
|
||||||
@@ -266,7 +267,7 @@
|
|||||||
android:background="@drawable/bg_r100_hui"
|
android:background="@drawable/bg_r100_hui"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:singleLine="true"
|
android:singleLine="true"
|
||||||
android:text="1"
|
tool:text="1"
|
||||||
android:textColor="@color/black"
|
android:textColor="@color/black"
|
||||||
android:textSize="16sp"
|
android:textSize="16sp"
|
||||||
android:textStyle="bold" />
|
android:textStyle="bold" />
|
||||||
@@ -285,7 +286,29 @@
|
|||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="@dimen/dp_40"
|
||||||
|
android:layout_marginTop="@dimen/dp_24"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="邀请码"
|
||||||
|
android:textColor="#73000000"
|
||||||
|
android:textSize="16sp"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text=" (非必填)"
|
||||||
|
android:textColor="#33000000"
|
||||||
|
android:textSize="12sp" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
|||||||
@@ -67,8 +67,8 @@ dependencies {
|
|||||||
implementation project(':moduletablayout')
|
implementation project(':moduletablayout')
|
||||||
implementation libs.activity
|
implementation libs.activity
|
||||||
implementation libs.constraintlayout
|
implementation libs.constraintlayout
|
||||||
implementation libs.androidx.appcompat
|
api 'androidx.activity:activity-compose:1.8.2'
|
||||||
implementation libs.androidx.appcompat
|
|
||||||
testImplementation libs.junit
|
testImplementation libs.junit
|
||||||
androidTestImplementation libs.ext.junit
|
androidTestImplementation libs.ext.junit
|
||||||
androidTestImplementation libs.espresso.core
|
androidTestImplementation libs.espresso.core
|
||||||
@@ -169,14 +169,15 @@ dependencies {
|
|||||||
|
|
||||||
//播放器
|
//播放器
|
||||||
//腾讯直播sdk
|
//腾讯直播sdk
|
||||||
api('com.tencent.liteav:LiteAVSDK_Professional:10.9.0.13102')
|
// api('com.tencent.liteav:LiteAVSDK_Professional:10.9.0.13102')
|
||||||
api('com.google.android.exoplayer:exoplayer-core:2.19.1')
|
// api('com.google.android.exoplayer:exoplayer-core:2.19.1')
|
||||||
api('com.google.android.exoplayer:exoplayer-ui:2.19.1')
|
// api('com.google.android.exoplayer:exoplayer-ui:2.19.1')
|
||||||
api("com.egame.vap:animplayer:2.0.8")
|
api("com.egame.vap:animplayer:2.0.8")
|
||||||
api("com.liulishuo.okdownload:okdownload:1.0.7")
|
api("com.liulishuo.okdownload:okdownload:1.0.7")
|
||||||
|
|
||||||
api('com.zlc.glide:webpdecoder:1.6.4.9.0')
|
api('com.zlc.glide:webpdecoder:1.6.4.9.0')
|
||||||
api('com.jungly:gridPasswordView:0.3')
|
api('com.jungly:gridPasswordView:0.3')
|
||||||
|
// 带有气泡的提示框,目前没有使用,暂不使用,使用位置是在RoomTipsView
|
||||||
api('com.cpiz.bubbleview:bubbleview:1.0.2')
|
api('com.cpiz.bubbleview:bubbleview:1.0.2')
|
||||||
|
|
||||||
// 集成音频 SDK声网
|
// 集成音频 SDK声网
|
||||||
|
|||||||
BIN
moduleUtil/src/main/assets/mic.svga
Normal file
@@ -220,85 +220,4 @@ public abstract class BaseMvpActivity<P extends IPresenter, VDB extends ViewData
|
|||||||
return resources;
|
return resources;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 显示全局飘屏消息(支持任意位置飘过)
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
// @Subscribe(threadMode = ThreadMode.MAIN)
|
|
||||||
// public void showPiaoPingMessage(MqttBean mqttBean) {
|
|
||||||
// WindowManager windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
|
|
||||||
// if (windowManager == null) return;
|
|
||||||
//
|
|
||||||
// int screenWidth = getResources().getDisplayMetrics().widthPixels;
|
|
||||||
// int screenHeight = getResources().getDisplayMetrics().heightPixels;
|
|
||||||
//
|
|
||||||
// WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams(
|
|
||||||
// WindowManager.LayoutParams.MATCH_PARENT,
|
|
||||||
// WindowManager.LayoutParams.WRAP_CONTENT,
|
|
||||||
// Build.VERSION.SDK_INT >= Build.VERSION_CODES.O ?
|
|
||||||
// WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY :
|
|
||||||
// WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
|
|
||||||
// WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
|
|
||||||
// WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN |
|
|
||||||
// WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
|
|
||||||
// PixelFormat.TRANSLUCENT);
|
|
||||||
//
|
|
||||||
// // 设置 Gravity 为左上角
|
|
||||||
// layoutParams.gravity = Gravity.TOP | Gravity.START;
|
|
||||||
//
|
|
||||||
// // Y 轴随机位置
|
|
||||||
//// layoutParams.y = (int) ((Math.random() * (screenHeight - 200)));
|
|
||||||
//
|
|
||||||
// // 初始 X 设为负值,确保 View 在屏幕左侧外
|
|
||||||
// layoutParams.x = -screenWidth;
|
|
||||||
//
|
|
||||||
// View piaoPingView = LayoutInflater.from(this).inflate(R.layout.item_piaoping, null);
|
|
||||||
// TextView textView = piaoPingView.findViewById(R.id.tv_name);
|
|
||||||
// TextView textView2 = piaoPingView.findViewById(R.id.tv_to_name);
|
|
||||||
// textView2.setText("送给"+mqttBean.getList().getToUserName());
|
|
||||||
// textView.setText(mqttBean.getList().getFromUserName());
|
|
||||||
// ImageUtils.loadHeadCC(mqttBean.getList().getGift_picture(), piaoPingView.findViewById(R.id.iv_piaoping));
|
|
||||||
// TextView tv_time = piaoPingView.findViewById(R.id.tv_num);
|
|
||||||
// tv_time.setText(mqttBean.getList().getNumber());
|
|
||||||
// windowManager.addView(piaoPingView, layoutParams);
|
|
||||||
//
|
|
||||||
// piaoPingView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
|
|
||||||
// @Override
|
|
||||||
// public void onGlobalLayout() {
|
|
||||||
// piaoPingView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
|
|
||||||
//
|
|
||||||
// // 设置锚点为左上角,避免偏移干扰
|
|
||||||
// piaoPingView.setPivotX(0);
|
|
||||||
// piaoPingView.setPivotY(0);
|
|
||||||
//
|
|
||||||
// // 启动动画:从左外滑入 -> 右外滑出
|
|
||||||
// ObjectAnimator animator = ObjectAnimator.ofFloat(
|
|
||||||
// piaoPingView,
|
|
||||||
// "translationX",
|
|
||||||
// 0f, // 初始偏移为 0(此时 View 在左侧外)
|
|
||||||
// screenWidth // 向右移动整个屏幕宽度
|
|
||||||
// );
|
|
||||||
// animator.setDuration(2000); // 整个动画的时长为2秒
|
|
||||||
//
|
|
||||||
// // 强制 GPU 渲染
|
|
||||||
// piaoPingView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
|
|
||||||
//
|
|
||||||
// // 延迟显示2秒后开始滑出屏幕的动画
|
|
||||||
// piaoPingView.postDelayed(new Runnable() {
|
|
||||||
// @Override
|
|
||||||
// public void run() {
|
|
||||||
// animator.start();
|
|
||||||
// }
|
|
||||||
// }, 3000);
|
|
||||||
//
|
|
||||||
// animator.addListener(new AnimatorListenerAdapter() {
|
|
||||||
// @Override
|
|
||||||
// public void onAnimationEnd(Animator animation) {
|
|
||||||
// windowManager.removeView(piaoPingView);
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import static android.view.View.GONE;
|
|||||||
import static android.view.View.VISIBLE;
|
import static android.view.View.VISIBLE;
|
||||||
import static com.blankj.utilcode.util.ActivityUtils.startActivity;
|
import static com.blankj.utilcode.util.ActivityUtils.startActivity;
|
||||||
|
|
||||||
|
import android.graphics.Color;
|
||||||
import android.text.SpannableStringBuilder;
|
import android.text.SpannableStringBuilder;
|
||||||
import android.text.Spanned;
|
import android.text.Spanned;
|
||||||
import android.text.TextPaint;
|
import android.text.TextPaint;
|
||||||
@@ -128,7 +129,7 @@ public class CirleListAdapter extends BaseQuickAdapter<CircleListBean, BaseViewH
|
|||||||
//头像
|
//头像
|
||||||
// ImageUtils.loadHeadCC(item.getAvatar(), helper.getView(R.id.dy_head_image));
|
// ImageUtils.loadHeadCC(item.getAvatar(), helper.getView(R.id.dy_head_image));
|
||||||
MeHeadView headView = helper.getView(R.id.dy_head_image);
|
MeHeadView headView = helper.getView(R.id.dy_head_image);
|
||||||
headView.setData(item.getAvatar(), "", item.getSex() + "");
|
headView.setData(item.getAvatar(), "", item.getNobility_image());
|
||||||
//动态内容以富文本展示
|
//动态内容以富文本展示
|
||||||
String content = item.getContent();
|
String content = item.getContent();
|
||||||
if (content == null || content.length() == 0) {
|
if (content == null || content.length() == 0) {
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import android.widget.TextView;
|
|||||||
|
|
||||||
import androidx.constraintlayout.widget.ConstraintLayout;
|
import androidx.constraintlayout.widget.ConstraintLayout;
|
||||||
|
|
||||||
|
import com.hjq.toast.ToastUtils;
|
||||||
import com.xscm.moduleutil.R;
|
import com.xscm.moduleutil.R;
|
||||||
import com.xscm.moduleutil.bean.RoonGiftModel;
|
import com.xscm.moduleutil.bean.RoonGiftModel;
|
||||||
import com.xscm.moduleutil.event.RoomGiftClickToEvent;
|
import com.xscm.moduleutil.event.RoomGiftClickToEvent;
|
||||||
@@ -26,6 +27,8 @@ import org.greenrobot.eventbus.EventBus;
|
|||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import static android.view.View.GONE;
|
||||||
|
|
||||||
public class GiftRoomAdapter extends BaseAdapter {
|
public class GiftRoomAdapter extends BaseAdapter {
|
||||||
private final List<RoonGiftModel> mDatas;
|
private final List<RoonGiftModel> mDatas;
|
||||||
private final LayoutInflater inflater;
|
private final LayoutInflater inflater;
|
||||||
@@ -110,39 +113,6 @@ public class GiftRoomAdapter extends BaseAdapter {
|
|||||||
this.mDatas.addAll(newData);
|
this.mDatas.addAll(newData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// private static class MyGestureDetector extends GestureDetector {
|
|
||||||
// private GiftRoomAdapter mAdapter;
|
|
||||||
// private RoonGiftModel mGiftModel;
|
|
||||||
//
|
|
||||||
// public MyGestureDetector(Context context) {
|
|
||||||
// super(context, new SimpleOnGestureListener() {
|
|
||||||
// @Override
|
|
||||||
// public boolean onSingleTapConfirmed(MotionEvent e) {
|
|
||||||
// if (mAdapter != null && mGiftModel != null) {
|
|
||||||
// EventBus.getDefault().post(new RoomGiftClickToEvent(mAdapter, mGiftModel, 1));
|
|
||||||
// }
|
|
||||||
// return true;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// @Override
|
|
||||||
// public boolean onDoubleTap(MotionEvent e) {
|
|
||||||
// if (mAdapter != null && mGiftModel != null) {
|
|
||||||
// EventBus.getDefault().post(new RoomGiftClickToEvent(mAdapter, mGiftModel, 2));
|
|
||||||
// }
|
|
||||||
// return true;
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// setOnDoubleTapListener(getListener());
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// public void setGiftModel(GiftRoomAdapter adapter, RoonGiftModel giftModel) {
|
|
||||||
// this.mAdapter = adapter;
|
|
||||||
// this.mGiftModel = giftModel;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressLint({"SetTextI18n", "ClickableViewAccessibility"})
|
@SuppressLint({"SetTextI18n", "ClickableViewAccessibility"})
|
||||||
public View getView(int position, View convertView, ViewGroup parent) {
|
public View getView(int position, View convertView, ViewGroup parent) {
|
||||||
@@ -157,7 +127,7 @@ public class GiftRoomAdapter extends BaseAdapter {
|
|||||||
viewHolder.item_layout = (ConstraintLayout) convertView.findViewById(R.id.cl_gift);
|
viewHolder.item_layout = (ConstraintLayout) convertView.findViewById(R.id.cl_gift);
|
||||||
viewHolder.ivDownOn = (ImageView) convertView.findViewById(R.id.iv_down_on);
|
viewHolder.ivDownOn = (ImageView) convertView.findViewById(R.id.iv_down_on);
|
||||||
viewHolder.cl_iv_down_on = (ConstraintLayout) convertView.findViewById(R.id.cl_iv_down_on);
|
viewHolder.cl_iv_down_on = (ConstraintLayout) convertView.findViewById(R.id.cl_iv_down_on);
|
||||||
|
viewHolder.iv_gift_select= (ImageView) convertView.findViewById(R.id.iv_gift_select);
|
||||||
convertView.setTag(viewHolder);
|
convertView.setTag(viewHolder);
|
||||||
} else {
|
} else {
|
||||||
viewHolder = (ViewHolder) convertView.getTag();
|
viewHolder = (ViewHolder) convertView.getTag();
|
||||||
@@ -165,10 +135,18 @@ public class GiftRoomAdapter extends BaseAdapter {
|
|||||||
|
|
||||||
viewHolder.item_layout.setOnClickListener(v -> {
|
viewHolder.item_layout.setOnClickListener(v -> {
|
||||||
// RoonGiftModel clickedModel = (RoonGiftModel) v.getTag();
|
// RoonGiftModel clickedModel = (RoonGiftModel) v.getTag();
|
||||||
EventBus.getDefault().post(new RoomGiftClickToEvent(this, giftModel, 1));
|
if (giftModel.getIs_lock()==0) {
|
||||||
|
EventBus.getDefault().post(new RoomGiftClickToEvent(this, giftModel, 1));
|
||||||
|
}else if (giftModel.getIs_lock()==1){
|
||||||
|
ToastUtils.show("当前属于爵位礼物,请开通爵位");
|
||||||
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
if (giftModel.getIs_lock()==0){
|
||||||
|
viewHolder.iv_gift_select.setVisibility(GONE);
|
||||||
|
}else {
|
||||||
|
viewHolder.iv_gift_select.setVisibility(View.VISIBLE);
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* 在给View绑定显示的数据时,计算正确的position = position + curIndex * pageSize,
|
* 在给View绑定显示的数据时,计算正确的position = position + curIndex * pageSize,
|
||||||
*/
|
*/
|
||||||
@@ -193,9 +171,9 @@ public class GiftRoomAdapter extends BaseAdapter {
|
|||||||
|
|
||||||
if (giftModel.isChecked()) {//被选中
|
if (giftModel.isChecked()) {//被选中
|
||||||
viewHolder.cl_iv_down_on.setBackgroundResource(R.mipmap.room_gift_bjx);
|
viewHolder.cl_iv_down_on.setBackgroundResource(R.mipmap.room_gift_bjx);
|
||||||
viewHolder.ivDownOn.setVisibility(View.GONE);
|
viewHolder.ivDownOn.setVisibility(GONE);
|
||||||
} else {
|
} else {
|
||||||
viewHolder.ivDownOn.setVisibility(View.GONE);
|
viewHolder.ivDownOn.setVisibility(GONE);
|
||||||
viewHolder.cl_iv_down_on.setBackgroundResource(0);
|
viewHolder.cl_iv_down_on.setBackgroundResource(0);
|
||||||
}
|
}
|
||||||
//设置
|
//设置
|
||||||
@@ -234,6 +212,7 @@ public class GiftRoomAdapter extends BaseAdapter {
|
|||||||
public ImageView iv_gift_pic;
|
public ImageView iv_gift_pic;
|
||||||
public TextView tv_gift_change_love_values;
|
public TextView tv_gift_change_love_values;
|
||||||
public ImageView ivDownOn;
|
public ImageView ivDownOn;
|
||||||
|
public ImageView iv_gift_select;
|
||||||
public ConstraintLayout cl_iv_down_on;
|
public ConstraintLayout cl_iv_down_on;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||