From 3708b099a7517377e287dcf2c088d91b86e72e8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=90=95=E5=8F=91=E5=BC=BA?= <903019642@qq.com> Date: Tue, 5 Sep 2017 13:31:20 +0800 Subject: [PATCH] upload code --- .gitignore | 9 + .idea/compiler.xml | 22 + .idea/copyright/profiles_settings.xml | 3 + .idea/dictionaries/apple.xml | 3 + .idea/gradle.xml | 19 + .../markdown-navigator/profiles_settings.xml | 3 + .idea/misc.xml | 95 +++ .idea/modules.xml | 9 + .idea/runConfigurations.xml | 12 + .idea/vcs.xml | 6 + app/.gitignore | 1 + app/build.gradle | 38 + app/proguard-rules.pro | 17 + .../ExampleInstrumentedTest.java | 26 + app/src/main/AndroidManifest.xml | 26 + .../main/java/com/lvfq/code/BaseActivity.java | 46 ++ .../com/lvfq/code/ImageWaterMarkActivity.java | 150 ++++ .../main/java/com/lvfq/code/MainActivity.java | 58 ++ .../main/java/com/lvfq/code/ModelBean.java | 66 ++ .../java/com/lvfq/code/MyApplication.java | 25 + .../main/java/com/lvfq/code/NoBodyEntity.java | 14 + .../lvfq/code/annotation/AnnotationTest1.java | 30 + .../lvfq/code/annotation/AnnotationUtil.java | 16 + .../java/com/lvfq/code/annotation/CusBus.java | 77 ++ .../lvfq/code/annotation/OnCusBusEvent.java | 24 + .../java/com/lvfq/code/annotation/Type.java | 15 + .../code/dynamic/CircleMovementMethod.java | 117 +++ .../lvfq/code/dynamic/CommentsActivity.java | 85 +++ .../main/java/com/lvfq/code/dynamic/Data.java | 121 +++ .../code/dynamic/DynamicImageActivity.java | 70 ++ .../lvfq/code/dynamic/data/CommentsBean.java | 52 ++ .../com/lvfq/code/dynamic/data/UserBean.java | 34 + .../dynamic/view/ColorFilterImageView.java | 51 ++ .../lvfq/code/dynamic/view/CommentsView.java | 191 +++++ .../com/lvfq/code/dynamic/view/LikesView.java | 138 ++++ .../code/dynamic/view/MultiImageView.java | 213 ++++++ .../com/lvfq/code/glide/GlideActivity.java | 62 ++ .../java/com/lvfq/code/http/HttpClient.java | 56 ++ .../code/http/NobodyConverterFactory.java | 64 ++ .../com/lvfq/code/http/RequestService.java | 33 + app/src/main/java/com/lvfq/code/mvp/Http.java | 23 + .../main/java/com/lvfq/code/mvp/HttpUtil.java | 106 +++ .../lvfq/code/mvp/IHttpResultListener.java | 13 + .../java/com/lvfq/code/mvp/LoginActivity.java | 77 ++ .../com/lvfq/code/mvp/RegisterActivity.java | 20 + .../com/lvfq/code/mvp/demo1/LoginModel.java | 20 + .../lvfq/code/mvp/demo1/LoginPresenter.java | 39 + .../com/lvfq/code/mvp/demo1/LoginView.java | 15 + .../com/lvfq/code/mvp/demo2/LoginModel2.java | 20 + .../lvfq/code/mvp/demo2/LoginPresenter2.java | 46 ++ .../com/lvfq/code/mvp/demo2/LoginView2.java | 15 + .../lvfq/code/mvp/demo3/BaseMvpPresenter.java | 28 + .../com/lvfq/code/mvp/demo3/IBaseMvpView.java | 13 + .../lvfq/code/mvp/demo3/IBasePresenter.java | 19 + .../com/lvfq/code/mvp/demo3/LoginModel3.java | 27 + .../lvfq/code/mvp/demo3/LoginPresenter3.java | 41 ++ .../com/lvfq/code/mvp/demo3/LoginView3.java | 15 + .../code/tablayout/PagerSlidingTabStrip.java | 689 ++++++++++++++++++ .../com/lvfq/code/tablayout/TabActivity.java | 72 ++ .../com/lvfq/code/tablayout/TabFragment.java | 46 ++ .../code/tablayout/custom/TabActivity1.java | 86 +++ .../tablayout/custom/TabSelectAdapter.java | 20 + .../lvfq/code/tablayout/custom/TabUtils.java | 174 +++++ .../tablayout/custom/UnAnimTabLayout.java | 153 ++++ .../java/com/lvfq/code/util/FileUtils.java | 381 ++++++++++ .../lvfq/code/util/Glide4_ImageLoadUtil.java | 225 ++++++ .../java/com/lvfq/code/util/ImageUtils.java | 43 ++ .../com/lvfq/code/util/MyAppGlideModule.java | 17 + app/src/main/res/drawable/shape_tab_green.xml | 5 + .../main/res/drawable/tab_selector_green.xml | 5 + app/src/main/res/layout/activity_comments.xml | 20 + .../res/layout/activity_dynamic_image.xml | 18 + app/src/main/res/layout/activity_glide.xml | 52 ++ .../res/layout/activity_img_water_mark.xml | 22 + app/src/main/res/layout/activity_login.xml | 14 + app/src/main/res/layout/activity_main.xml | 40 + app/src/main/res/layout/activity_tab.xml | 30 + app/src/main/res/layout/activity_tab1.xml | 31 + .../main/res/layout/item_dynamic_image.xml | 22 + app/src/main/res/mipmap-hdpi/ic_launcher.png | Bin 0 -> 3418 bytes app/src/main/res/mipmap-mdpi/ic_launcher.png | Bin 0 -> 2206 bytes app/src/main/res/mipmap-xhdpi/ic_launcher.png | Bin 0 -> 4842 bytes app/src/main/res/mipmap-xhdpi/img_default.png | Bin 0 -> 17975 bytes .../main/res/mipmap-xhdpi/img_like_icon.png | Bin 0 -> 1722 bytes .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin 0 -> 7718 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin 0 -> 10486 bytes app/src/main/res/values-w820dp/dimens.xml | 6 + app/src/main/res/values/attrs.xml | 20 + app/src/main/res/values/colors.xml | 8 + app/src/main/res/values/dimens.xml | 5 + app/src/main/res/values/strings.xml | 3 + app/src/main/res/values/styles.xml | 15 + .../lvfq/myworkingtest/ExampleUnitTest.java | 17 + build.gradle | 25 + gradle.properties | 17 + gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 53636 bytes gradle/wrapper/gradle-wrapper.properties | 6 + gradlew | 160 ++++ gradlew.bat | 90 +++ settings.gradle | 1 + 100 files changed, 5172 insertions(+) create mode 100644 .gitignore create mode 100644 .idea/compiler.xml create mode 100644 .idea/copyright/profiles_settings.xml create mode 100644 .idea/dictionaries/apple.xml create mode 100644 .idea/gradle.xml create mode 100644 .idea/markdown-navigator/profiles_settings.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/runConfigurations.xml create mode 100644 .idea/vcs.xml create mode 100644 app/.gitignore create mode 100644 app/build.gradle create mode 100644 app/proguard-rules.pro create mode 100644 app/src/androidTest/java/com/lvfq/myworkingtest/ExampleInstrumentedTest.java create mode 100644 app/src/main/AndroidManifest.xml create mode 100644 app/src/main/java/com/lvfq/code/BaseActivity.java create mode 100644 app/src/main/java/com/lvfq/code/ImageWaterMarkActivity.java create mode 100644 app/src/main/java/com/lvfq/code/MainActivity.java create mode 100644 app/src/main/java/com/lvfq/code/ModelBean.java create mode 100644 app/src/main/java/com/lvfq/code/MyApplication.java create mode 100644 app/src/main/java/com/lvfq/code/NoBodyEntity.java create mode 100644 app/src/main/java/com/lvfq/code/annotation/AnnotationTest1.java create mode 100644 app/src/main/java/com/lvfq/code/annotation/AnnotationUtil.java create mode 100644 app/src/main/java/com/lvfq/code/annotation/CusBus.java create mode 100644 app/src/main/java/com/lvfq/code/annotation/OnCusBusEvent.java create mode 100644 app/src/main/java/com/lvfq/code/annotation/Type.java create mode 100755 app/src/main/java/com/lvfq/code/dynamic/CircleMovementMethod.java create mode 100644 app/src/main/java/com/lvfq/code/dynamic/CommentsActivity.java create mode 100644 app/src/main/java/com/lvfq/code/dynamic/Data.java create mode 100644 app/src/main/java/com/lvfq/code/dynamic/DynamicImageActivity.java create mode 100644 app/src/main/java/com/lvfq/code/dynamic/data/CommentsBean.java create mode 100644 app/src/main/java/com/lvfq/code/dynamic/data/UserBean.java create mode 100644 app/src/main/java/com/lvfq/code/dynamic/view/ColorFilterImageView.java create mode 100644 app/src/main/java/com/lvfq/code/dynamic/view/CommentsView.java create mode 100644 app/src/main/java/com/lvfq/code/dynamic/view/LikesView.java create mode 100644 app/src/main/java/com/lvfq/code/dynamic/view/MultiImageView.java create mode 100644 app/src/main/java/com/lvfq/code/glide/GlideActivity.java create mode 100644 app/src/main/java/com/lvfq/code/http/HttpClient.java create mode 100644 app/src/main/java/com/lvfq/code/http/NobodyConverterFactory.java create mode 100644 app/src/main/java/com/lvfq/code/http/RequestService.java create mode 100644 app/src/main/java/com/lvfq/code/mvp/Http.java create mode 100644 app/src/main/java/com/lvfq/code/mvp/HttpUtil.java create mode 100644 app/src/main/java/com/lvfq/code/mvp/IHttpResultListener.java create mode 100644 app/src/main/java/com/lvfq/code/mvp/LoginActivity.java create mode 100644 app/src/main/java/com/lvfq/code/mvp/RegisterActivity.java create mode 100644 app/src/main/java/com/lvfq/code/mvp/demo1/LoginModel.java create mode 100644 app/src/main/java/com/lvfq/code/mvp/demo1/LoginPresenter.java create mode 100644 app/src/main/java/com/lvfq/code/mvp/demo1/LoginView.java create mode 100644 app/src/main/java/com/lvfq/code/mvp/demo2/LoginModel2.java create mode 100644 app/src/main/java/com/lvfq/code/mvp/demo2/LoginPresenter2.java create mode 100644 app/src/main/java/com/lvfq/code/mvp/demo2/LoginView2.java create mode 100644 app/src/main/java/com/lvfq/code/mvp/demo3/BaseMvpPresenter.java create mode 100644 app/src/main/java/com/lvfq/code/mvp/demo3/IBaseMvpView.java create mode 100644 app/src/main/java/com/lvfq/code/mvp/demo3/IBasePresenter.java create mode 100644 app/src/main/java/com/lvfq/code/mvp/demo3/LoginModel3.java create mode 100644 app/src/main/java/com/lvfq/code/mvp/demo3/LoginPresenter3.java create mode 100644 app/src/main/java/com/lvfq/code/mvp/demo3/LoginView3.java create mode 100755 app/src/main/java/com/lvfq/code/tablayout/PagerSlidingTabStrip.java create mode 100644 app/src/main/java/com/lvfq/code/tablayout/TabActivity.java create mode 100644 app/src/main/java/com/lvfq/code/tablayout/TabFragment.java create mode 100644 app/src/main/java/com/lvfq/code/tablayout/custom/TabActivity1.java create mode 100755 app/src/main/java/com/lvfq/code/tablayout/custom/TabSelectAdapter.java create mode 100755 app/src/main/java/com/lvfq/code/tablayout/custom/TabUtils.java create mode 100755 app/src/main/java/com/lvfq/code/tablayout/custom/UnAnimTabLayout.java create mode 100644 app/src/main/java/com/lvfq/code/util/FileUtils.java create mode 100644 app/src/main/java/com/lvfq/code/util/Glide4_ImageLoadUtil.java create mode 100644 app/src/main/java/com/lvfq/code/util/ImageUtils.java create mode 100644 app/src/main/java/com/lvfq/code/util/MyAppGlideModule.java create mode 100755 app/src/main/res/drawable/shape_tab_green.xml create mode 100755 app/src/main/res/drawable/tab_selector_green.xml create mode 100644 app/src/main/res/layout/activity_comments.xml create mode 100644 app/src/main/res/layout/activity_dynamic_image.xml create mode 100644 app/src/main/res/layout/activity_glide.xml create mode 100644 app/src/main/res/layout/activity_img_water_mark.xml create mode 100644 app/src/main/res/layout/activity_login.xml create mode 100644 app/src/main/res/layout/activity_main.xml create mode 100644 app/src/main/res/layout/activity_tab.xml create mode 100644 app/src/main/res/layout/activity_tab1.xml create mode 100644 app/src/main/res/layout/item_dynamic_image.xml create mode 100644 app/src/main/res/mipmap-hdpi/ic_launcher.png create mode 100644 app/src/main/res/mipmap-mdpi/ic_launcher.png create mode 100644 app/src/main/res/mipmap-xhdpi/ic_launcher.png create mode 100644 app/src/main/res/mipmap-xhdpi/img_default.png create mode 100644 app/src/main/res/mipmap-xhdpi/img_like_icon.png create mode 100644 app/src/main/res/mipmap-xxhdpi/ic_launcher.png create mode 100644 app/src/main/res/mipmap-xxxhdpi/ic_launcher.png create mode 100644 app/src/main/res/values-w820dp/dimens.xml create mode 100755 app/src/main/res/values/attrs.xml create mode 100644 app/src/main/res/values/colors.xml create mode 100644 app/src/main/res/values/dimens.xml create mode 100644 app/src/main/res/values/strings.xml create mode 100644 app/src/main/res/values/styles.xml create mode 100644 app/src/test/java/com/lvfq/myworkingtest/ExampleUnitTest.java create mode 100644 build.gradle create mode 100644 gradle.properties create mode 100644 gradle/wrapper/gradle-wrapper.jar create mode 100644 gradle/wrapper/gradle-wrapper.properties create mode 100755 gradlew create mode 100644 gradlew.bat create mode 100644 settings.gradle diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..39fb081 --- /dev/null +++ b/.gitignore @@ -0,0 +1,9 @@ +*.iml +.gradle +/local.properties +/.idea/workspace.xml +/.idea/libraries +.DS_Store +/build +/captures +.externalNativeBuild diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 0000000..96cc43e --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/copyright/profiles_settings.xml b/.idea/copyright/profiles_settings.xml new file mode 100644 index 0000000..e7bedf3 --- /dev/null +++ b/.idea/copyright/profiles_settings.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/.idea/dictionaries/apple.xml b/.idea/dictionaries/apple.xml new file mode 100644 index 0000000..142834e --- /dev/null +++ b/.idea/dictionaries/apple.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..ae871af --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,19 @@ + + + + + + \ No newline at end of file diff --git a/.idea/markdown-navigator/profiles_settings.xml b/.idea/markdown-navigator/profiles_settings.xml new file mode 100644 index 0000000..57927c5 --- /dev/null +++ b/.idea/markdown-navigator/profiles_settings.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..559ffe6 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,95 @@ + + + + + + + + + + + + + + + + + + Android + + + Android > Lint > Correctness + + + Java + + + Java language level migration aidsJava + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..66504d9 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..9a9b371 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,38 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 25 + buildToolsVersion "25.0.2" + defaultConfig { + applicationId "com.lvfq.code" + minSdkVersion 15 + targetSdkVersion 22 + versionCode 1 + versionName "1.0" + testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + } + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } +} + +dependencies { + compile fileTree(include: ['*.jar'], dir: 'libs') + androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { + exclude group: 'com.android.support', module: 'support-annotations' + }) + compile 'com.android.support:appcompat-v7:25.1.0' + testCompile 'junit:junit:4.12' + compile 'com.squareup.retrofit2:retrofit:2.2.0' + compile 'com.squareup.retrofit2:converter-gson:2.2.0' + compile 'com.squareup.retrofit2:converter-scalars:2.3.0' + compile 'com.android.support:design:25.0.0' + compile 'com.github.lvfaqiang:AndroidUtils:1.1.2' + compile 'com.github.bumptech.glide:glide:4.0.0' + annotationProcessor 'com.github.bumptech.glide:compiler:4.0.0' + compile 'com.android.support:support-v4:25.3.1' + compile 'com.zhy:base-rvadapter:3.0.3' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..deab50f --- /dev/null +++ b/app/proguard-rules.pro @@ -0,0 +1,17 @@ +# Add project specific ProGuard rules here. +# By default, the flags in this file are appended to flags specified +# in /Users/apple/Library/Android/sdk/tools/proguard/proguard-android.txt +# You can edit the include path and order by changing the proguardFiles +# directive in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# Add any project specific keep options here: + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} diff --git a/app/src/androidTest/java/com/lvfq/myworkingtest/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/lvfq/myworkingtest/ExampleInstrumentedTest.java new file mode 100644 index 0000000..3415f6e --- /dev/null +++ b/app/src/androidTest/java/com/lvfq/myworkingtest/ExampleInstrumentedTest.java @@ -0,0 +1,26 @@ +package com.lvfq.myworkingtest; + +import android.content.Context; +import android.support.test.InstrumentationRegistry; +import android.support.test.runner.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumentation test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() throws Exception { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getTargetContext(); + + assertEquals("com.lvfq.myworkingtest", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..6f7f118 --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/lvfq/code/BaseActivity.java b/app/src/main/java/com/lvfq/code/BaseActivity.java new file mode 100644 index 0000000..acbcae6 --- /dev/null +++ b/app/src/main/java/com/lvfq/code/BaseActivity.java @@ -0,0 +1,46 @@ +package com.lvfq.code; + +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.support.v4.app.FragmentActivity; + +import com.lvfq.code.mvp.demo3.BaseMvpPresenter; +import com.lvfq.code.mvp.demo3.IBaseMvpView; + +/** + * BaseActivity + * + * @author lvfq + * @date 2017/7/17 下午3:04 + * @mainFunction : + */ + +public abstract class BaseActivity> extends FragmentActivity { + + private P presenter; + + public abstract P bindPresenter(); + + public P getPresenter() { + return presenter; + } + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + if (presenter == null) { + presenter = bindPresenter(); + if (presenter != null && this instanceof IBaseMvpView) { + presenter.attachView((V) this); + } + } + } + + @Override + protected void onDestroy() { + super.onDestroy(); + if (presenter != null) { + presenter.detachView(); + } + } +} diff --git a/app/src/main/java/com/lvfq/code/ImageWaterMarkActivity.java b/app/src/main/java/com/lvfq/code/ImageWaterMarkActivity.java new file mode 100644 index 0000000..da56333 --- /dev/null +++ b/app/src/main/java/com/lvfq/code/ImageWaterMarkActivity.java @@ -0,0 +1,150 @@ +package com.lvfq.code; + +import android.content.Intent; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; +import android.graphics.Typeface; +import android.net.Uri; +import android.os.Bundle; +import android.os.Environment; +import android.provider.MediaStore; +import android.support.annotation.Nullable; +import android.support.v4.app.FragmentActivity; +import android.util.Log; +import android.util.TypedValue; +import android.view.View; +import android.widget.ImageView; + +import com.lvfq.code.util.FileUtils; +import com.lvfq.code.util.ImageUtils; +import com.lvfq.myworkingtest.R; + +import java.io.File; +import java.io.FileNotFoundException; + +/** + * ImageWaterMarkActivity + * + * @author lvfq + * @date 2017/4/19 上午10:26 + * @mainFunction : + */ + +public class ImageWaterMarkActivity extends FragmentActivity { + + public static String path = Environment.getExternalStorageDirectory() + File.separator + "Android" + File.separator + + "_test" + File.separator; + + + private ImageView iv_img; + + private Uri imgPath; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_img_water_mark); + iv_img = (ImageView) findViewById(R.id.iv_img); + + + } + + public void onClick(View view) { + Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); + imgPath = Uri.fromFile(new File(mImageFileCachePath() + "img.jpg")); + intent.putExtra(MediaStore.EXTRA_OUTPUT, imgPath); + startActivityForResult(intent, 1); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + if (resultCode != RESULT_OK) { + return; + } + + if (requestCode == 1) { + int angle = FileUtils.readPictureDegree(imgPath.getEncodedPath()); + Log.i("lfq", "angle = " + angle); + try { + Bitmap bitmap = createBitmap(BitmapFactory.decodeStream(getContentResolver().openInputStream(imgPath)), "添加的水印文字"); + ImageUtils.saveFile(bitmap, imgPath.getEncodedPath()); + Bitmap bitmap1 = FileUtils.ratingImage(imgPath.getEncodedPath(), bitmap); + + iv_img.setImageBitmap(bitmap); +// iv_img.setImageBitmap(bitmap1); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } + +// bitmap.recycle(); +// bitmap1.recycle(); + } + } + + /** + * @param src 添加水印的图片 + * @param title 水印文字 + * @return + */ + public Bitmap createBitmap(Bitmap src, String title) { + if (src == null) { + return src; + } + Bitmap bitmap = src; + // 获取原始图片的宽与高 + int w = bitmap.getWidth(); + int h = bitmap.getHeight(); + Bitmap newBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888); + Canvas mCanvas = new Canvas(newBitmap); + // 往位图中开始画入src原始图片 + mCanvas.drawBitmap(bitmap, 0, 0, null); + // 开始加入文字 + if (null != title) { + Paint textPaint = new Paint(); + + textPaint.setTextSize(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 48, getResources().getDisplayMetrics())); + String familyName = "宋体"; + Typeface typeface = Typeface.create(familyName, + Typeface.NORMAL); + textPaint.setTypeface(typeface); + textPaint.setTextAlign(Paint.Align.CENTER); + float textHeight = textPaint.descent() - textPaint.ascent(); + + textPaint.setAntiAlias(true); + textPaint.setColor(Color.BLACK); + textPaint.setStrokeWidth(textHeight + dip2px(8)); + textPaint.setAlpha((int) (255 * 0.8)); + mCanvas.drawLine(0, h - (textHeight / 2 + dip2px(4)), w, h - (textHeight / 2 + dip2px(4)), textPaint); // 先画背景。 + textPaint.setColor(Color.WHITE); + mCanvas.drawText(title, w / 2, h - (textHeight / 2) + dip2px(20), textPaint); + + } + mCanvas.save(Canvas.ALL_SAVE_FLAG); + mCanvas.restore(); + bitmap.recycle(); + return newBitmap; + } + + + public static String mImageFileCachePath() { + String s = Environment.getExternalStorageDirectory() + File.separator + "Android" + File.separator + + "_test" + File.separator; + File file = new File(s); + if (!file.exists()) { + file.mkdirs(); + } + return s; + } + + + /** + * 根据手机的分辨率从 dp 的单位 转成为 px(像素) + */ + public int dip2px(float dpValue) { + final float scale = getResources().getDisplayMetrics().density; + return (int) (dpValue * scale + 0.5f); + } +} diff --git a/app/src/main/java/com/lvfq/code/MainActivity.java b/app/src/main/java/com/lvfq/code/MainActivity.java new file mode 100644 index 0000000..8a0028f --- /dev/null +++ b/app/src/main/java/com/lvfq/code/MainActivity.java @@ -0,0 +1,58 @@ +package com.lvfq.code; + +import android.os.Bundle; +import android.text.Editable; +import android.text.TextWatcher; +import android.util.Log; +import android.widget.EditText; +import android.widget.TextView; + +import com.lvfq.code.mvp.demo3.LoginPresenter3; +import com.lvfq.myworkingtest.R; +import com.lvfq.code.mvp.demo3.LoginView3; + +public class MainActivity extends BaseActivity implements LoginView3 { + + private TextView tv_symbol; + private EditText et_content; + + @Override + public LoginPresenter3 bindPresenter() { + return null; + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + + tv_symbol = (TextView) findViewById(R.id.tv_symbol); + et_content = (EditText) findViewById(R.id.et_content); + et_content.addTextChangedListener(new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) { + + } + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) { + + } + + @Override + public void afterTextChanged(Editable s) { + int width = (int) et_content.getPaint().measureText(s.toString()); + Log.i("lfq", "width: " + width); + tv_symbol.setPadding(0, 0, width + 5, 0); + } + }); + + et_content.setText("10000"); + + } + + @Override + public void onResult(String result) { + + } +} diff --git a/app/src/main/java/com/lvfq/code/ModelBean.java b/app/src/main/java/com/lvfq/code/ModelBean.java new file mode 100644 index 0000000..59a00df --- /dev/null +++ b/app/src/main/java/com/lvfq/code/ModelBean.java @@ -0,0 +1,66 @@ +package com.lvfq.code; + +/** + * ModelBean + * + * @author lvfq + * @Github: https://github.com/lvfaqiang + * @Blog: http://blog.csdn.net/lv_fq + * @date 2017/8/4 下午10:30 + * @desc : + */ + +public class ModelBean { + + + /** + * errorCtx : null + * resultData : {"isMainServer ":true,"serverNumber":1234} + * success : true + */ + + private ResultDataBean resultData; + private boolean success; + + public ResultDataBean getResultData() { + return resultData; + } + + public void setResultData(ResultDataBean resultData) { + this.resultData = resultData; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class ResultDataBean { + /** + * isMainServer : true + * serverNumber : 1234 + */ + + private boolean isMainServer; + private int serverNumber; + + public boolean isMainServer() { + return isMainServer; + } + + public void setMainServer(boolean mainServer) { + isMainServer = mainServer; + } + + public int getServerNumber() { + return serverNumber; + } + + public void setServerNumber(int serverNumber) { + this.serverNumber = serverNumber; + } + } +} diff --git a/app/src/main/java/com/lvfq/code/MyApplication.java b/app/src/main/java/com/lvfq/code/MyApplication.java new file mode 100644 index 0000000..2854610 --- /dev/null +++ b/app/src/main/java/com/lvfq/code/MyApplication.java @@ -0,0 +1,25 @@ +package com.lvfq.code; + +import android.app.Application; + +import com.lvfq.library.utils.LvUtils; + +/** + * MyApplication + * + * @author lvfq + * @Github: https://github.com/lvfaqiang + * @Blog: http://blog.csdn.net/lv_fq + * @date 2017/9/1 下午11:15 + * @desc : + */ + +public class MyApplication extends Application { + + @Override + public void onCreate() { + super.onCreate(); + + LvUtils.init(this); + } +} diff --git a/app/src/main/java/com/lvfq/code/NoBodyEntity.java b/app/src/main/java/com/lvfq/code/NoBodyEntity.java new file mode 100644 index 0000000..051e5aa --- /dev/null +++ b/app/src/main/java/com/lvfq/code/NoBodyEntity.java @@ -0,0 +1,14 @@ +package com.lvfq.code; + +/** + * NoBodyEntity + * + * @author lvfq + * @Github: https://github.com/lvfaqiang + * @Blog: http://blog.csdn.net/lv_fq + * @date 2017/8/4 下午11:07 + * @desc : + */ + +public class NoBodyEntity { +} diff --git a/app/src/main/java/com/lvfq/code/annotation/AnnotationTest1.java b/app/src/main/java/com/lvfq/code/annotation/AnnotationTest1.java new file mode 100644 index 0000000..e5b5a5b --- /dev/null +++ b/app/src/main/java/com/lvfq/code/annotation/AnnotationTest1.java @@ -0,0 +1,30 @@ +package com.lvfq.code.annotation; + +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.support.v4.app.FragmentActivity; + +/** + * AnnotationTest1 + * + * @author lvfq + * @Github: https://github.com/lvfaqiang + * @Blog: http://blog.csdn.net/lv_fq + * @date 2017/7/26 下午1:53 + * @desc : + */ + +public class AnnotationTest1 extends FragmentActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + + } + + @OnCusBusEvent(tag = "" ) + private void mTest() { + + } +} diff --git a/app/src/main/java/com/lvfq/code/annotation/AnnotationUtil.java b/app/src/main/java/com/lvfq/code/annotation/AnnotationUtil.java new file mode 100644 index 0000000..bf898de --- /dev/null +++ b/app/src/main/java/com/lvfq/code/annotation/AnnotationUtil.java @@ -0,0 +1,16 @@ +package com.lvfq.code.annotation; + +/** + * AnnotationUtil + * + * @author lvfq + * @Github: https://github.com/lvfaqiang + * @Blog: http://blog.csdn.net/lv_fq + * @date 2017/7/26 下午2:18 + * @desc : + */ + +public class AnnotationUtil { + + +} diff --git a/app/src/main/java/com/lvfq/code/annotation/CusBus.java b/app/src/main/java/com/lvfq/code/annotation/CusBus.java new file mode 100644 index 0000000..b9298bb --- /dev/null +++ b/app/src/main/java/com/lvfq/code/annotation/CusBus.java @@ -0,0 +1,77 @@ +package com.lvfq.code.annotation; + +import android.app.Activity; +import android.support.v4.app.Fragment; + +import java.lang.annotation.Annotation; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +/** + * CusBus + * + * @author lvfq + * @Github: https://github.com/lvfaqiang + * @Blog: http://blog.csdn.net/lv_fq + * @date 2017/7/26 下午2:04 + * @desc : + */ + +public class CusBus { + private static CusBus instance = null; + private static ConcurrentMap map = new ConcurrentHashMap<>(); + private static Map classes = new HashMap<>(); + + public static CusBus getInstance() { + if (instance == null) { + synchronized (CusBus.class) { + if (instance == null) { + instance = new CusBus(); + } + } + } + return instance; + } + + public void register(Fragment fragment) { +// classes.add(fragment.getClass()); + classes.put(fragment.hashCode(), fragment.getClass()); + + } + + public void register(Activity activity) { + classes.put(activity.hashCode(), activity.getClass()); + } + + public void execute(Class clazz) { + +// Class clazz = subscriber.getClass(); +// List methodList = new ArrayList<>(); +// Method[] methods = clazz.getMethods(); +// if (methods != null && methods.length > 0) { +// for (Method method : methods) { +// if (method.isAnnotationPresent(OnCusBusEvent.class)) { +// methodList.add(method); +// } +// } +// if (methodList.size() > 0) { +// map.put(clazz, methodList); +// } +// } + +// if (methods != null && methods.length > 0) { +// for (Method method : methods) { +// if (method.isAnnotationPresent(clazz)) { +// try { +// method.invoke(subscriber, (Object[]) new Objects[]{}); +// } catch (Exception e) { +// e.printStackTrace(); +// } +// } +// } +// } + } +} diff --git a/app/src/main/java/com/lvfq/code/annotation/OnCusBusEvent.java b/app/src/main/java/com/lvfq/code/annotation/OnCusBusEvent.java new file mode 100644 index 0000000..cf5d868 --- /dev/null +++ b/app/src/main/java/com/lvfq/code/annotation/OnCusBusEvent.java @@ -0,0 +1,24 @@ +package com.lvfq.code.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * OnCusBusEvent + * + * @author lvfq + * @Github: https://github.com/lvfaqiang + * @Blog: http://blog.csdn.net/lv_fq + * @date 2017/7/26 下午2:10 + * @desc : + */ + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +public @interface OnCusBusEvent { + String tag(); + + Type type() default Type.NONE; +} diff --git a/app/src/main/java/com/lvfq/code/annotation/Type.java b/app/src/main/java/com/lvfq/code/annotation/Type.java new file mode 100644 index 0000000..222e860 --- /dev/null +++ b/app/src/main/java/com/lvfq/code/annotation/Type.java @@ -0,0 +1,15 @@ +package com.lvfq.code.annotation; + +/** + * Type + * + * @author lvfq + * @Github: https://github.com/lvfaqiang + * @Blog: http://blog.csdn.net/lv_fq + * @date 2017/7/26 下午5:27 + * @desc : + */ + +public enum Type { + NONE , POST, GET, MAIN +} diff --git a/app/src/main/java/com/lvfq/code/dynamic/CircleMovementMethod.java b/app/src/main/java/com/lvfq/code/dynamic/CircleMovementMethod.java new file mode 100755 index 0000000..a11588e --- /dev/null +++ b/app/src/main/java/com/lvfq/code/dynamic/CircleMovementMethod.java @@ -0,0 +1,117 @@ +package com.lvfq.code.dynamic; + +import android.text.Layout; +import android.text.Selection; +import android.text.Spannable; +import android.text.method.BaseMovementMethod; +import android.text.method.Touch; +import android.text.style.BackgroundColorSpan; +import android.text.style.ClickableSpan; +import android.view.MotionEvent; +import android.widget.TextView; + +/** + * @author yiw + * @Description: + * @date 16/1/2 16:54 + */ +public class CircleMovementMethod extends BaseMovementMethod { + private final static int DEFAULT_COLOR_ID = android.R.color.transparent; + /** + * 整个textView的背景色 + */ + private int textViewBgColor; + /** + * 点击部分文字时部分文字的背景色 + */ + private int clickableSpanBgClor; + + private BackgroundColorSpan mBgSpan; + private ClickableSpan[] mClickLinks; + + private boolean isParseTv = false; + + public boolean isParseTv() { + return isParseTv; + } + + public void setParseTv(boolean parseTv) { + isParseTv = parseTv; + } + + /** + * @param clickableSpanBgClor 点击选中部分时的背景色 + */ + public CircleMovementMethod(int clickableSpanBgClor) { + this.clickableSpanBgClor = clickableSpanBgClor; + } + + /** + * @param clickableSpanBgClor 点击选中部分时的背景色 + * @param textViewBgColor 整个textView点击时的背景色 + */ + public CircleMovementMethod(int clickableSpanBgClor, int textViewBgColor) { + this.textViewBgColor = textViewBgColor; + this.clickableSpanBgClor = clickableSpanBgClor; + } + + public boolean onTouchEvent(TextView widget, Spannable buffer, + MotionEvent event) { + + int action = event.getAction(); + if (action == MotionEvent.ACTION_DOWN) { + int x = (int) event.getX(); + int y = (int) event.getY(); + + x -= widget.getTotalPaddingLeft(); + y -= widget.getTotalPaddingTop(); + + x += widget.getScrollX(); + y += widget.getScrollY(); + + Layout layout = widget.getLayout(); + int line = layout.getLineForVertical(y); + int off = layout.getOffsetForHorizontal(line, x); + + mClickLinks = buffer.getSpans(off, off, ClickableSpan.class); + if (mClickLinks.length > 0) { + setParseTv(false); + // 点击的是Span区域,不要把点击事件传递 + Selection.setSelection(buffer, + buffer.getSpanStart(mClickLinks[0]), + buffer.getSpanEnd(mClickLinks[0])); + //设置点击区域的背景色 + mBgSpan = new BackgroundColorSpan(clickableSpanBgClor); + buffer.setSpan(mBgSpan, + buffer.getSpanStart(mClickLinks[0]), + buffer.getSpanEnd(mClickLinks[0]), + Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + } else { + setParseTv(true); + // textview选中效果 +// widget.setBackgroundColor(textViewBgColor); + widget.setBackgroundResource(DEFAULT_COLOR_ID); + } + + } else if (action == MotionEvent.ACTION_UP) { + if (mClickLinks.length > 0) { + mClickLinks[0].onClick(widget); + if (mBgSpan != null) {//移除点击时设置的背景span + buffer.removeSpan(mBgSpan); + } + } else { + + } + Selection.removeSelection(buffer); + widget.setBackgroundResource(DEFAULT_COLOR_ID); + } else if (action == MotionEvent.ACTION_MOVE) { + //这种情况不用做处理 + } else { + if (mBgSpan != null) {//移除点击时设置的背景span + buffer.removeSpan(mBgSpan); + } + widget.setBackgroundResource(DEFAULT_COLOR_ID); + } + return Touch.onTouchEvent(widget, buffer, event); + } +} diff --git a/app/src/main/java/com/lvfq/code/dynamic/CommentsActivity.java b/app/src/main/java/com/lvfq/code/dynamic/CommentsActivity.java new file mode 100644 index 0000000..4b191ef --- /dev/null +++ b/app/src/main/java/com/lvfq/code/dynamic/CommentsActivity.java @@ -0,0 +1,85 @@ +package com.lvfq.code.dynamic; + +import android.os.Bundle; +import android.os.Handler; +import android.os.Message; +import android.support.annotation.Nullable; +import android.support.v7.app.AppCompatActivity; +import android.util.Log; +import android.view.View; +import android.widget.Toast; + +import com.lvfq.code.dynamic.data.CommentsBean; +import com.lvfq.code.dynamic.data.UserBean; +import com.lvfq.code.dynamic.view.LikesView; +import com.lvfq.library.utils.LvV; +import com.lvfq.myworkingtest.R; +import com.lvfq.code.dynamic.view.CommentsView; + +/** + * CommentsActivity + * + * @author lvfq + * @Github: https://github.com/lvfaqiang + * @Blog: http://blog.csdn.net/lv_fq + * @date 2017/9/3 下午9:56 + * @desc : + */ + +public class CommentsActivity extends AppCompatActivity { + + private CommentsView commentView; + private LikesView likeView; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_comments); + + commentView = LvV.find(this, R.id.commentView); + likeView = LvV.find(this, R.id.likeView); + + likeView.setList(Data.getLikes()); + likeView.setListener(new LikesView.onItemClickListener() { + @Override + public void onItemClick(int position, UserBean bean) { + new MyThread().start(); + } + }); + likeView.notifyDataSetChanged(); + + commentView = LvV.find(this, R.id.commentView); + commentView.setList(Data.getComments()); + commentView.setOnItemClickListener(new CommentsView.onItemClickListener() { + @Override + public void onItemClick(int position, CommentsBean bean) { + Log.i("lfq", Thread.currentThread().getName()); + new MyThread().start(); + } + }); + commentView.notifyDataSetChanged(); + } + + private class MyThread extends Thread { + private Handler handler; + + @Override + public void run() { +// Looper.prepare(); + handler = new Handler(getMainLooper()) { + @Override + public void handleMessage(Message msg) { + if (msg.what == 1) { + Log.i("lfq", msg.what + " , mas.what"); + Toast.makeText(CommentsActivity.this, Thread.currentThread().getName(), Toast.LENGTH_SHORT).show(); + commentView.setVisibility(View.GONE); + } + } + }; + + handler.sendEmptyMessage(1); +// Looper.loop(); + + } + } +} diff --git a/app/src/main/java/com/lvfq/code/dynamic/Data.java b/app/src/main/java/com/lvfq/code/dynamic/Data.java new file mode 100644 index 0000000..065c6b2 --- /dev/null +++ b/app/src/main/java/com/lvfq/code/dynamic/Data.java @@ -0,0 +1,121 @@ +package com.lvfq.code.dynamic; + +import com.lvfq.code.dynamic.data.CommentsBean; +import com.lvfq.code.dynamic.data.UserBean; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * Data + * + * @author lvfq + * @Github: https://github.com/lvfaqiang + * @Blog: http://blog.csdn.net/lv_fq + * @date 2017/9/2 上午12:14 + * @desc : + */ + +public class Data { + + +// http://opgirl-tmp.adbxb.cn/images2/mi/2202/148_ce2b24f5ea4fadaf6c5591416e7990dc_75.jpg +// +// http://opgirl-tmp.adbxb.cn/images3/mi/20/144_dc7b83c64f60363a8212f01eef43f513_75.jpg +// http://opgirl-tmp.adbxb.cn/images2/mi/1447/148_62de05945c28dbccaeb92f131f26f972_75.jpg +// http://opgirl-tmp.adbxb.cn/images2/mi/1240/142_b2f099d4f8576543cb0b0c3878cae26e_75.jpg +// http://i1.go2yd.com/corpimage.php?url=http://si1.go2yd.com/get-image/0CZZQOCHE3M&source=mb&type=_896x504 +// +// http://i1.go2yd.com/corpimage.php?url=http://si1.go2yd.com/get-image/09yg7aATwp6&source=mb&type=_896x504 +// +// http://opgirl-tmp.adbxb.cn/images2/mi/1307/206_773d003844d1966a7ce0cee1d245155a_75.jpg +// +// http://opgirl-tmp.adbxb.cn/images2/mi/2847/206_da5207eb0798f155572dca227ddf0411_75.jpg +// +// http://opgirl-tmp.adbxb.cn/images1/mi/2566/208_cfcb6e2cd501aadf61fc572119ad8a29_75.jpg +// +// http://opgirl-tmp.adbxb.cn/images2/mi/1392/206_7c9ab9991319e284c8ce781481a866a4_75.jpeg + + private static String[] imgs = { + "http://opgirl-tmp.adbxb.cn/images2/mi/2202/148_ce2b24f5ea4fadaf6c5591416e7990dc_75.jpg", + "http://opgirl-tmp.adbxb.cn/images3/mi/20/144_dc7b83c64f60363a8212f01eef43f513_75.jpg", + "http://i1.go2yd.com/corpimage.php?url=http://si1.go2yd.com/get-image/0CZZQOCHE3M&source=mb&type=_896x504", + "http://opgirl-tmp.adbxb.cn/images2/mi/1447/148_62de05945c28dbccaeb92f131f26f972_75.jpg", + "http://opgirl-tmp.adbxb.cn/images2/mi/1240/142_b2f099d4f8576543cb0b0c3878cae26e_75.jpg", + "http://i1.go2yd.com/corpimage.php?url=http://si1.go2yd.com/get-image/09yg7aATwp6&source=mb&type=_896x504", + "http://opgirl-tmp.adbxb.cn/images2/mi/1307/206_773d003844d1966a7ce0cee1d245155a_75.jpg", + "http://opgirl-tmp.adbxb.cn/images2/mi/2847/206_da5207eb0798f155572dca227ddf0411_75.jpg", +// "http://opgirl-tmp.adbxb.cn/images1/mi/2566/208_cfcb6e2cd501aadf61fc572119ad8a29_75.jpg", + "http://opgirl-tmp.adbxb.cn/images2/mi/1392/206_7c9ab9991319e284c8ce781481a866a4_75.jpeg" + }; + + /** + * 获取图片数量 + * + * @param count + * @return + */ + public static List getImgs(int count) { + if (count <= 0) { + return null; + } + List list = new ArrayList<>(); + if (count >= 9) { + return Arrays.asList(imgs); + } else { + for (int i = 0; i < count; i++) { + list.add(imgs[i]); + } + } + return list; + } + + /** + * 生成评论列表 + * + * @return + */ + public static List getComments() { + List list = new ArrayList<>(); + for (int i = 0; i < 10; i++) { + CommentsBean commentsBean = new CommentsBean(); + commentsBean.setCommentsId(i); + commentsBean.setContent("zhe shi wo yong lai ce shi shu ru de wen ben nei rong " + i); + if (i % 2 == 0) { + UserBean replyUser = new UserBean(); + replyUser.setUserId(i + 30); + replyUser.setUserName("用户" + replyUser.getUserId()); + commentsBean.setReplyUser(replyUser); + } + UserBean comUser = new UserBean(); + comUser.setUserId(i); + comUser.setUserName("用户" + comUser.getUserId()); + + commentsBean.setCommentsUser(comUser); + + list.add(commentsBean); + } + + return list; + } + + + /** + * 生成点赞列表 + * + * @return + */ + public static List getLikes() { + List list = new ArrayList<>(); + for (int i = 0; i < 10; i++) { + UserBean userBean = new UserBean(); + userBean.setUserName("用户" + i); + userBean.setUserId(i + 1); + list.add(userBean); + } + + return list; + } + +} diff --git a/app/src/main/java/com/lvfq/code/dynamic/DynamicImageActivity.java b/app/src/main/java/com/lvfq/code/dynamic/DynamicImageActivity.java new file mode 100644 index 0000000..2f8ba9c --- /dev/null +++ b/app/src/main/java/com/lvfq/code/dynamic/DynamicImageActivity.java @@ -0,0 +1,70 @@ +package com.lvfq.code.dynamic; + +import android.app.Activity; +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.support.v4.app.FragmentActivity; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.view.View; + +import com.lvfq.code.dynamic.view.MultiImageView; +import com.lvfq.library.utils.LvToastUtil; +import com.lvfq.library.utils.LvV; +import com.lvfq.myworkingtest.R; +import com.zhy.adapter.recyclerview.CommonAdapter; +import com.zhy.adapter.recyclerview.base.ViewHolder; + +import java.util.ArrayList; +import java.util.List; + +/** + * DynamicImageActivity + * + * @author lvfq + * @Github: https://github.com/lvfaqiang + * @Blog: http://blog.csdn.net/lv_fq + * @date 2017/8/25 上午9:16 + * @desc : + */ + +public class DynamicImageActivity extends FragmentActivity { + + RecyclerView recyclerView; + CommonAdapter mAdapter; + List mList = new ArrayList<>(); + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_dynamic_image); + + recyclerView = LvV.find(this, R.id.recyclerView); + mList = Data.getImgs(9); + + initAdapter(); + + recyclerView.setLayoutManager(new LinearLayoutManager(this)); + recyclerView.setAdapter(mAdapter); + + } + + private void initAdapter() { + mAdapter = new CommonAdapter(this, R.layout.item_dynamic_image, mList) { + @Override + protected void convert(ViewHolder holder, String s, int position) { + MultiImageView multiImage = holder.getView(R.id.multi_image); + holder.setText(R.id.tv_title, (position + 1) + "张图"); + multiImage.setList(Data.getImgs(position + 1)); + final int pos = position; + multiImage.setOnItemClickListener(new MultiImageView.OnItemClickListener() { + @Override + public void onItemClick(View view, int position) { + LvToastUtil.showToast((Activity) mContext, "position1:" + pos + " , position2:" + position); + } + }); + } + }; + + } +} diff --git a/app/src/main/java/com/lvfq/code/dynamic/data/CommentsBean.java b/app/src/main/java/com/lvfq/code/dynamic/data/CommentsBean.java new file mode 100644 index 0000000..5176b9e --- /dev/null +++ b/app/src/main/java/com/lvfq/code/dynamic/data/CommentsBean.java @@ -0,0 +1,52 @@ +package com.lvfq.code.dynamic.data; + +import java.io.Serializable; + +/** + * CommentsBean + * + * @author lvfq + * @Github: https://github.com/lvfaqiang + * @Blog: http://blog.csdn.net/lv_fq + * @date 2017/9/3 下午10:03 + * @desc : + */ + +public class CommentsBean implements Serializable { + private int commentsId; + private String content; + private UserBean replyUser; // 回复人信息 + private UserBean commentsUser; // 评论人信息 + + public int getCommentsId() { + return commentsId; + } + + public void setCommentsId(int commentsId) { + this.commentsId = commentsId; + } + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } + + public UserBean getReplyUser() { + return replyUser; + } + + public void setReplyUser(UserBean replyUser) { + this.replyUser = replyUser; + } + + public UserBean getCommentsUser() { + return commentsUser; + } + + public void setCommentsUser(UserBean commentsUser) { + this.commentsUser = commentsUser; + } +} diff --git a/app/src/main/java/com/lvfq/code/dynamic/data/UserBean.java b/app/src/main/java/com/lvfq/code/dynamic/data/UserBean.java new file mode 100644 index 0000000..3347df4 --- /dev/null +++ b/app/src/main/java/com/lvfq/code/dynamic/data/UserBean.java @@ -0,0 +1,34 @@ +package com.lvfq.code.dynamic.data; + +import java.io.Serializable; + +/** + * UserBean + * + * @author lvfq + * @Github: https://github.com/lvfaqiang + * @Blog: http://blog.csdn.net/lv_fq + * @date 2017/9/3 下午10:01 + * @desc : + */ + +public class UserBean implements Serializable { + private int userId; + private String userName; + + public int getUserId() { + return userId; + } + + public void setUserId(int userId) { + this.userId = userId; + } + + public String getUserName() { + return userName; + } + + public void setUserName(String userName) { + this.userName = userName; + } +} diff --git a/app/src/main/java/com/lvfq/code/dynamic/view/ColorFilterImageView.java b/app/src/main/java/com/lvfq/code/dynamic/view/ColorFilterImageView.java new file mode 100644 index 0000000..ed7a6e1 --- /dev/null +++ b/app/src/main/java/com/lvfq/code/dynamic/view/ColorFilterImageView.java @@ -0,0 +1,51 @@ +package com.lvfq.code.dynamic.view; + +import android.content.Context; +import android.graphics.Color; +import android.graphics.PorterDuff.Mode; +import android.util.AttributeSet; +import android.view.MotionEvent; +import android.view.View; +import android.view.View.OnTouchListener; +import android.widget.ImageView; + +/** + * @author hnclca + * @ClassName: ColorFilterImageView + * @Description: 实现图像根据按下抬起动作变化颜色 + * @date 2016-02-26 + */ +public class ColorFilterImageView extends ImageView implements OnTouchListener { + public ColorFilterImageView(Context context) { + this(context, null, 0); + } + + public ColorFilterImageView(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + public ColorFilterImageView(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + init(); + } + + private void init() { + setOnTouchListener(this); + } + + @Override + public boolean onTouch(View v, MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: // 按下时图像变灰 + setColorFilter(Color.GRAY, Mode.MULTIPLY); + break; + case MotionEvent.ACTION_UP: // 手指离开或取消操作时恢复原色 + case MotionEvent.ACTION_CANCEL: + setColorFilter(Color.TRANSPARENT); + break; + default: + break; + } + return false; + } +} diff --git a/app/src/main/java/com/lvfq/code/dynamic/view/CommentsView.java b/app/src/main/java/com/lvfq/code/dynamic/view/CommentsView.java new file mode 100644 index 0000000..6512f48 --- /dev/null +++ b/app/src/main/java/com/lvfq/code/dynamic/view/CommentsView.java @@ -0,0 +1,191 @@ +package com.lvfq.code.dynamic.view; + +import android.content.Context; +import android.support.annotation.Nullable; +import android.text.Spannable; +import android.text.SpannableString; +import android.text.SpannableStringBuilder; +import android.text.TextPaint; +import android.text.style.ClickableSpan; +import android.util.AttributeSet; +import android.view.View; +import android.widget.LinearLayout; +import android.widget.TextView; +import android.widget.Toast; + +import com.lvfq.code.dynamic.CircleMovementMethod; +import com.lvfq.code.dynamic.data.CommentsBean; +import com.lvfq.code.dynamic.data.UserBean; + +import java.util.List; + +/** + * CommentsView + * + * @author lvfq + * @Github: https://github.com/lvfaqiang + * @Blog: http://blog.csdn.net/lv_fq + * @date 2017/9/3 下午9:58 + * @desc : + */ + +public class CommentsView extends LinearLayout { + + private Context mContext; + private List mDatas; + private onItemClickListener listener; + + public CommentsView(Context context) { + this(context, null); + } + + public CommentsView(Context context, @Nullable AttributeSet attrs) { + this(context, attrs, 0); + } + + public CommentsView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + setOrientation(VERTICAL); + this.mContext = context; + } + + /** + * 设置评论列表信息 + * + * @param list + */ + public void setList(List list) { + mDatas = list; + } + + public void setOnItemClickListener(onItemClickListener listener) { + this.listener = listener; + } + + public void notifyDataSetChanged() { + removeAllViews(); + if (mDatas == null || mDatas.size() <= 0) { + return; + } + LayoutParams layoutParams = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT); + layoutParams.setMargins(0, 10, 0, 10); + for (int i = 0; i < mDatas.size(); i++) { + View view = getView(i); + if (view == null) { + throw new NullPointerException("listview item layout is null, please check getView()..."); + } + addView(view, i, layoutParams); + } + } + + private View getView(final int position) { + final CommentsBean item = mDatas.get(position); + UserBean replyUser = item.getReplyUser(); + boolean hasReply = false; // 是否有回复 + if (replyUser != null) { + hasReply = true; + } + TextView textView = new TextView(mContext); + textView.setTextSize(15); + textView.setTextColor(0xff686868); + + SpannableStringBuilder builder = new SpannableStringBuilder(); + UserBean comUser = item.getCommentsUser(); + String name = comUser.getUserName(); + if (hasReply) { + builder.append(setClickableSpan(name, item.getCommentsUser())); + builder.append(" 回复 "); + builder.append(setClickableSpan(replyUser.getUserName(), item.getReplyUser())); + + } else { + builder.append(setClickableSpan(name, item.getCommentsUser())); + } + builder.append(" : "); + builder.append(setClickableSpanContent(item.getContent(), position)); + builder.append(" "); + textView.setText(builder); + // 设置点击背景色 + textView.setHighlightColor(getResources().getColor(android.R.color.transparent)); +// textView.setHighlightColor(0xff000000); + final CircleMovementMethod method = new CircleMovementMethod(0xffcccccc, 0xffcccccc); + textView.setMovementMethod(method); + + textView.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + if (method.isParseTv()) { + if (listener != null) { + listener.onItemClick(position, item); + } + } + } + }); + + return textView; + } + + /** + * 设置评论内容点击事件 + * + * @param item + * @param position + * @return + */ + public SpannableString setClickableSpanContent(final String item, final int position) { + final SpannableString string = new SpannableString(item); + ClickableSpan span = new ClickableSpan() { + @Override + public void onClick(View widget) { + // TODO: 2017/9/3 评论内容点击事件 + Toast.makeText(mContext, "position: " + position + " , content: " + item, Toast.LENGTH_SHORT).show(); + } + + @Override + public void updateDrawState(TextPaint ds) { + super.updateDrawState(ds); + // 设置显示的内容文本颜色 + ds.setColor(0xff686868); + ds.setUnderlineText(false); + } + }; + string.setSpan(span, 0, string.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + return string; + } + + /** + * 设置评论用户名字点击事件 + * + * @param item + * @param bean + * @return + */ + public SpannableString setClickableSpan(final String item, final UserBean bean) { + final SpannableString string = new SpannableString(item); + ClickableSpan span = new ClickableSpan() { + @Override + public void onClick(View widget) { + // TODO: 2017/9/3 评论用户名字点击事件 + Toast.makeText(mContext, bean.getUserName(), Toast.LENGTH_SHORT).show(); + } + + @Override + public void updateDrawState(TextPaint ds) { + super.updateDrawState(ds); + // 设置显示的用户名文本颜色 + ds.setColor(0xff387dcc); + ds.setUnderlineText(false); + } + }; + + string.setSpan(span, 0, string.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + return string; + } + + /** + * 定义一个用于回调的接口 + */ + public interface onItemClickListener { + void onItemClick(int position, CommentsBean bean); + } + +} diff --git a/app/src/main/java/com/lvfq/code/dynamic/view/LikesView.java b/app/src/main/java/com/lvfq/code/dynamic/view/LikesView.java new file mode 100644 index 0000000..779bcb0 --- /dev/null +++ b/app/src/main/java/com/lvfq/code/dynamic/view/LikesView.java @@ -0,0 +1,138 @@ +package com.lvfq.code.dynamic.view; + +import android.content.Context; +import android.support.annotation.Nullable; +import android.text.Spannable; +import android.text.SpannableString; +import android.text.SpannableStringBuilder; +import android.text.TextPaint; +import android.text.style.ClickableSpan; +import android.text.style.DynamicDrawableSpan; +import android.text.style.ImageSpan; +import android.util.AttributeSet; +import android.view.View; +import android.widget.TextView; + +import com.lvfq.code.dynamic.CircleMovementMethod; +import com.lvfq.code.dynamic.data.UserBean; +import com.lvfq.myworkingtest.R; + +import java.util.List; + +/** + * LikesView + * + * @author lvfq + * @Github: https://github.com/lvfaqiang + * @Blog: http://blog.csdn.net/lv_fq + * @date 2017/9/4 上午11:56 + * @desc : + */ + +public class LikesView extends TextView { + + private Context mContext; + private List list; + + public LikesView(Context context) { + this(context, null); + } + + public LikesView(Context context, @Nullable AttributeSet attrs) { + this(context, attrs, 0); + } + + public LikesView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + mContext = context; + } + + /** + * 设置点赞数据 + * + * @param list + */ + public void setList(List list) { + this.list = list; + } + + /** + * 刷新点赞列表 + */ + public void notifyDataSetChanged() { + if (list == null || list.size() <= 0) { + return; + } + SpannableStringBuilder builder = new SpannableStringBuilder(); + builder.append(setImageSpan()); + for (int i = 0; i < list.size(); i++) { + UserBean item = list.get(i); + builder.append(setClickableSpan(item.getUserName(), item)); + if (i != list.size() - 1) { + builder.append(" , "); + } else { + builder.append(" "); + } + } + + setText(builder); + setMovementMethod(new CircleMovementMethod(0xffcccccc, 0xffcccccc)); +// setMovementMethod(LinkMovementMethod.getInstance()); + } + + /** + * 设置评论用户名字点击事件 + * + * @param item + * @param bean + * @return + */ + public SpannableString setClickableSpan(final String item, final UserBean bean) { + final SpannableString string = new SpannableString(item); + ClickableSpan span = new ClickableSpan() { + @Override + public void onClick(View widget) { + // TODO: 2017/9/3 评论用户名字点击事件 +// Toast.makeText(mContext, bean.getUserName(), Toast.LENGTH_SHORT).show(); + if (listener != null) { + listener.onItemClick(0, bean); + } + } + + @Override + public void updateDrawState(TextPaint ds) { + super.updateDrawState(ds); + // 设置显示的文字颜色 + ds.setColor(0xff387dcc); + ds.setUnderlineText(false); + } + }; + + string.setSpan(span, 0, string.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + return string; + } + + /** + * 设置点赞图标 + * + * @return + */ + private SpannableString setImageSpan() { + String text = " "; + SpannableString imgSpanText = new SpannableString(text); + imgSpanText.setSpan(new ImageSpan(getContext(), R.mipmap.img_like_icon, DynamicDrawableSpan.ALIGN_BASELINE), + 0, 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + return imgSpanText; + } + + private onItemClickListener listener; + + public void setListener(onItemClickListener listener) { + this.listener = listener; + } + + public interface onItemClickListener { + void onItemClick(int position, UserBean bean); + } + +} diff --git a/app/src/main/java/com/lvfq/code/dynamic/view/MultiImageView.java b/app/src/main/java/com/lvfq/code/dynamic/view/MultiImageView.java new file mode 100644 index 0000000..df00e1e --- /dev/null +++ b/app/src/main/java/com/lvfq/code/dynamic/view/MultiImageView.java @@ -0,0 +1,213 @@ +package com.lvfq.code.dynamic.view; + +import android.content.Context; +import android.text.TextUtils; +import android.util.AttributeSet; +import android.view.View; +import android.widget.ImageView; +import android.widget.ImageView.ScaleType; +import android.widget.LinearLayout; + +import com.bumptech.glide.Glide; +import com.lvfq.library.utils.LvDPUtil; + +import java.util.List; + +/** + * @author shoyu + * @ClassName MultiImageView.java + * @Description: 显示1~N张图片的View + */ + +public class MultiImageView extends LinearLayout { + public static int MAX_WIDTH = 0; + + // 照片的Url列表 + private List imagesList; + + /** + * 长度 单位为Pixel * + */ + private int pxOneMaxWandH; // 单张图最大允许宽高 + private int pxMoreWandH = 0;// 多张图的宽高 + private int pxImagePadding = LvDPUtil.dip2px(3);// 图片间的间距 + + private int MAX_PER_ROW_COUNT = 3;// 每行显示最大数 + + private LayoutParams onePicPara; + private LayoutParams morePara, moreParaColumnFirst; + private LayoutParams rowPara; + + private OnItemClickListener mOnItemClickListener; + + public void setOnItemClickListener(OnItemClickListener onItemClickListener) { + mOnItemClickListener = onItemClickListener; + } + + public MultiImageView(Context context) { + super(context); + } + + public MultiImageView(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public void setList(List lists) throws IllegalArgumentException { + if (lists == null) { + throw new IllegalArgumentException("imageList is null..."); + } + imagesList = lists; + + if (MAX_WIDTH > 0) { + // 如果需要两张和四张图横向铺满, +// if (lists.size() == 2 || lists.size() == 4) { +// pxMoreWandH = (MAX_WIDTH - pxImagePadding) / 2; +// } else { + pxMoreWandH = (MAX_WIDTH - pxImagePadding * 2) / 3; //解决右侧图片和内容对不齐问题 +// } + pxOneMaxWandH = MAX_WIDTH * 2 / 3; // 一张图的时候,图片宽度 + initImageLayoutParams(); + } + + initView(); + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + if (MAX_WIDTH == 0) { + int width = measureWidth(widthMeasureSpec); + if (width > 0) { + MAX_WIDTH = width - getPaddingLeft() - getPaddingRight(); + if (imagesList != null && imagesList.size() > 0) { + setList(imagesList); + } + } + } + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + } + + /** + * Determines the width of this view + * + * @param measureSpec A measureSpec packed into an int + * @return The width of the view, honoring constraints from measureSpec + */ + private int measureWidth(int measureSpec) { + int result = 0; + int specMode = MeasureSpec.getMode(measureSpec); + int specSize = MeasureSpec.getSize(measureSpec); + + if (specMode == MeasureSpec.EXACTLY) { + // We were told how big to be + result = specSize; + } else { + // Measure the text + // result = (int) mTextPaint.measureText(mText) + getPaddingLeft() + // + getPaddingRight(); + if (specMode == MeasureSpec.AT_MOST) { + // Respect AT_MOST value if that was what is called for by + // measureSpec + result = Math.min(result, specSize); + } + } + return result; + } + + private void initImageLayoutParams() { + int wrap = LayoutParams.WRAP_CONTENT; + int match = LayoutParams.MATCH_PARENT; + + onePicPara = new LayoutParams(pxOneMaxWandH, wrap); + + moreParaColumnFirst = new LayoutParams(pxMoreWandH, pxMoreWandH); + morePara = new LayoutParams(pxMoreWandH, pxMoreWandH); + morePara.setMargins(pxImagePadding, 0, 0, 0); + + rowPara = new LayoutParams(match, wrap); + } + + // 根据imageView的数量初始化不同的View布局,还要为每一个View作点击效果 + private void initView() { + this.setOrientation(VERTICAL); + this.removeAllViews(); + if (MAX_WIDTH == 0) { + //为了触发onMeasure()来测量MultiImageView的最大宽度,MultiImageView的宽设置为match_parent + addView(new View(getContext())); + return; + } + + if (imagesList == null || imagesList.size() == 0) { + return; + } + + if (imagesList.size() == 1) { + addView(createImageView(0, false)); + } else { + int allCount = imagesList.size(); + if (allCount == 4) { + MAX_PER_ROW_COUNT = 2; + } else { + MAX_PER_ROW_COUNT = 3; + } + int rowCount = allCount / MAX_PER_ROW_COUNT + + (allCount % MAX_PER_ROW_COUNT > 0 ? 1 : 0);// 行数 + for (int rowCursor = 0; rowCursor < rowCount; rowCursor++) { + LinearLayout rowLayout = new LinearLayout(getContext()); + rowLayout.setOrientation(LinearLayout.HORIZONTAL); + + rowLayout.setLayoutParams(rowPara); + if (rowCursor != 0) { + rowLayout.setPadding(0, pxImagePadding, 0, 0); + } + + int columnCount = allCount % MAX_PER_ROW_COUNT == 0 ? MAX_PER_ROW_COUNT + : allCount % MAX_PER_ROW_COUNT;//每行的列数 + if (rowCursor != rowCount - 1) { + columnCount = MAX_PER_ROW_COUNT; + } + addView(rowLayout); + + int rowOffset = rowCursor * MAX_PER_ROW_COUNT;// 行偏移 + for (int columnCursor = 0; columnCursor < columnCount; columnCursor++) { + int position = columnCursor + rowOffset; + rowLayout.addView(createImageView(position, true)); + } + } + } + } + + private ImageView createImageView(final int position, final boolean isMultiImage) { + String url = ""; + if (!TextUtils.isEmpty(imagesList.get(position))) { + url = imagesList.get(position); + } + + ImageView imageView = new ColorFilterImageView(getContext()); + if (isMultiImage) { + imageView.setScaleType(ScaleType.CENTER_CROP); + imageView.setLayoutParams(position % MAX_PER_ROW_COUNT == 0 ? moreParaColumnFirst : morePara); + } else { + imageView.setAdjustViewBounds(true); + imageView.setScaleType(ScaleType.FIT_START); + imageView.setMaxHeight(pxOneMaxWandH); + imageView.setLayoutParams(onePicPara); + } + + imageView.setId(url.hashCode()); + imageView.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + if (mOnItemClickListener != null) { + mOnItemClickListener.onItemClick(v, position); + } + } + }); + // TODO: 2016/10/18 之后设置网络图片 + Glide.with(getContext()).load(url).into(imageView); + return imageView; + } + + public interface OnItemClickListener { + void onItemClick(View view, int position); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/lvfq/code/glide/GlideActivity.java b/app/src/main/java/com/lvfq/code/glide/GlideActivity.java new file mode 100644 index 0000000..9799e72 --- /dev/null +++ b/app/src/main/java/com/lvfq/code/glide/GlideActivity.java @@ -0,0 +1,62 @@ +package com.lvfq.code.glide; + +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.support.v4.app.FragmentActivity; +import android.widget.ImageView; + +import com.lvfq.library.utils.LvV; +import com.lvfq.myworkingtest.R; +import com.lvfq.code.dynamic.Data; +import com.lvfq.myworkingtest.util.GlideApp; + +/** + * GlideActivity + * + * @author lvfq + * @Github: https://github.com/lvfaqiang + * @Blog: http://blog.csdn.net/lv_fq + * @date 2017/9/2 下午3:17 + * @desc : + */ + +public class GlideActivity extends FragmentActivity { + + ImageView iv_1; + ImageView iv_2; + ImageView iv_3; + ImageView iv_4; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_glide); + + iv_1 = LvV.find(this, R.id.iv_1); + iv_2 = LvV.find(this, R.id.iv_2); + iv_3 = LvV.find(this, R.id.iv_3); + iv_4 = LvV.find(this, R.id.iv_4); + +// RequestOptions options = new RequestOptions(); +// options.centerCrop(); +// +// Glide.with(this) +// .load(Data.getImgs(1)) +// .apply(options) +// .into(iv_1); + + GlideApp.with(this) + .load(Data.getImgs(1)) + .fitCenter() + .into(iv_1); + +// GlideApp.with(this).load(Data.getImgs(1)).into(iv_1); +// Glide4_ImageLoadUtil.loadImg(this, Data.getImgs(1), R.mipmap.img_default, iv_1); + +// Glide4_ImageLoadUtil.loadCircleImg(this, Data.getImgs(1), R.mipmap.img_default, iv_2); +// +// Glide4_ImageLoadUtil.loadRoundImg(this, Data.getImgs(1), R.mipmap.img_default, iv_3); + + + } +} diff --git a/app/src/main/java/com/lvfq/code/http/HttpClient.java b/app/src/main/java/com/lvfq/code/http/HttpClient.java new file mode 100644 index 0000000..d9b5780 --- /dev/null +++ b/app/src/main/java/com/lvfq/code/http/HttpClient.java @@ -0,0 +1,56 @@ +package com.lvfq.code.http; + +import java.util.concurrent.TimeUnit; + +import okhttp3.OkHttpClient; +import retrofit2.Retrofit; +import retrofit2.converter.gson.GsonConverterFactory; + +/** + * HttpClient + * + * @author lvfq + * @date 2017/7/13 下午11:00 + * @mainFunction : + */ + +public class HttpClient { + + private static RequestService service; + private static long TIMOUT = 10000; //设置超时时间 +// http://an.zdeps.com/Invoking/user_info?keys=64b83c8381fc6d059ecd352f776124be&vci=12121212121H + + /** + * 调用 retrofit 服务 + * + * @return + */ + public static RequestService getService() { + if (service == null) { + synchronized (HttpClient.class) { + if (service == null) { + service = new Retrofit.Builder() + .baseUrl("http://192.168.0.107:8080/") + .addConverterFactory(NobodyConverterFactory.create()) + .addConverterFactory(GsonConverterFactory.create()) +// .client(new OkHttpClient().newBuilder().addInterceptor(new Interceptor() { +// @Override +// public Response intercept(Chain chain) throws IOException { +// Request request = chain.request(); +// HttpUrl url = request.url().newBuilder().addQueryParameter("platformType", "ANDROID").addQueryParameter("version", V.getVersionName(MyApplication.getContext())).build(); +// return chain.proceed(request.newBuilder().url(url).build()); +// } +// }).build()) + .client(new OkHttpClient().newBuilder().connectTimeout(TIMOUT, TimeUnit.MILLISECONDS) + .writeTimeout(TIMOUT, TimeUnit.MILLISECONDS) + .readTimeout(TIMOUT, TimeUnit.MILLISECONDS) + .build()) + .build() + .create(RequestService.class); + } + } + } + return service; + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/lvfq/code/http/NobodyConverterFactory.java b/app/src/main/java/com/lvfq/code/http/NobodyConverterFactory.java new file mode 100644 index 0000000..a19b45a --- /dev/null +++ b/app/src/main/java/com/lvfq/code/http/NobodyConverterFactory.java @@ -0,0 +1,64 @@ +package com.lvfq.code.http; + +import com.lvfq.code.NoBodyEntity; + +import java.io.IOException; +import java.lang.annotation.Annotation; +import java.lang.reflect.Type; + +import okhttp3.RequestBody; +import okhttp3.ResponseBody; +import retrofit2.Converter; +import retrofit2.Retrofit; + +/** + * NobodyConverterFactory + * + * @author lvfq + * @Github: https://github.com/lvfaqiang + * @Blog: http://blog.csdn.net/lv_fq + * @date 2017/8/4 下午11:04 + * @desc : + */ + +public class NobodyConverterFactory extends Converter.Factory { + + public static final NobodyConverterFactory create() { + return new NobodyConverterFactory(); + } + + private NobodyConverterFactory() { + } + + //将响应对象responseBody转成目标类型对象(也就是Call里给定的类型) + @Override + public Converter responseBodyConverter(Type type, Annotation[] annotations, + Retrofit retrofit) { + //判断当前的类型是否是我们需要处理的类型 + if (NoBodyEntity.class.equals(type)) { + //是则创建一个Converter返回转换数据 + return new Converter() { + @Override + public NoBodyEntity convert(ResponseBody value) throws IOException { + //这里直接返回null是因为我们不需要使用到响应体,本来也没有响应体. + //返回的对象会存到response.body()里. + return null; + } + }; + } + return null; + } + + //其它两个方法我们不需要使用到.所以不需要重写. + @Override + public Converter requestBodyConverter(Type type, + Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) { + return null; + } + + @Override + public Converter stringConverter(Type type, Annotation[] annotations, + Retrofit retrofit) { + return null; + } +} diff --git a/app/src/main/java/com/lvfq/code/http/RequestService.java b/app/src/main/java/com/lvfq/code/http/RequestService.java new file mode 100644 index 0000000..4215f17 --- /dev/null +++ b/app/src/main/java/com/lvfq/code/http/RequestService.java @@ -0,0 +1,33 @@ +package com.lvfq.code.http; + +import com.lvfq.code.ModelBean; + +import retrofit2.Call; +import retrofit2.http.Field; +import retrofit2.http.FormUrlEncoded; +import retrofit2.http.GET; +import retrofit2.http.POST; +import retrofit2.http.Query; + +/** + * RequestService + * + * @author lvfq + * @date 2017/7/13 下午11:00 + * @mainFunction : + */ + +public interface RequestService { + + @POST("login") + Call login(@Query("userName") String userName, + @Query("passWord") String passWord); + + @FormUrlEncoded + @POST("Invoking/user_info") + Call userInfo(@Field("keys") String keys, + @Field("vci") String vci); + + @GET("front/server") + Call serverInfo(); +} diff --git a/app/src/main/java/com/lvfq/code/mvp/Http.java b/app/src/main/java/com/lvfq/code/mvp/Http.java new file mode 100644 index 0000000..6eb3228 --- /dev/null +++ b/app/src/main/java/com/lvfq/code/mvp/Http.java @@ -0,0 +1,23 @@ +package com.lvfq.code.mvp; + +import java.util.HashMap; +import java.util.Map; + +/** + * Http + * + * @author lvfq + * @date 2017/7/13 下午2:22 + * @mainFunction : + */ + +public class Http { + + public static void http_login(String userName, String password, IHttpResultListener listener) { + Map map = new HashMap<>(); + map.put("userName", userName); + map.put("passWord", password); + HttpUtil.post("login", map, listener); + } + +} diff --git a/app/src/main/java/com/lvfq/code/mvp/HttpUtil.java b/app/src/main/java/com/lvfq/code/mvp/HttpUtil.java new file mode 100644 index 0000000..3654dee --- /dev/null +++ b/app/src/main/java/com/lvfq/code/mvp/HttpUtil.java @@ -0,0 +1,106 @@ +package com.lvfq.code.mvp; + +import android.os.Handler; +import android.util.Log; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.net.HttpURLConnection; +import java.net.URL; +import java.util.Map; + +/** + * HttpUtil + * + * @author lvfq + * @date 2017/7/13 下午12:17 + * @mainFunction : + */ + +public class HttpUtil { + + static final String HTTP = "http://192.168.2.1:8080/"; + + private static Handler handler = new Handler(); + + public static void post(final String url, final Map params, final IHttpResultListener listener) { + new Thread(new Runnable() { + @Override + public void run() { + String result = ""; + HttpURLConnection conn = null; + OutputStream out = null; + BufferedReader reader = null; + try { + StringBuilder paramsStr = new StringBuilder(); + if (params != null && params.size() > 0) { + for (Map.Entry entry : params.entrySet()) { + paramsStr.append(entry.getKey()).append("=").append(entry.getValue().toString()).append("&"); + } + paramsStr.deleteCharAt(paramsStr.length() - 1); + } + URL u = new URL(HTTP + url); + conn = (HttpURLConnection) u.openConnection(); + + // 设置连接参数 + conn.setDoOutput(true); + conn.setDoInput(true); + conn.setRequestMethod("POST");// 设置以POST方式 + conn.setUseCaches(false); // Post请求不使用缓存 + conn.setInstanceFollowRedirects(true); + conn.setRequestProperty("Content-Type", + "application/x-www-form-urlencoded"); + conn.setRequestProperty("Charset", "UTF-8"); + + conn.setConnectTimeout(10000); + conn.setReadTimeout(10000); + + // 上传的参数 + Log.i("lfq", paramsStr.toString()); + out = conn.getOutputStream(); + out.write(paramsStr.toString().getBytes()); + out.flush(); + out.close(); + + reader = new BufferedReader(new InputStreamReader(conn.getInputStream())); + StringBuffer strBuf = new StringBuffer(); + String str = null; + while ((str = reader.readLine()) != null) { + strBuf.append(str); + } + result = strBuf.toString(); + Log.i("lfq", strBuf.toString()); + } catch (Exception e) { + e.printStackTrace(); + result = e.toString(); + } finally { + try { + if (out != null) { + out.close(); + } + if (reader != null) { + reader.close(); + } + if (conn != null) { + conn.disconnect(); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + if (listener != null) { + final String res = result; + handler.post(new Runnable() { + @Override + public void run() { + listener.onResult(res); + } + }); + } + } + }).start(); + + } +} diff --git a/app/src/main/java/com/lvfq/code/mvp/IHttpResultListener.java b/app/src/main/java/com/lvfq/code/mvp/IHttpResultListener.java new file mode 100644 index 0000000..df0af43 --- /dev/null +++ b/app/src/main/java/com/lvfq/code/mvp/IHttpResultListener.java @@ -0,0 +1,13 @@ +package com.lvfq.code.mvp; + +/** + * IHttpResultListener + * + * @author lvfq + * @date 2017/7/13 下午2:20 + * @mainFunction : + */ + +public interface IHttpResultListener { + void onResult(String t); +} diff --git a/app/src/main/java/com/lvfq/code/mvp/LoginActivity.java b/app/src/main/java/com/lvfq/code/mvp/LoginActivity.java new file mode 100644 index 0000000..86e23b7 --- /dev/null +++ b/app/src/main/java/com/lvfq/code/mvp/LoginActivity.java @@ -0,0 +1,77 @@ +package com.lvfq.code.mvp; + +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.util.Log; +import android.view.View; +import android.widget.Toast; + +import com.lvfq.code.BaseActivity; +import com.lvfq.code.ModelBean; +import com.lvfq.code.mvp.demo3.LoginPresenter3; +import com.lvfq.myworkingtest.R; +import com.lvfq.code.http.HttpClient; +import com.lvfq.code.mvp.demo3.LoginView3; + +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; + +/** + * LoginActivity + * + * @author lvfq + * @date 2017/7/12 下午9:46 + * @mainFunction : + */ + +public class LoginActivity extends BaseActivity implements LoginView3 { + + @Override + public LoginPresenter3 bindPresenter() { + return new LoginPresenter3(); + } + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_login); + } + + + public void clickLogin(View view) { +// getPresenter().login("发强", "123456"); + HttpClient.getService().serverInfo().enqueue(new Callback() { + @Override + public void onResponse(Call call, Response response) { + ModelBean bean = response.body(); + Log.i("lfq", bean.getResultData().isMainServer() + ""); + } + + @Override + public void onFailure(Call call, Throwable t) { + Log.i("lfq", t.getMessage() + ""); + } + }); + +// Http.http_login("发强", "123456", this); +// HttpClient.getService().login("lvfaqiang", "123456").enqueue(new Callback() { +// @Override +// public void onResponse(Call call, Response response) { +// ModelBean bean = response.body(); +// Log.i("lfq", "" + bean.getStatus()); +// } +// +// @Override +// public void onFailure(Call call, Throwable t) { +// Log.i("lfq", t.toString()); +// } +// }); + } + + @Override + public void onResult(final String s) { + Toast.makeText(LoginActivity.this, s, Toast.LENGTH_SHORT).show(); + Log.i("lfq", "login Result: " + s); + } +} diff --git a/app/src/main/java/com/lvfq/code/mvp/RegisterActivity.java b/app/src/main/java/com/lvfq/code/mvp/RegisterActivity.java new file mode 100644 index 0000000..c05460a --- /dev/null +++ b/app/src/main/java/com/lvfq/code/mvp/RegisterActivity.java @@ -0,0 +1,20 @@ +package com.lvfq.code.mvp; + +import com.lvfq.code.BaseActivity; +import com.lvfq.code.mvp.demo3.BaseMvpPresenter; + +/** + * RegisterActivity + * + * @author lvfq + * @date 2017/7/17 下午10:13 + * @mainFunction : + */ + +public class RegisterActivity extends BaseActivity { + @Override + public BaseMvpPresenter bindPresenter() { + return null; + } + +} diff --git a/app/src/main/java/com/lvfq/code/mvp/demo1/LoginModel.java b/app/src/main/java/com/lvfq/code/mvp/demo1/LoginModel.java new file mode 100644 index 0000000..3e732b2 --- /dev/null +++ b/app/src/main/java/com/lvfq/code/mvp/demo1/LoginModel.java @@ -0,0 +1,20 @@ +package com.lvfq.code.mvp.demo1; + +import com.lvfq.code.mvp.Http; +import com.lvfq.code.mvp.IHttpResultListener; + +/** + * LoginModel + * + * @author lvfq + * @date 2017/7/13 下午11:22 + * @mainFunction : M 层 + */ + +public class LoginModel { + + public void login(String userName, String passWord, IHttpResultListener listener) { + Http.http_login(userName, passWord, listener); + } + +} diff --git a/app/src/main/java/com/lvfq/code/mvp/demo1/LoginPresenter.java b/app/src/main/java/com/lvfq/code/mvp/demo1/LoginPresenter.java new file mode 100644 index 0000000..0e02ed2 --- /dev/null +++ b/app/src/main/java/com/lvfq/code/mvp/demo1/LoginPresenter.java @@ -0,0 +1,39 @@ +package com.lvfq.code.mvp.demo1; + +import com.lvfq.code.mvp.IHttpResultListener; + +/** + * LoginPresenter + * + * @author lvfq + * @date 2017/7/13 下午11:21 + * @mainFunction : + */ + +public class LoginPresenter { + + private LoginModel loginModel; + private LoginView loginView; + + public LoginPresenter(LoginView loginView) { + this.loginView = loginView; + loginModel = new LoginModel(); + } + + /** + * 登录 + * + * @param userName + * @param passWord + */ + public void login(String userName, String passWord) { + loginModel.login(userName, passWord, new IHttpResultListener() { + @Override + public void onResult(String t) { + if (loginView != null) { + loginView.onResult(t); + } + } + }); + } +} diff --git a/app/src/main/java/com/lvfq/code/mvp/demo1/LoginView.java b/app/src/main/java/com/lvfq/code/mvp/demo1/LoginView.java new file mode 100644 index 0000000..cada149 --- /dev/null +++ b/app/src/main/java/com/lvfq/code/mvp/demo1/LoginView.java @@ -0,0 +1,15 @@ +package com.lvfq.code.mvp.demo1; + +/** + * LoginView + * + * @author lvfq + * @date 2017/7/13 下午11:21 + * @mainFunction : 解耦和 + */ + +public interface LoginView { + + void onResult(String result); + +} diff --git a/app/src/main/java/com/lvfq/code/mvp/demo2/LoginModel2.java b/app/src/main/java/com/lvfq/code/mvp/demo2/LoginModel2.java new file mode 100644 index 0000000..5d5f33f --- /dev/null +++ b/app/src/main/java/com/lvfq/code/mvp/demo2/LoginModel2.java @@ -0,0 +1,20 @@ +package com.lvfq.code.mvp.demo2; + +import com.lvfq.code.mvp.Http; +import com.lvfq.code.mvp.IHttpResultListener; + +/** + * LoginModel + * + * @author lvfq + * @date 2017/7/13 下午11:22 + * @mainFunction : M 层 + */ + +public class LoginModel2 { + + public void login(String userName, String passWord, IHttpResultListener listener) { + Http.http_login(userName, passWord, listener); + } + +} diff --git a/app/src/main/java/com/lvfq/code/mvp/demo2/LoginPresenter2.java b/app/src/main/java/com/lvfq/code/mvp/demo2/LoginPresenter2.java new file mode 100644 index 0000000..44b100b --- /dev/null +++ b/app/src/main/java/com/lvfq/code/mvp/demo2/LoginPresenter2.java @@ -0,0 +1,46 @@ +package com.lvfq.code.mvp.demo2; + +import com.lvfq.code.mvp.IHttpResultListener; + +/** + * LoginPresenter + * + * @author lvfq + * @date 2017/7/13 下午11:21 + * @mainFunction : + */ + +public class LoginPresenter2 { + + private LoginModel2 loginModel; + private LoginView2 loginView; + + public LoginPresenter2() { + loginModel = new LoginModel2(); + } + + public void attachView(LoginView2 loginView) { + this.loginView = loginView; + } + + public void dettachView() { + this.loginView = null; + } + + /** + * 登录 + * + * @param userName + * @param passWord + */ + public void login(String userName, String passWord) { + loginModel.login(userName, passWord, new IHttpResultListener() { + @Override + public void onResult(String t) { + if (loginView != null) { + loginView.onResult(t); + } + } + }); + } +} diff --git a/app/src/main/java/com/lvfq/code/mvp/demo2/LoginView2.java b/app/src/main/java/com/lvfq/code/mvp/demo2/LoginView2.java new file mode 100644 index 0000000..0482c3e --- /dev/null +++ b/app/src/main/java/com/lvfq/code/mvp/demo2/LoginView2.java @@ -0,0 +1,15 @@ +package com.lvfq.code.mvp.demo2; + +/** + * LoginView + * + * @author lvfq + * @date 2017/7/13 下午11:21 + * @mainFunction : 解耦和 + */ + +public interface LoginView2 { + + void onResult(String result); + +} diff --git a/app/src/main/java/com/lvfq/code/mvp/demo3/BaseMvpPresenter.java b/app/src/main/java/com/lvfq/code/mvp/demo3/BaseMvpPresenter.java new file mode 100644 index 0000000..cbce57a --- /dev/null +++ b/app/src/main/java/com/lvfq/code/mvp/demo3/BaseMvpPresenter.java @@ -0,0 +1,28 @@ +package com.lvfq.code.mvp.demo3; + +/** + * BaseMvpPresenter + * + * @author lvfq + * @date 2017/7/17 下午3:25 + * @mainFunction : + */ + +public class BaseMvpPresenter implements IBasePresenter { + private V view; + + @Override + public V getView() { + return view; + } + + @Override + public void attachView(V view) { + this.view = view; + } + + @Override + public void detachView() { + this.view = null; + } +} diff --git a/app/src/main/java/com/lvfq/code/mvp/demo3/IBaseMvpView.java b/app/src/main/java/com/lvfq/code/mvp/demo3/IBaseMvpView.java new file mode 100644 index 0000000..90f39b9 --- /dev/null +++ b/app/src/main/java/com/lvfq/code/mvp/demo3/IBaseMvpView.java @@ -0,0 +1,13 @@ +package com.lvfq.code.mvp.demo3; + +/** + * IBaseMvpView + * + * @author lvfq + * @date 2017/7/17 下午3:15 + * @mainFunction : + */ + +public interface IBaseMvpView { + +} diff --git a/app/src/main/java/com/lvfq/code/mvp/demo3/IBasePresenter.java b/app/src/main/java/com/lvfq/code/mvp/demo3/IBasePresenter.java new file mode 100644 index 0000000..0ad225d --- /dev/null +++ b/app/src/main/java/com/lvfq/code/mvp/demo3/IBasePresenter.java @@ -0,0 +1,19 @@ +package com.lvfq.code.mvp.demo3; + +/** + * IBasePresenter + * + * @author lvfq + * @Github: https://github.com/lvfaqiang + * @Blog: http://blog.csdn.net/lv_fq + * @date 2017/7/26 下午12:40 + * @desc : + */ + +public interface IBasePresenter { + V getView(); + + void attachView(V view); + + void detachView(); +} diff --git a/app/src/main/java/com/lvfq/code/mvp/demo3/LoginModel3.java b/app/src/main/java/com/lvfq/code/mvp/demo3/LoginModel3.java new file mode 100644 index 0000000..f91f212 --- /dev/null +++ b/app/src/main/java/com/lvfq/code/mvp/demo3/LoginModel3.java @@ -0,0 +1,27 @@ +package com.lvfq.code.mvp.demo3; + +import com.lvfq.code.mvp.Http; +import com.lvfq.code.mvp.IHttpResultListener; + +/** + * LoginModel + * + * @author lvfq + * @date 2017/7/13 下午11:22 + * @mainFunction : M 层 + */ + +public class LoginModel3 { + + public void login(String userName, String passWord, IHttpResultListener listener) { + Http.http_login(userName, passWord, listener); + } + + /** + * 保存登录用户数据 + */ + public void saveUserData(){ + //... + } + +} diff --git a/app/src/main/java/com/lvfq/code/mvp/demo3/LoginPresenter3.java b/app/src/main/java/com/lvfq/code/mvp/demo3/LoginPresenter3.java new file mode 100644 index 0000000..8be1791 --- /dev/null +++ b/app/src/main/java/com/lvfq/code/mvp/demo3/LoginPresenter3.java @@ -0,0 +1,41 @@ +package com.lvfq.code.mvp.demo3; + +import com.lvfq.code.mvp.IHttpResultListener; + +/** + * LoginPresenter + * + * @author lvfq + * @date 2017/7/13 下午11:21 + * @mainFunction : + */ + +public class LoginPresenter3 extends BaseMvpPresenter { + + private LoginModel3 loginModel; + + public LoginPresenter3() { + loginModel = new LoginModel3(); + } + + /** + * 登录 + * + * @param userName + * @param passWord + */ + public void login(String userName, String passWord) { + loginModel.login(userName, passWord, new IHttpResultListener() { + @Override + public void onResult(String t) { + // 其他的数据操作。 + loginModel.saveUserData(); + + if (getView() != null) { + // 最终返回界面,进行 UI 操作。 + getView().onResult(t); + } + } + }); + } +} diff --git a/app/src/main/java/com/lvfq/code/mvp/demo3/LoginView3.java b/app/src/main/java/com/lvfq/code/mvp/demo3/LoginView3.java new file mode 100644 index 0000000..b12849d --- /dev/null +++ b/app/src/main/java/com/lvfq/code/mvp/demo3/LoginView3.java @@ -0,0 +1,15 @@ +package com.lvfq.code.mvp.demo3; + +/** + * LoginView + * + * @author lvfq + * @date 2017/7/13 下午11:21 + * @mainFunction : 解耦和 + */ + +public interface LoginView3 extends IBaseMvpView { + + void onResult(String result); + +} diff --git a/app/src/main/java/com/lvfq/code/tablayout/PagerSlidingTabStrip.java b/app/src/main/java/com/lvfq/code/tablayout/PagerSlidingTabStrip.java new file mode 100755 index 0000000..f8727de --- /dev/null +++ b/app/src/main/java/com/lvfq/code/tablayout/PagerSlidingTabStrip.java @@ -0,0 +1,689 @@ +/* + * Copyright (C) 2013 Andreas Stuetz + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.lvfq.code.tablayout; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.res.TypedArray; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.Paint.Style; +import android.graphics.Typeface; +import android.os.Build; +import android.os.Parcel; +import android.os.Parcelable; +import android.support.v4.view.ViewPager; +import android.support.v4.view.ViewPager.OnPageChangeListener; +import android.util.AttributeSet; +import android.util.DisplayMetrics; +import android.util.TypedValue; +import android.view.Gravity; +import android.view.View; +import android.view.ViewTreeObserver.OnGlobalLayoutListener; +import android.widget.HorizontalScrollView; +import android.widget.ImageButton; +import android.widget.LinearLayout; +import android.widget.TextView; + +import com.lvfq.myworkingtest.R; + +import java.util.Locale; + +/** + * PagerSlidingTabStrip + * + * @author lvfq + * @Github: https://github.com/lvfaqiang + * @Blog: http://blog.csdn.net/lv_fq + * @date 2017/8/29 上午10:35 + * @desc : + */ + +public class PagerSlidingTabStrip extends HorizontalScrollView { + + public interface IconTabProvider { + public int getPageIconResId(int position); + } + + // @formatter:off + private static final int[] ATTRS = new int[]{android.R.attr.textSize, + android.R.attr.textColor}; + // @formatter:on + + private LinearLayout.LayoutParams defaultTabLayoutParams; + private LinearLayout.LayoutParams expandedTabLayoutParams; + + private final PageListener pageListener = new PageListener(); + public OnPageChangeListener delegatePageListener; + + private LinearLayout tabsContainer; + private ViewPager pager; + + private int pageCount; + + private int currentPosition = 0; + private float currentPositionOffset = 0f; + + private Paint rectPaint; + private Paint dividerPaint; + + private boolean checkedTabWidths = false; + + private int indicatorColor = 0xffFF811C; // 指示器颜色 + private int underlineColor = 0xffCECECE; // 下划线颜色 + private int dividerColor = 0xFF811C; // 分割线颜色 + private int indicatorPadding = 10; //指示器 左右内边距 + + private boolean shouldExpand = false;//FF811C + private boolean textAllCaps = true; + + private int scrollOffset = 52; + private int indicatorHeight = 0; // 指示器高度 + private int underlineHeight = 0; // 下划线高度 + private int dividerPadding = 6; // 分割线 + private int tabPadding = 22; + private int tabPaddingr = 19; // 选中的tab padding + private int dividerWidth = 1; + private int tabTextSize = 16; // 默认文字大小 + private int tabTextColor = 0xff999999; // 默认颜色 + + private int tabTextSizer = 16; // 选中的文字大小 + private int tabTextColorr = 0xffffffff; // 选中颜色 + private Typeface tabTypeface = null; + private int tabTypefaceStyle = Typeface.NORMAL; + + private int lastScrollX = 0; + + private int tabBackgroundResId /*= R.drawable.background_tab*/; + + private Locale locale; +// PageSelectedImpl mSelected; + + public PagerSlidingTabStrip(Context context) { + this(context, null); + } + + public PagerSlidingTabStrip(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + public PagerSlidingTabStrip(Context context, AttributeSet attrs, + int defStyle) { + super(context, attrs, defStyle); + + setFillViewport(true); + setWillNotDraw(false); + + tabsContainer = new LinearLayout(context); + tabsContainer.setOrientation(LinearLayout.HORIZONTAL); + tabsContainer.setLayoutParams(new LayoutParams( + LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); + addView(tabsContainer); + + DisplayMetrics dm = getResources().getDisplayMetrics(); + + scrollOffset = (int) TypedValue.applyDimension( + TypedValue.COMPLEX_UNIT_DIP, scrollOffset, dm); + indicatorHeight = (int) TypedValue.applyDimension( + TypedValue.COMPLEX_UNIT_DIP, indicatorHeight, dm); + underlineHeight = (int) TypedValue.applyDimension( + TypedValue.COMPLEX_UNIT_DIP, underlineHeight, dm); + dividerPadding = (int) TypedValue.applyDimension( + TypedValue.COMPLEX_UNIT_DIP, dividerPadding, dm); + tabPadding = (int) TypedValue.applyDimension( + TypedValue.COMPLEX_UNIT_DIP, tabPadding, dm); + tabPaddingr = (int) TypedValue.applyDimension( + TypedValue.COMPLEX_UNIT_DIP, tabPaddingr, dm); + indicatorPadding = (int) TypedValue.applyDimension( + TypedValue.COMPLEX_UNIT_DIP, indicatorPadding, dm); + dividerWidth = (int) TypedValue.applyDimension( + TypedValue.COMPLEX_UNIT_DIP, dividerWidth, dm); + tabTextSize = (int) TypedValue.applyDimension( + TypedValue.COMPLEX_UNIT_SP, tabTextSize, dm); + tabTextSizer = (int) TypedValue.applyDimension( + TypedValue.COMPLEX_UNIT_SP, tabTextSizer, dm); + // get system attrs (android:textSize and android:textColor) + + TypedArray a = context.obtainStyledAttributes(attrs, ATTRS); + + tabTextSize = a.getDimensionPixelSize(0, tabTextSize); + tabTextColor = a.getColor(1, tabTextColor); + + a.recycle(); + + // get custom attrs + + a = context.obtainStyledAttributes(attrs, R.styleable.PagerSlidingTabStrip); + + indicatorColor = a.getColor(R.styleable.PagerSlidingTabStrip_indicatorColor, indicatorColor); + indicatorPadding = a.getDimensionPixelSize(R.styleable.PagerSlidingTabStrip_indicatorPaddingLeftRight, indicatorPadding); + underlineColor = a.getColor(R.styleable.PagerSlidingTabStrip_underlineColor, underlineColor); + dividerColor = a.getColor(R.styleable.PagerSlidingTabStrip_dividerColor, dividerColor); + indicatorHeight = a.getDimensionPixelSize(R.styleable.PagerSlidingTabStrip_indicatorHeight, indicatorHeight); + underlineHeight = a.getDimensionPixelSize(R.styleable.PagerSlidingTabStrip_underlineHeight, underlineHeight); + dividerPadding = a.getDimensionPixelSize(R.styleable.PagerSlidingTabStrip_dividerPadding, dividerPadding); + tabPadding = a.getDimensionPixelSize(R.styleable.PagerSlidingTabStrip_tabPaddingLeftRight, tabPadding); + tabBackgroundResId = a.getResourceId(R.styleable.PagerSlidingTabStrip_tabBackground, tabBackgroundResId); + shouldExpand = a.getBoolean(R.styleable.PagerSlidingTabStrip_shouldExpand, shouldExpand); + scrollOffset = a.getDimensionPixelSize(R.styleable.PagerSlidingTabStrip_scrollOffset, scrollOffset); +// textAllCaps = a.getBoolean(R.styleable.PagerSlidingTabStrip_textAllCaps, textAllCaps); + tabTextSize = a.getDimensionPixelSize(R.styleable.PagerSlidingTabStrip_tabDefTextSize, tabTextSize); + tabTextSizer = a.getDimensionPixelSize(R.styleable.PagerSlidingTabStrip_tabSelTextSize, tabTextSizer); + tabTextColor = a.getColor(R.styleable.PagerSlidingTabStrip_tabDefTextColor, tabTextColor); + tabTextColorr = a.getColor(R.styleable.PagerSlidingTabStrip_tabSelTextColor, tabTextColorr); + + a.recycle(); + + rectPaint = new Paint(); + rectPaint.setAntiAlias(true); + rectPaint.setStyle(Style.FILL); + + dividerPaint = new Paint(); + dividerPaint.setAntiAlias(true); + dividerPaint.setStrokeWidth(dividerWidth); + + defaultTabLayoutParams = new LinearLayout.LayoutParams(0, + LayoutParams.MATCH_PARENT, 1.0f); +// defaultTabLayoutParams = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT); + expandedTabLayoutParams = new LinearLayout.LayoutParams(0, + LayoutParams.MATCH_PARENT, 1.0f); + + if (locale == null) { + locale = getResources().getConfiguration().locale; + } + } + + /** + * 设置一个回调接口 + * + * @param pager + */ + public void setViewPager(ViewPager pager) { + this.pager = pager; + + if (pager.getAdapter() == null) { + throw new IllegalStateException( + "ViewPager does not have adapter instance."); + } + + pager.setOnPageChangeListener(pageListener); + + notifyDataSetChanged(); + } + + public void setOnPageChangeListener(OnPageChangeListener listener) { + this.delegatePageListener = listener; + } + + public void notifyDataSetChanged() { + + tabsContainer.removeAllViews(); + + pageCount = pager.getAdapter().getCount(); + + for (int i = 0; i < pageCount; i++) { + + if (pager.getAdapter() instanceof IconTabProvider) { + addIconTab(i, + ((IconTabProvider) pager.getAdapter()) + .getPageIconResId(i)); + } else { + addTextTab(i, pager.getAdapter().getPageTitle(i).toString()); + } + + } + + updateTabStyles(); + + checkedTabWidths = false; + + getViewTreeObserver().addOnGlobalLayoutListener( + new OnGlobalLayoutListener() { + + @SuppressWarnings("deprecation") + @SuppressLint("NewApi") + @Override + public void onGlobalLayout() { + + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) { + getViewTreeObserver().removeGlobalOnLayoutListener( + this); + } else { + getViewTreeObserver().removeOnGlobalLayoutListener( + this); + } + + currentPosition = pager.getCurrentItem(); + scrollToChild(currentPosition, 0); + } + }); + + } + + private void addTextTab(final int position, String title) { + + TextView tab = new TextView(getContext()); + tab.setText(title); + tab.setFocusable(true); + tab.setGravity(Gravity.CENTER); + tab.setSingleLine(); + + tab.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + pager.setCurrentItem(position); + } + }); + + tabsContainer.addView(tab); + + } + + private void addIconTab(final int position, int resId) { + + ImageButton tab = new ImageButton(getContext()); + tab.setFocusable(true); + tab.setImageResource(resId); + + tab.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + pager.setCurrentItem(position); + } + }); + + tabsContainer.addView(tab); + + } + + private void updateTabStyles() { + int currentIndex = this.pager.getCurrentItem(); + for (int i = 0; i < pageCount; i++) { + + View v = tabsContainer.getChildAt(i); + + v.setLayoutParams(defaultTabLayoutParams); + v.setBackgroundResource(tabBackgroundResId); + + if (v instanceof TextView) { + + TextView tab = (TextView) v; + tab.setTypeface(tabTypeface, tabTypefaceStyle); + v.setPadding(tabPadding, 0, tabPadding, 0); + if (currentIndex == i) { + tab.setTextSize(TypedValue.COMPLEX_UNIT_PX, tabTextSizer); + tab.setTextColor(tabTextColorr); +// if (shouldExpand) { +// v.setPadding(tabPadding, 0, tabPadding, 0); +// } else { +// v.setPadding(tabPadding, 0, tabPadding, 0); +// } + } else { + tab.setTextSize(TypedValue.COMPLEX_UNIT_PX, tabTextSize); + tab.setTextColor(tabTextColor); +// if (shouldExpand) { +// v.setPadding(0, 0, 0, 0); +// } else { +// v.setPadding(0, 0, 0, 0); +// } + } + // setAllCaps() is only available from API 14, so the upper case + // is made manually if we are on a + // pre-ICS-build + if (textAllCaps) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) { + tab.setAllCaps(true); + } else { + tab.setText(tab.getText().toString() + .toUpperCase(locale)); + } + } + } + } + + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + + if (!shouldExpand + || MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.UNSPECIFIED) { + return; + } + + int myWidth = getMeasuredWidth(); + int childWidth = 0; + for (int i = 0; i < pageCount; i++) { + childWidth += tabsContainer.getChildAt(i).getMeasuredWidth(); + } + + if (!checkedTabWidths && childWidth > 0 && myWidth > 0) { + + if (childWidth <= myWidth) { + for (int i = 0; i < pageCount; i++) { + tabsContainer.getChildAt(i).setLayoutParams( + expandedTabLayoutParams); + } + } + + checkedTabWidths = true; + } + } + + private void scrollToChild(int position, int offset) { + + if (pageCount == 0) { + return; + } + + int newScrollX = tabsContainer.getChildAt(position).getLeft() + offset; + + if (position > 0 || offset > 0) { + newScrollX -= scrollOffset; + } + + if (newScrollX != lastScrollX) { + lastScrollX = newScrollX; + scrollTo(newScrollX, 0); + } + + } + + @Override + protected void onDraw(Canvas canvas) { + super.onDraw(canvas); + + if (isInEditMode() || pageCount == 0) { + return; + } + + final int height = getHeight(); + + // draw indicator line + + rectPaint.setColor(indicatorColor); + + // default: line below current tab + View currentTab = tabsContainer.getChildAt(currentPosition); + float lineLeft = currentTab.getLeft(); + float lineRight = currentTab.getRight(); + + // if there is an offset, start interpolating left and right coordinates + // between current and next tab + if (currentPositionOffset > 0f && currentPosition < pageCount - 1) { + + View nextTab = tabsContainer.getChildAt(currentPosition + 1); + final float nextTabLeft = nextTab.getLeft(); + final float nextTabRight = nextTab.getRight(); + + lineLeft = (currentPositionOffset * nextTabLeft + (1f - currentPositionOffset) + * lineLeft); + lineRight = (currentPositionOffset * nextTabRight + (1f - currentPositionOffset) + * lineRight); + } + + canvas.drawRect(lineLeft + indicatorPadding, height - indicatorHeight, lineRight - indicatorPadding, height, + rectPaint); + + // draw underline + + rectPaint.setColor(underlineColor); + canvas.drawRect(0, height - underlineHeight, tabsContainer.getWidth(), + height, rectPaint); + + // draw divider + + dividerPaint.setColor(dividerColor); + for (int i = 0; i < pageCount - 1; i++) { + View tab = tabsContainer.getChildAt(i); + canvas.drawLine(tab.getRight(), dividerPadding, tab.getRight(), + height - dividerPadding, dividerPaint); + } + } + + private class PageListener implements OnPageChangeListener { + + @Override + public void onPageScrolled(int position, float positionOffset, + int positionOffsetPixels) { + + currentPosition = position; + currentPositionOffset = positionOffset; + + scrollToChild(position, (int) (positionOffset * tabsContainer + .getChildAt(position).getWidth())); + + invalidate(); + + if (delegatePageListener != null) { + delegatePageListener.onPageScrolled(position, positionOffset, + positionOffsetPixels); + } + } + + @Override + public void onPageScrollStateChanged(int state) { + if (state == ViewPager.SCROLL_STATE_IDLE) { + scrollToChild(pager.getCurrentItem(), 0); + } + + if (delegatePageListener != null) { + delegatePageListener.onPageScrollStateChanged(state); + } + } + + @Override + public void onPageSelected(int position) { + if (delegatePageListener != null) { + delegatePageListener.onPageSelected(position); + } +// mSelected.selectedPage(position); + updateTabStyles(); + } + + } + + public void setIndicatorColor(int indicatorColor) { + this.indicatorColor = indicatorColor; + invalidate(); + } + + public void setIndicatorColorResource(int resId) { + this.indicatorColor = getResources().getColor(resId); + invalidate(); + } + + public int getIndicatorColor() { + return this.indicatorColor; + } + + public void setIndicatorHeight(int indicatorLineHeightPx) { + this.indicatorHeight = indicatorLineHeightPx; + invalidate(); + } + + public int getIndicatorHeight() { + return indicatorHeight; + } + + public void setUnderlineColor(int underlineColor) { + this.underlineColor = underlineColor; + invalidate(); + } + + public void setUnderlineColorResource(int resId) { + this.underlineColor = getResources().getColor(resId); + invalidate(); + } + + public int getUnderlineColor() { + return underlineColor; + } + + public void setDividerColor(int dividerColor) { + this.dividerColor = dividerColor; + invalidate(); + } + + public void setDividerColorResource(int resId) { + this.dividerColor = getResources().getColor(resId); + invalidate(); + } + + public int getDividerColor() { + return dividerColor; + } + + public void setUnderlineHeight(int underlineHeightPx) { + this.underlineHeight = underlineHeightPx; + invalidate(); + } + + public int getUnderlineHeight() { + return underlineHeight; + } + + public void setDividerPadding(int dividerPaddingPx) { + this.dividerPadding = dividerPaddingPx; + invalidate(); + } + + public int getDividerPadding() { + return dividerPadding; + } + + public void setScrollOffset(int scrollOffsetPx) { + this.scrollOffset = scrollOffsetPx; + invalidate(); + } + + public int getScrollOffset() { + return scrollOffset; + } + + public void setShouldExpand(boolean shouldExpand) { + this.shouldExpand = shouldExpand; + requestLayout(); + } + + public boolean getShouldExpand() { + return shouldExpand; + } + + public boolean isTextAllCaps() { + return textAllCaps; + } + + public void setAllCaps(boolean textAllCaps) { + this.textAllCaps = textAllCaps; + } + + public void setTextSize(int textSizePx) { + this.tabTextSize = textSizePx; + updateTabStyles(); + } + + public int getTextSize() { + return tabTextSize; + } + + public void setTextColor(int textColor) { + this.tabTextColor = textColor; + updateTabStyles(); + } + + public void setTextColorResource(int resId) { + this.tabTextColor = getResources().getColor(resId); + updateTabStyles(); + } + + public int getTextColor() { + return tabTextColor; + } + + public void setTypeface(Typeface typeface, int style) { + this.tabTypeface = typeface; + this.tabTypefaceStyle = style; + updateTabStyles(); + } + + public void setTabBackground(int resId) { + this.tabBackgroundResId = resId; + } + + public int getTabBackground() { + return tabBackgroundResId; + } + + public void setTabPaddingLeftRight(int paddingPx) { + this.tabPadding = paddingPx; + updateTabStyles(); + } + + public int getTabPaddingLeftRight() { + return tabPadding; + } + + @Override + public void onRestoreInstanceState(Parcelable state) { + SavedState savedState = (SavedState) state; + super.onRestoreInstanceState(savedState.getSuperState()); + currentPosition = savedState.currentPosition; + requestLayout(); + } + + @Override + public Parcelable onSaveInstanceState() { + Parcelable superState = super.onSaveInstanceState(); + SavedState savedState = new SavedState(superState); + savedState.currentPosition = currentPosition; + return savedState; + } + + static class SavedState extends BaseSavedState { + int currentPosition; + + public SavedState(Parcelable superState) { + super(superState); + } + + private SavedState(Parcel in) { + super(in); + currentPosition = in.readInt(); + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + super.writeToParcel(dest, flags); + dest.writeInt(currentPosition); + } + + public static final Creator CREATOR = new Creator() { + @Override + public SavedState createFromParcel(Parcel in) { + return new SavedState(in); + } + + @Override + public SavedState[] newArray(int size) { + return new SavedState[size]; + } + }; + } + +} diff --git a/app/src/main/java/com/lvfq/code/tablayout/TabActivity.java b/app/src/main/java/com/lvfq/code/tablayout/TabActivity.java new file mode 100644 index 0000000..b217201 --- /dev/null +++ b/app/src/main/java/com/lvfq/code/tablayout/TabActivity.java @@ -0,0 +1,72 @@ +package com.lvfq.code.tablayout; + +import android.os.Bundle; +import android.os.Parcelable; +import android.support.annotation.Nullable; +import android.support.v4.app.Fragment; +import android.support.v4.app.FragmentActivity; +import android.support.v4.app.FragmentManager; +import android.support.v4.app.FragmentStatePagerAdapter; +import android.support.v4.view.ViewPager; + +import com.lvfq.library.utils.LvV; +import com.lvfq.myworkingtest.R; + +/** + * TabActivity + * + * @author lvfq + * @Github: https://github.com/lvfaqiang + * @Blog: http://blog.csdn.net/lv_fq + * @date 2017/9/1 下午4:22 + * @desc : + */ + +public class TabActivity extends FragmentActivity { + + private PagerSlidingTabStrip tabs; + private ViewPager viewPager; + + private String[] titles = {"热点", "推荐", "标题党", "视频", "本地农业", "科技", "政治", "农业", "其他"}; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_tab); + tabs = LvV.find(this, R.id.tabs); + viewPager = LvV.find(this, R.id.viewPager); + + TabAdapter adapter = new TabAdapter(getSupportFragmentManager()); + if (adapter != null) { + viewPager.setAdapter(adapter); + tabs.setViewPager(viewPager); + } + + } + + class TabAdapter extends FragmentStatePagerAdapter { + + public TabAdapter(FragmentManager fm) { + super(fm); + } + + @Override + public int getCount() { + return titles.length; + } + + @Override + public Fragment getItem(int pos) { + return TabFragment.getInstance(titles[pos]); + } + + @Override + public void restoreState(Parcelable arg0, ClassLoader arg1) { + } + @Override + public CharSequence getPageTitle(int position) { + return titles[position]; + } + } + +} diff --git a/app/src/main/java/com/lvfq/code/tablayout/TabFragment.java b/app/src/main/java/com/lvfq/code/tablayout/TabFragment.java new file mode 100644 index 0000000..ee4ac0a --- /dev/null +++ b/app/src/main/java/com/lvfq/code/tablayout/TabFragment.java @@ -0,0 +1,46 @@ +package com.lvfq.code.tablayout; + +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.support.v4.app.Fragment; +import android.util.Log; +import android.view.Gravity; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +/** + * TabFragment + * + * @author lvfq + * @Github: https://github.com/lvfaqiang + * @Blog: http://blog.csdn.net/lv_fq + * @date 2017/9/1 下午4:38 + * @desc : + */ + +public class TabFragment extends Fragment { + + + public static TabFragment getInstance(String string) { + TabFragment instance = new TabFragment(); + Bundle bundle = new Bundle(); + bundle.putString("title", string); + instance.setArguments(bundle); + return instance; + } + + @Nullable + @Override + public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + + String text = getArguments().getString("title"); + TextView textView = new TextView(getActivity()); + textView.setText(text); + textView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); + textView.setGravity(Gravity.CENTER); + Log.i("lfq", "title : " + text + " , hashCode : " + hashCode()); + return textView; + } +} diff --git a/app/src/main/java/com/lvfq/code/tablayout/custom/TabActivity1.java b/app/src/main/java/com/lvfq/code/tablayout/custom/TabActivity1.java new file mode 100644 index 0000000..2099db7 --- /dev/null +++ b/app/src/main/java/com/lvfq/code/tablayout/custom/TabActivity1.java @@ -0,0 +1,86 @@ +package com.lvfq.code.tablayout.custom; + +import android.os.Bundle; +import android.os.Parcelable; +import android.support.annotation.Nullable; +import android.support.design.widget.TabLayout; +import android.support.v4.app.Fragment; +import android.support.v4.app.FragmentManager; +import android.support.v4.app.FragmentStatePagerAdapter; +import android.support.v4.view.ViewPager; +import android.support.v7.app.AppCompatActivity; + +import com.lvfq.library.utils.LvV; +import com.lvfq.myworkingtest.R; +import com.lvfq.code.tablayout.TabFragment; + +/** + * TabActivity1 + * + * @author lvfq + * @Github: https://github.com/lvfaqiang + * @Blog: http://blog.csdn.net/lv_fq + * @date 2017/9/4 下午7:02 + * @desc : + */ + +public class TabActivity1 extends AppCompatActivity { + + UnAnimTabLayout tabLayout; + private ViewPager viewPager; + private TabAdapter mAdapter; + private String[] titles = {"热点", "推荐", "标题党", "视频", "本地农业", "科技", "政治", "农业", "其他"}; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_tab1); + tabLayout = LvV.find(this, R.id.tab); + viewPager = LvV.find(this, R.id.viewPager); + mAdapter = new TabAdapter(getSupportFragmentManager()); + viewPager.setAdapter(mAdapter); + tabLayout.setupWithViewPager(viewPager); + tabLayout.addOnTabSelectedListener(new TabSelectAdapter() { + @Override + public void onTabSelected(TabLayout.Tab tab) { +// TabUtils.tabSelect(tabLayout, tab); + TabUtils.tabBoldCurrent(tabLayout, tab); +// int tag = (int) tab.getTag(); +// LvToastUtil.showToast(TabActivity1.this, tag + ""); + + } + }); + tabLayout.post(new Runnable() { + @Override + public void run() { + TabUtils.setIndicator(tabLayout, 10, 10); + } + }); + } + + class TabAdapter extends FragmentStatePagerAdapter { + + public TabAdapter(FragmentManager fm) { + super(fm); + } + + @Override + public int getCount() { + return titles.length; + } + + @Override + public Fragment getItem(int pos) { + return TabFragment.getInstance(titles[pos]); + } + + @Override + public void restoreState(Parcelable arg0, ClassLoader arg1) { + } + + @Override + public CharSequence getPageTitle(int position) { + return titles[position]; + } + } +} diff --git a/app/src/main/java/com/lvfq/code/tablayout/custom/TabSelectAdapter.java b/app/src/main/java/com/lvfq/code/tablayout/custom/TabSelectAdapter.java new file mode 100755 index 0000000..76bc4e6 --- /dev/null +++ b/app/src/main/java/com/lvfq/code/tablayout/custom/TabSelectAdapter.java @@ -0,0 +1,20 @@ +package com.lvfq.code.tablayout.custom; + +import android.support.design.widget.TabLayout; + +public class TabSelectAdapter implements TabLayout.OnTabSelectedListener { + @Override + public void onTabSelected(TabLayout.Tab tab) { + + } + + @Override + public void onTabUnselected(TabLayout.Tab tab) { + + } + + @Override + public void onTabReselected(TabLayout.Tab tab) { + + } +} \ No newline at end of file diff --git a/app/src/main/java/com/lvfq/code/tablayout/custom/TabUtils.java b/app/src/main/java/com/lvfq/code/tablayout/custom/TabUtils.java new file mode 100755 index 0000000..081ba9e --- /dev/null +++ b/app/src/main/java/com/lvfq/code/tablayout/custom/TabUtils.java @@ -0,0 +1,174 @@ +package com.lvfq.code.tablayout.custom; + +import android.content.res.Resources; +import android.graphics.Typeface; +import android.support.design.widget.TabLayout; +import android.util.TypedValue; +import android.view.View; +import android.view.ViewGroup; +import android.widget.LinearLayout; +import android.widget.TextView; + +import java.lang.reflect.Field; + +/** + * 修改Tablayout tab的字体和shadow + * created by qibin + */ +public class TabUtils { + + public static void boldTab(TabLayout.Tab tab) { + setTabStyle(tab, Typeface.DEFAULT_BOLD, 0, 0, 0, 0); + } + + /** + * 选中某条, 改变样式 + * + * @param tabLayout + * @param currentTab + */ + public static void tabSelect(TabLayout tabLayout, TabLayout.Tab currentTab) { + int tabCount = tabLayout.getTabCount(); + TabLayout.Tab tab; + for (int i = 0; i < tabCount; i++) { + tab = tabLayout.getTabAt(i); + setTabStyle(tab, Typeface.DEFAULT, 0, 0, 0, 0x00000000); + } + + setTabStyle(currentTab, Typeface.DEFAULT_BOLD, 1, 2, 2, 0x55000000); + } + + public static void tabSelectAt(TabLayout tabLayout, TabLayout.Tab currentTab, int position) { + int tabCount = tabLayout.getTabCount(); + TabLayout.Tab tab; + for (int i = 0; i < tabCount; i++) { + tab = tabLayout.getTabAt(i); + if (i != position) { + setTabStyle(tab, Typeface.DEFAULT, 0, 0, 0, 0x00000000); + } else { + setTabStyle(currentTab, Typeface.DEFAULT_BOLD, 1, 2, 2, 0x55000000); + } + } + } + + /** + * 通过反射去设置样式 + * + * @param tab + * @param tf + * @param radius + * @param dx + * @param dy + * @param color + */ + public static void setTabStyle(TabLayout.Tab tab, Typeface tf, int radius, float dx, float dy, int color) { + TextView tv = getTextView(tab); + if (tv == null) { + return; + } + //TODO 暂时不做阴影效果 +// tv.setTextSize(18); + tv.setTypeface(tf); + tv.setShadowLayer(radius, dx, dy, color); + } + + private static TextView getTextView(TabLayout.Tab tab) { + try { + Field mView = tab.getClass().getDeclaredField("mView"); + mView.setAccessible(true); + Object mViewObj = mView.get(tab); + Field mTextView = mViewObj.getClass().getDeclaredField("mTextView"); + mTextView.setAccessible(true); + return (TextView) mTextView.get(mViewObj); + } catch (Exception e) { + + } + + return null; + } + + /** + * 通过反射去设置下划线样式bufen + * + * @param tab + * @param leftDip + * @param rightDip + */ + public static void setIndicator(TabLayout tab, int leftDip, int rightDip) { + try { + Field tabStrip = TabLayout.class.getDeclaredField("mTabStrip"); + tabStrip.setAccessible(true); + LinearLayout llTab = (LinearLayout) tabStrip.get(tab); + int left = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, leftDip, Resources.getSystem().getDisplayMetrics()); + int right = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, rightDip, Resources.getSystem().getDisplayMetrics()); + + for (int i = 0; i < llTab.getChildCount(); i++) { + View child = llTab.getChildAt(i); + child.setPadding(0, 0, 0, 0); + LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.MATCH_PARENT, 1); + params.leftMargin = left; + params.rightMargin = right; + child.setLayoutParams(params); + child.invalidate(); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + /** + * 加粗current + * + * @param tabLayout + * @param currentTab + */ + public static void tabBoldCurrent(TabLayout tabLayout, TabLayout.Tab currentTab) { + int tabCount = tabLayout.getTabCount(); + TabLayout.Tab tab; + for (int i = 0; i < tabCount; i++) { + tab = tabLayout.getTabAt(i); + TextView tv = getTextView(tab); + if (tv == null) { + continue; + } + tv.setTypeface(Typeface.DEFAULT); + } + + TextView tv = getTextView(currentTab); + if (tv == null) { + return; + } + tv.setTypeface(Typeface.DEFAULT_BOLD); + } + + + public static void enableTabs(TabLayout tabLayout, Boolean enable) { + ViewGroup viewGroup = getTabViewGroup(tabLayout); + if (viewGroup != null) + for (int childIndex = 0; childIndex < viewGroup.getChildCount(); childIndex++) { + View tabView = viewGroup.getChildAt(childIndex); + if (tabView != null) + tabView.setEnabled(enable); + } + } + + public static View getTabView(TabLayout tabLayout, int position) { + View tabView = null; + ViewGroup viewGroup = getTabViewGroup(tabLayout); + if (viewGroup != null && viewGroup.getChildCount() > position) + tabView = viewGroup.getChildAt(position); + + return tabView; + } + + private static ViewGroup getTabViewGroup(TabLayout tabLayout) { + ViewGroup viewGroup = null; + + if (tabLayout != null && tabLayout.getChildCount() > 0) { + View view = tabLayout.getChildAt(0); + if (view != null && view instanceof ViewGroup) + viewGroup = (ViewGroup) view; + } + return viewGroup; + } +} diff --git a/app/src/main/java/com/lvfq/code/tablayout/custom/UnAnimTabLayout.java b/app/src/main/java/com/lvfq/code/tablayout/custom/UnAnimTabLayout.java new file mode 100755 index 0000000..bdbcb6a --- /dev/null +++ b/app/src/main/java/com/lvfq/code/tablayout/custom/UnAnimTabLayout.java @@ -0,0 +1,153 @@ +package com.lvfq.code.tablayout.custom; + +import android.content.Context; +import android.support.annotation.NonNull; +import android.support.design.widget.TabLayout; +import android.util.AttributeSet; + +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +/** + * 重写TabLayout关于mSelectedTab的方法,解决动画卡断问题
+ * 利用反射将mSelectedTab设置为null, 这样可以做到禁用动画
+ * 利用静态代理重写tabSelect事件,解决mSelectedTab置为null后重复点击某一item会多次回调的问题 + */ +public class UnAnimTabLayout extends TabLayout { + + private Tab mCurrentSelectedTab; + + public UnAnimTabLayout(Context context) { + super(context); + } + + public UnAnimTabLayout(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public UnAnimTabLayout(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + } + + @Override + public void removeAllTabs() { + mCurrentSelectedTab = null; + super.removeAllTabs(); + } + + public int getSelectedTabPosition() { + return mCurrentSelectedTab != null ? mCurrentSelectedTab.getPosition() : -1; + } + + /** + * 重写父类的remove逻辑
+ * 具体实现方式: 1. 在调用真正remove之前将mSelectedTab设置为自己保存的mCurrentSelectedTab
+ * 2. 调用父类的removeTabAt()方法
+ * 3. 将父类的mSelectedTab置为null + * @param position + */ + public void removeTabAt(int position) { + Field mSelectedTab = null; + try { + mSelectedTab = getClass().getSuperclass().getDeclaredField("mSelectedTab"); + mSelectedTab.setAccessible(true); + mSelectedTab.set(this, mCurrentSelectedTab); + } catch (NoSuchFieldException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + + super.removeTabAt(position); + + if (mSelectedTab != null && mSelectedTab.isAccessible()) { + try { + mSelectedTab.set(this, null); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + } + } + + public void addOnTabSelectedListener(@NonNull OnTabSelectedListener listener) { + super.addOnTabSelectedListener(new TabSelectedListenerProxy(listener)); + } + + // proxy for tab event listener + class TabSelectedListenerProxy implements OnTabSelectedListener { + + private OnTabSelectedListener mListener; + TabSelectedListenerProxy(OnTabSelectedListener li) { + mListener = li; + } + + @Override + public void onTabSelected(Tab tab) { + final Tab currentTab = mCurrentSelectedTab; + + try { + Field mSelectedTab = UnAnimTabLayout.class.getSuperclass().getDeclaredField("mSelectedTab"); + mSelectedTab.setAccessible(true); + mSelectedTab.set(UnAnimTabLayout.this, null); + } catch (NoSuchFieldException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + + if (currentTab == tab) { + if (currentTab != null) { + try { + Method dispatchTabUnselected = UnAnimTabLayout.class.getSuperclass() + .getDeclaredMethod("dispatchTabReselected", Tab.class); + dispatchTabUnselected.setAccessible(true); + dispatchTabUnselected.invoke(UnAnimTabLayout.this, tab); + + final int newPosition = tab != null ? tab.getPosition() : Tab.INVALID_POSITION; + Method setScrollPosition = UnAnimTabLayout.class.getSuperclass() + .getDeclaredMethod("setScrollPosition", int.class, float.class, boolean.class); + setScrollPosition.setAccessible(true); + setScrollPosition.invoke(UnAnimTabLayout.this, newPosition, 0f, true); + } catch (NoSuchMethodException e) { + e.printStackTrace(); + } catch (InvocationTargetException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + } + } + + if (currentTab != null && currentTab == tab) { return;} + + if (currentTab != null) { + try { + Method dispatchTabUnselected = UnAnimTabLayout.class.getSuperclass() + .getDeclaredMethod("dispatchTabUnselected", Tab.class); + dispatchTabUnselected.setAccessible(true); + dispatchTabUnselected.invoke(UnAnimTabLayout.this, currentTab); + } catch (NoSuchMethodException e) { + e.printStackTrace(); + } catch (InvocationTargetException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + } + + mCurrentSelectedTab = tab; + mListener.onTabSelected(tab); + } + + @Override + public void onTabUnselected(Tab tab) { + // 永远不会执行到~ + } + + @Override + public void onTabReselected(Tab tab) { + // 永远不会执行到~ + } + } +} diff --git a/app/src/main/java/com/lvfq/code/util/FileUtils.java b/app/src/main/java/com/lvfq/code/util/FileUtils.java new file mode 100644 index 0000000..4ba8e28 --- /dev/null +++ b/app/src/main/java/com/lvfq/code/util/FileUtils.java @@ -0,0 +1,381 @@ +package com.lvfq.code.util; + +import android.content.ContentResolver; +import android.content.Context; +import android.database.Cursor; +import android.graphics.Bitmap; +import android.graphics.Bitmap.CompressFormat; +import android.graphics.Bitmap.Config; +import android.graphics.BitmapFactory; +import android.graphics.Matrix; +import android.media.ExifInterface; +import android.net.Uri; +import android.os.Environment; +import android.provider.MediaStore; +import android.text.TextUtils; +import android.util.Log; + +import java.io.BufferedOutputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.nio.channels.FileChannel; +import java.util.Date; + +public class FileUtils { + + public static String mImageFileCachePath() { + String s = Environment.getExternalStorageDirectory() + File.separator + "Android" + File.separator + + "_test" + File.separator; + File file = new File(s); + if (!file.exists()) { + file.mkdirs(); + } + return s; + } + + /** + * 把图片压缩到200K + * + * @param oldpath + * 压缩前的图片路径 + * @param newPath + * 压缩后的图片路径 + * @return + */ + /** + * 把图片压缩到200K + * + * @param oldpath 压缩前的图片路径 + * @param newPath 压缩后的图片路径 + * @return + */ + public static File compressFile(String oldpath, String newPath) { + Bitmap compressBitmap = FileUtils.decodeFile(oldpath); + Bitmap newBitmap = ratingImage(oldpath, compressBitmap); + ByteArrayOutputStream os = new ByteArrayOutputStream(); + newBitmap.compress(CompressFormat.PNG, 100, os); + byte[] bytes = os.toByteArray(); + + File file = null; + try { + file = FileUtils.getFileFromBytes(bytes, newPath); + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (newBitmap != null) { + if (!newBitmap.isRecycled()) { + newBitmap.recycle(); + } + newBitmap = null; + } + if (compressBitmap != null) { + if (!compressBitmap.isRecycled()) { + compressBitmap.recycle(); + } + compressBitmap = null; + } + } + return file; + } + + public static Bitmap ratingImage(String filePath, Bitmap bitmap) { + int degree = readPictureDegree(filePath); + return rotaingImageView(degree, bitmap); + } + + /** + * 旋转图片 + * + * @param angle + * @param bitmap + * @return Bitmap + */ + public static Bitmap rotaingImageView(int angle, Bitmap bitmap) { + // 旋转图片 动作 + Matrix matrix = new Matrix(); + matrix.postRotate(angle); + System.out.println("angle2=" + angle); + // 创建新的图片 + Bitmap resizedBitmap = Bitmap.createBitmap(bitmap, 0, 0, + bitmap.getWidth(), bitmap.getHeight(), matrix, true); + return resizedBitmap; + } + + /** + * 读取图片属性:旋转的角度 + * + * @param path 图片绝对路径 + * @return degree旋转的角度 + */ + public static int readPictureDegree(String path) { + int degree = 0; + try { + ExifInterface exifInterface = new ExifInterface(path); + int orientation = exifInterface.getAttributeInt( + ExifInterface.TAG_ORIENTATION, + ExifInterface.ORIENTATION_NORMAL); + switch (orientation) { + case ExifInterface.ORIENTATION_ROTATE_90: + degree = 90; + break; + case ExifInterface.ORIENTATION_ROTATE_180: + degree = 180; + break; + case ExifInterface.ORIENTATION_ROTATE_270: + degree = 270; + break; + } + } catch (IOException e) { + e.printStackTrace(); + } + return degree; + } + + /** + * 把字节数组保存为一个文件 + * + * @param b + * @param outputFile + * @return + */ + public static File getFileFromBytes(byte[] b, String outputFile) { + File ret = null; + BufferedOutputStream stream = null; + try { + ret = new File(outputFile); + FileOutputStream fstream = new FileOutputStream(ret); + stream = new BufferedOutputStream(fstream); + stream.write(b); + } catch (Exception e) { + // log.error("helper:get file from byte process error!"); + e.printStackTrace(); + } finally { + if (stream != null) { + try { + stream.close(); + } catch (IOException e) { + // log.error("helper:get file from byte process error!"); + e.printStackTrace(); + } + } + } + return ret; + } + + /** + * 图片压缩 + * + * @param fPath + * @return + */ + public static Bitmap decodeFile(String fPath) { + BitmapFactory.Options opts = new BitmapFactory.Options(); + opts.inJustDecodeBounds = true; + opts.inDither = false; // Disable Dithering mode + opts.inPurgeable = true; // Tell to gc that whether it needs free + opts.inInputShareable = true; // Which kind of reference will be used to + BitmapFactory.decodeFile(fPath, opts); + final int REQUIRED_SIZE = 800; + int scale = 1; + if (opts.outHeight > REQUIRED_SIZE || opts.outWidth > REQUIRED_SIZE) { + final int heightRatio = Math.round((float) opts.outHeight + / (float) REQUIRED_SIZE); + final int widthRatio = Math.round((float) opts.outWidth + / (float) REQUIRED_SIZE); + scale = heightRatio < widthRatio ? heightRatio : widthRatio;// + } + opts.inJustDecodeBounds = false; + opts.inSampleSize = scale; + Bitmap bm = BitmapFactory.decodeFile(fPath, opts).copy( + Config.ARGB_8888, false); + return bm; + } + + /** + * 创建目录 + * + * @param path + */ + public static void setMkdir(String path) { + File file = new File(path); + if (!file.exists()) { + file.mkdirs(); + Log.e("file", "目录不存在 创建目录 "); + } else { + Log.e("file", "目录存在"); + } + } + + /** + * 获取目录名称 + * + * @param url + * @return FileName + */ + public static String getFileName(String url) { + int lastIndexStart = url.lastIndexOf("/"); + if (lastIndexStart != -1) { + return url.substring(lastIndexStart + 1, url.length()); + } else { + return null; + } + } + + /** + * 删除该目录下的文件 + * + * @param path + */ + public static void delFile(String path) { + if (!TextUtils.isEmpty(path)) { + File file = new File(path); + if (file.exists()) { + + if (file.isDirectory()) { + if (file.listFiles() == null || file.listFiles().length <= 0) { + file.delete(); + return; + } + for (File f : file.listFiles()) { + delFile(f.getAbsolutePath()); + } + } + file.delete(); + } + } + } + + + /** + * 图像压缩(质量,大小), + * + * @param fileUri + * @return + */ + public static File scal(Uri fileUri) { + String path = fileUri.getPath(); + File outputFile = new File(path); + long fileSize = outputFile.length(); + final long fileMaxSize = 200 * 1024; + if (fileSize >= fileMaxSize) { + BitmapFactory.Options options = new BitmapFactory.Options(); + options.inJustDecodeBounds = true; + BitmapFactory.decodeFile(path, options); + int height = options.outHeight; + int width = options.outWidth; + + double scale = Math.sqrt((float) fileSize / fileMaxSize); + options.outHeight = (int) (height / scale); + options.outWidth = (int) (width / scale); + options.inSampleSize = (int) (scale + 0.8); + options.inJustDecodeBounds = false; + + Bitmap bitmap = BitmapFactory.decodeFile(path, options); + String myPahth = createImageFile().getPath(); + outputFile = new File(myPahth); + FileOutputStream fos = null; + try { + fos = new FileOutputStream(outputFile); + bitmap.compress(CompressFormat.JPEG, 100, fos); + fos.close(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + if (!bitmap.isRecycled()) { + bitmap.recycle(); + } else { + File tempFile = outputFile; + outputFile = new File(createImageFile().getPath()); + copyFileUsingFileChannels(tempFile, outputFile); + } + + } + return outputFile; + + } + + private static String getOutputImageUri() { + return new Date().getTime() + ".png"; + } + + public static Uri createImageFile() { + return Uri.parse(mImageFileCachePath() + getOutputImageUri()); + // Create an image file name +// String imageFileName = System.currentTimeMillis() + ""; +// File storageDir = Environment.getExternalStoragePublicDirectory( +// Environment.DIRECTORY_PICTURES); +// File image = null; +// try { +// image = File.createTempFile(imageFileName, ".jpg", storageDir); +//// image = File.createTempFile( +//// imageFileName, /* prefix */ +//// .jpg, /* suffix */ +//// storageDir /* directory */ +//// ); +// } catch (IOException e) { +// // TODO Auto-generated catch block +// e.printStackTrace(); +// } +// +// // Save a file: path for use with ACTION_VIEW intents +// return Uri.fromFile(image); + } + + public static void copyFileUsingFileChannels(File source, File dest) { + FileChannel inputChannel = null; + FileChannel outputChannel = null; + try { + try { + inputChannel = new FileInputStream(source).getChannel(); + outputChannel = new FileOutputStream(dest).getChannel(); + outputChannel.transferFrom(inputChannel, 0, inputChannel.size()); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } finally { + try { + inputChannel.close(); + outputChannel.close(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + } + + /** + * 绝对路径转成相对路径 + * + * @param context + * @param uri + * @return + */ + + public static String getRealFilePath(final Context context, final Uri uri) { + if (null == uri) return null; + final String scheme = uri.getScheme(); + String data = null; + if (scheme == null) + data = uri.getPath(); + else if (ContentResolver.SCHEME_FILE.equals(scheme)) { + data = uri.getPath(); + } else if (ContentResolver.SCHEME_CONTENT.equals(scheme)) { + Cursor cursor = context.getContentResolver().query(uri, new String[]{MediaStore.Images.ImageColumns.DATA}, null, null, null); + if (null != cursor) { + if (cursor.moveToFirst()) { + int index = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA); + if (index > -1) { + data = cursor.getString(index); + } + } + cursor.close(); + } + } + return data; + } +} \ No newline at end of file diff --git a/app/src/main/java/com/lvfq/code/util/Glide4_ImageLoadUtil.java b/app/src/main/java/com/lvfq/code/util/Glide4_ImageLoadUtil.java new file mode 100644 index 0000000..0619f9f --- /dev/null +++ b/app/src/main/java/com/lvfq/code/util/Glide4_ImageLoadUtil.java @@ -0,0 +1,225 @@ +package com.lvfq.code.util; + +import android.content.Context; +import android.widget.ImageView; + +import com.bumptech.glide.load.engine.DiskCacheStrategy; +import com.bumptech.glide.load.resource.bitmap.RoundedCorners; +import com.bumptech.glide.request.RequestOptions; + +/** + * ImageLoadUtil + * + * @author lvfq + * @date 2017/7/19 下午9:30 + * @mainFunction : + */ + +public class Glide4_ImageLoadUtil { + + private static final int RADIUS = 4; + + /** + * 初始化 Options 参数 + * + * @param resourceId + * @param errorResourceId + * @return + */ + private static RequestOptions initOptions(int resourceId, int errorResourceId) { + RequestOptions options = new RequestOptions() + .centerCrop() + .placeholder(resourceId) + .error(errorResourceId == 0 ? resourceId : errorResourceId) + .diskCacheStrategy(DiskCacheStrategy.ALL); + return options; + } + + /** + * 调用 Glide 加载 + * + * @param context + * @param options + * @param url + * @param imageView + */ + private static void glideApply(Context context, RequestOptions options, Object url, ImageView imageView) { + GlideApp.with(context) + .applyDefaultRequestOptions(options) + .load(url) + .into(imageView); + } + + /************* 默认加载方式 ****************/ + /** + * 默认加载图片 + * + * @param context + * @param url + * @param resourceId + * @param imageView + */ + public static void loadImg(Context context, Object url, int resourceId, ImageView imageView) { + loadImg(context, url, resourceId, 0, imageView); + } + + /** + * 默认加载图片 + * + * @param context + * @param url + * @param resourceId + * @param imageView + */ + public static void loadImg(Context context, Object url, int resourceId, int errorResourceId, ImageView imageView) { + RequestOptions options = initOptions(resourceId, errorResourceId); + glideApply(context, options, url, imageView); + } + + /************* 加载圆形图 ****************/ + /** + * 加载圆形图片 + * + * @param context + * @param url + * @param resourceId + * @param imageView + */ + public static void loadCircleImg(Context context, Object url, int resourceId, ImageView imageView) { + loadCircleImg(context, url, resourceId, 0, imageView); + } + + /** + * 加载圆形图片 + * + * @param context + * @param url + * @param resourceId + * @param errorResourceId 给 0 默认显示 resouceId + * @param imageView + */ + public static void loadCircleImg(Context context, Object url, int resourceId, int errorResourceId, ImageView imageView) { + RequestOptions options = initOptions(resourceId, errorResourceId) + .circleCrop(); + + glideApply(context, options, url, imageView); + } + + /************* 加载圆角图片 方式 1 ****************/ + + + /** + * 加载圆角 + * + * @param context + * @param url + * @param resourceId 占位图 + * @param errorResourceId 加载失败图 + * @param imageView + * @param dp + */ + public static void loadRoundImg(Context context, Object url, int resourceId, int errorResourceId, ImageView imageView, int dp) { + RequestOptions options = initOptions(resourceId, errorResourceId) + .transform(new RoundedCorners(dp)); + + glideApply(context, options, url, imageView); + } + + /** + * 加载圆角 + * + * @param context + * @param url + * @param resourceId 占位图(也是加载失败图) + * @param imageView + * @param dp + */ + public static void loadRoundImg(Context context, Object url, int resourceId, ImageView imageView, int dp) { + RequestOptions options = initOptions(resourceId, 0) + .transform(new RoundedCorners(dp)); + + glideApply(context, options, url, imageView); + } + + /** + * 加载圆角,默认圆角值为 4 + * + * @param context + * @param url + * @param resourceId 占位图(也是加载失败图) + * @param imageView + */ + public static void loadRoundImg(Context context, Object url, int resourceId, ImageView imageView) { + RequestOptions options = initOptions(resourceId, 0); +// .transform(new RoundedCorners(RADIUS)).transform(new CenterCrop()); + +// Glide.with(context) +// .applyDefaultRequestOptions(options) +// .load(url) +// .into(imageView); + glideApply(context, options, url, imageView); + } + + + /************* 加载圆角图片 方式 2 ****************/ + + /** + * 加载圆角图片 + * + * @param context + * @param url + * @param resourceId 占位图 + * @param errorResourceId 加载失败图 + * @param imageView + * @param dp + * @param type + */ +// public static void loadRoundImgCorner(Context context, Object url, int resourceId, int errorResourceId, ImageView imageView, int dp, RoundedCornersTransformation.CornerType type) { +// RequestOptions options = initOptions(resourceId, errorResourceId) +// .transform(new RoundedCornersTransformation(context, dp, 0, type)); +// +// glideApply(context, options, url, imageView); +// } + + /** + * 加载圆角图片 默认圆角值为 4 + * + * @param context + * @param url + * @param resourceId 占位图 + * @param errorResourceId 加载失败图 + * @param imageView + */ +// public static void loadRoundImgCorner(Context context, Object url, int resourceId, int errorResourceId, ImageView imageView) { +// loadRoundImgCorner(context, url, resourceId, errorResourceId, imageView, RADIUS, RoundedCornersTransformation.CornerType.ALL); +// } + + /** + * 加载圆角图片 + * + * @param context + * @param url + * @param resourceId 占位图(也是加载失败图) + * @param imageView + * @param dp + */ +// public static void loadRoundImgCorner(Context context, Object url, int resourceId, ImageView imageView, int dp) { +// loadRoundImgCorner(context, url, resourceId, 0, imageView, dp, RoundedCornersTransformation.CornerType.ALL); +// } + + /** + * 加载圆角图片 + * + * @param context + * @param url + * @param resourceId 占位图 + * @param errorResourceId 加载失败图 + * @param imageView + * @param dp + */ +// public static void loadRoundImgCorner(Context context, Object url, int resourceId, int errorResourceId, ImageView imageView, int dp) { +// loadRoundImgCorner(context, url, resourceId, errorResourceId, imageView, dp, RoundedCornersTransformation.CornerType.ALL); +// } + + +} diff --git a/app/src/main/java/com/lvfq/code/util/ImageUtils.java b/app/src/main/java/com/lvfq/code/util/ImageUtils.java new file mode 100644 index 0000000..f66e1d1 --- /dev/null +++ b/app/src/main/java/com/lvfq/code/util/ImageUtils.java @@ -0,0 +1,43 @@ +package com.lvfq.code.util; + +import android.graphics.Bitmap; +import android.util.Log; + +import java.io.FileOutputStream; +import java.io.IOException; + +/** + * ImageUtils + * + * @author lvfq + * @date 2017/4/19 下午2:35 + * @mainFunction : + */ + +public class ImageUtils { + /** + * 把图片村保存在相应的文件当中 + * + * @param pBitmap + * @param fileName + */ + public static void saveFile(Bitmap pBitmap, String fileName) { + FileOutputStream fos = null; + try { + fos = new FileOutputStream(fileName); + pBitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos); + fos.flush(); + Log.i("jiangqq", "保存图片到sdcard卡成功."); + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (fos != null) { + try { + fos.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + } +} diff --git a/app/src/main/java/com/lvfq/code/util/MyAppGlideModule.java b/app/src/main/java/com/lvfq/code/util/MyAppGlideModule.java new file mode 100644 index 0000000..ca63b55 --- /dev/null +++ b/app/src/main/java/com/lvfq/code/util/MyAppGlideModule.java @@ -0,0 +1,17 @@ +package com.lvfq.code.util; + +import com.bumptech.glide.annotation.GlideModule; +import com.bumptech.glide.module.AppGlideModule; + +/** + * MyAppGlideModule + * + * @author lvfq + * @Github: https://github.com/lvfaqiang + * @Blog: http://blog.csdn.net/lv_fq + * @date 2017/9/3 下午1:26 + * @desc : + */ + +@GlideModule +public final class MyAppGlideModule extends AppGlideModule {} \ No newline at end of file diff --git a/app/src/main/res/drawable/shape_tab_green.xml b/app/src/main/res/drawable/shape_tab_green.xml new file mode 100755 index 0000000..79e38ee --- /dev/null +++ b/app/src/main/res/drawable/shape_tab_green.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/tab_selector_green.xml b/app/src/main/res/drawable/tab_selector_green.xml new file mode 100755 index 0000000..4c19a28 --- /dev/null +++ b/app/src/main/res/drawable/tab_selector_green.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_comments.xml b/app/src/main/res/layout/activity_comments.xml new file mode 100644 index 0000000..b535665 --- /dev/null +++ b/app/src/main/res/layout/activity_comments.xml @@ -0,0 +1,20 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_dynamic_image.xml b/app/src/main/res/layout/activity_dynamic_image.xml new file mode 100644 index 0000000..9a82664 --- /dev/null +++ b/app/src/main/res/layout/activity_dynamic_image.xml @@ -0,0 +1,18 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_glide.xml b/app/src/main/res/layout/activity_glide.xml new file mode 100644 index 0000000..f5b596d --- /dev/null +++ b/app/src/main/res/layout/activity_glide.xml @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_img_water_mark.xml b/app/src/main/res/layout/activity_img_water_mark.xml new file mode 100644 index 0000000..f622e34 --- /dev/null +++ b/app/src/main/res/layout/activity_img_water_mark.xml @@ -0,0 +1,22 @@ + + + +