├── .gitignore ├── .idea ├── caches │ └── build_file_checksums.ser ├── codeStyles │ └── Project.xml ├── encodings.xml ├── gradle.xml ├── misc.xml └── vcs.xml ├── README.md ├── app ├── .gitignore ├── build.gradle ├── libs │ └── jbox2d-library-2.3.1-SNAPSHOT.jar ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── lemon │ │ └── customview │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── assets │ │ └── fonts │ │ │ ├── AmaticaSC-Regular.ttf │ │ │ ├── Lato-Black.ttf │ │ │ ├── Mirza-Regular.ttf │ │ │ └── PoiretOne-Regular.ttf │ ├── java │ │ └── com │ │ │ └── lemon │ │ │ └── customview │ │ │ ├── DepthMapView.java │ │ │ ├── activity │ │ │ ├── MainActivity.kt │ │ │ ├── WebViewActivity.java │ │ │ ├── material │ │ │ │ ├── MaterialActivity.java │ │ │ │ ├── TextInputLayoutActivity.java │ │ │ │ └── ZhiFuBaoActivity.java │ │ │ └── view │ │ │ │ ├── DepthMapViewActivity.java │ │ │ │ ├── ExpandableTextViewActivity.java │ │ │ │ ├── KeyboardActivity.java │ │ │ │ ├── LinePathActivity.java │ │ │ │ ├── MarqueeViewActivity.java │ │ │ │ ├── MeiHeartViewActivity.java │ │ │ │ ├── Roll3DViewActivity.java │ │ │ │ ├── RoundImageViewActivity.java │ │ │ │ ├── ShapeImageViewActivity.java │ │ │ │ ├── ShowInRecyclerViewActivity.java │ │ │ │ ├── TextPathViewActivity.java │ │ │ │ ├── TheoryActivity.java │ │ │ │ ├── TimeLineMarkerViewActivity.java │ │ │ │ ├── VerifyCodeViewActivity.java │ │ │ │ ├── imageview │ │ │ │ └── ImageViewActivity.kt │ │ │ │ └── textview │ │ │ │ ├── AlphaTextViewActivity.kt │ │ │ │ ├── FoldTextViewActivity.java │ │ │ │ ├── HTextViewActivity.kt │ │ │ │ ├── NumberTextViewActivity.kt │ │ │ │ ├── SlantedTextViewActivity.java │ │ │ │ └── TextViewActivity.kt │ │ │ ├── bean │ │ │ ├── DepthData.java │ │ │ └── DepthDataBean.java │ │ │ ├── image │ │ │ └── ImageCache.java │ │ │ ├── listener │ │ │ ├── MyLinkMovementMethod.java │ │ │ └── TextWatcherListener.java │ │ │ ├── model │ │ │ ├── CharacterDiffResult.java │ │ │ ├── ViewModel.java │ │ │ └── ViewModelWithFlag.java │ │ │ ├── other │ │ │ └── KeyboardDecoration.java │ │ │ ├── utils │ │ │ ├── ImageUtils.java │ │ │ ├── ReflectUtil.java │ │ │ ├── ResourceUtil.java │ │ │ └── Util.java │ │ │ └── widget │ │ │ ├── ExpandableTextView │ │ │ ├── ExpandableTextView.java │ │ │ ├── FormatData.java │ │ │ ├── LinkType.java │ │ │ └── StatusType.java │ │ │ ├── Heart │ │ │ ├── Heart.java │ │ │ ├── HeartType.java │ │ │ ├── HeartView.java │ │ │ ├── MeiHeartView.java │ │ │ ├── NewHeart.java │ │ │ └── SimpleSurfaceView.java │ │ │ ├── KeyboardLayout.java │ │ │ ├── KeyboardView.java │ │ │ ├── LinePathView.java │ │ │ ├── LoveView.java │ │ │ ├── MarqueeView.java │ │ │ ├── PasswordView.java │ │ │ ├── Roll3DLinearLayout.java │ │ │ ├── Roll3DView.java │ │ │ ├── SelectorAttrs.java │ │ │ ├── SlantedTextView.java │ │ │ ├── TimeLineMarkerView.java │ │ │ ├── VerifyCodeView.java │ │ │ ├── htextview │ │ │ ├── HTextView.java │ │ │ └── animatetext │ │ │ │ ├── AnvilText.java │ │ │ │ ├── BurnText.java │ │ │ │ ├── EvaporateText.java │ │ │ │ ├── FallText.java │ │ │ │ ├── HText.java │ │ │ │ ├── IHText.java │ │ │ │ ├── LineText.java │ │ │ │ ├── PixelateText.java │ │ │ │ ├── RainBowText.java │ │ │ │ ├── ScaleText.java │ │ │ │ ├── SparkleText.java │ │ │ │ └── TyperText.java │ │ │ ├── imageview │ │ │ ├── RoundImageView.java │ │ │ └── ShapeImageView.java │ │ │ ├── new_path │ │ │ ├── BezierPraiseAnimator.java │ │ │ ├── BezierPraiseView.java │ │ │ ├── FanView.java │ │ │ ├── MoBike.java │ │ │ ├── MoBikeView.java │ │ │ ├── PraiseEvaluator.java │ │ │ └── TextPathView.java │ │ │ └── textview │ │ │ ├── AlphaTextView.java │ │ │ ├── FoldTextView.java │ │ │ ├── NumberTextView.java │ │ │ └── SpannableFoldTextView.java │ └── res │ │ ├── drawable │ │ ├── cell_edit_bg.xml │ │ ├── cell_edit_bg1.xml │ │ ├── common_key_selector.xml │ │ ├── delete_key_selector.xml │ │ ├── fire.png │ │ ├── fire_smoke.xml │ │ ├── fragment.png │ │ ├── heart_default.png │ │ ├── img1.png │ │ ├── img2.png │ │ ├── img3.png │ │ ├── img4.png │ │ ├── img5.png │ │ ├── mei_ic_praise_1.png │ │ ├── mei_ic_praise_10.png │ │ ├── mei_ic_praise_11.png │ │ ├── mei_ic_praise_12.png │ │ ├── mei_ic_praise_13.png │ │ ├── mei_ic_praise_14.png │ │ ├── mei_ic_praise_2.png │ │ ├── mei_ic_praise_3.png │ │ ├── mei_ic_praise_4.png │ │ ├── mei_ic_praise_5.png │ │ ├── mei_ic_praise_6.png │ │ ├── mei_ic_praise_7.png │ │ ├── mei_ic_praise_8.png │ │ ├── mei_ic_praise_9.png │ │ ├── shape_search.xml │ │ ├── smoke.png │ │ ├── sparkle.png │ │ ├── ss_heart1.png │ │ ├── ss_heart2.png │ │ ├── ss_heart3.png │ │ ├── ss_heart4.png │ │ ├── ss_heart5.png │ │ ├── timeline_bg_blue.xml │ │ ├── wenzi0000.png │ │ ├── wenzi0001.png │ │ ├── wenzi0002.png │ │ ├── wenzi0003.png │ │ ├── wenzi0004.png │ │ ├── wenzi0005.png │ │ ├── wenzi0006.png │ │ ├── wenzi0007.png │ │ ├── wenzi0008.png │ │ ├── wenzi0009.png │ │ ├── wenzi0010.png │ │ ├── wenzi0011.png │ │ ├── wenzi0012.png │ │ ├── wenzi0013.png │ │ ├── wenzi0014.png │ │ ├── wenzi0015.png │ │ ├── wenzi0016.png │ │ ├── wenzi0017.png │ │ ├── wenzi0018.png │ │ ├── wenzi0019.png │ │ ├── wenzi0020.png │ │ ├── wenzi0021.png │ │ ├── wenzi0022.png │ │ ├── wenzi0023.png │ │ ├── wenzi0024.png │ │ ├── wenzi0025.png │ │ ├── wenzi0026.png │ │ ├── wenzi0027.png │ │ ├── wenzi0028.png │ │ ├── wenzi0029.png │ │ ├── wenzi0030.png │ │ ├── wenzi0031.png │ │ ├── wenzi0032.png │ │ ├── wenzi0033.png │ │ ├── wenzi0034.png │ │ ├── wenzi0035.png │ │ ├── wenzi0036.png │ │ ├── wenzi0037.png │ │ ├── wenzi0038.png │ │ ├── wenzi0039.png │ │ ├── wenzi0040.png │ │ ├── wenzi0041.png │ │ ├── wenzi0042.png │ │ ├── wenzi0043.png │ │ ├── wenzi0044.png │ │ ├── wenzi0045.png │ │ ├── wenzi0046.png │ │ ├── wenzi0047.png │ │ ├── wenzi0048.png │ │ ├── wenzi0049.png │ │ ├── wenzi0050.png │ │ └── wenzi0051.png │ │ ├── layout │ │ ├── activity_alpha_text_view.xml │ │ ├── activity_depthmap_view.xml │ │ ├── activity_expandable_textview.xml │ │ ├── activity_fold_textview.xml │ │ ├── activity_h_text_view.xml │ │ ├── activity_image_view.xml │ │ ├── activity_keyboard.xml │ │ ├── activity_line_path.xml │ │ ├── activity_main.xml │ │ ├── activity_marquee_view.xml │ │ ├── activity_material.xml │ │ ├── activity_mei_heart_view.xml │ │ ├── activity_number_text_view.xml │ │ ├── activity_roll_3d_view.xml │ │ ├── activity_round_image_view.xml │ │ ├── activity_shape_image_view.xml │ │ ├── activity_show_in_recycler_view.xml │ │ ├── activity_slanted_textview.xml │ │ ├── activity_text_input_layout.xml │ │ ├── activity_text_path_view.xml │ │ ├── activity_text_view.xml │ │ ├── activity_theory.xml │ │ ├── activity_time_line_marker_view.xml │ │ ├── activity_verify_code_view.xml │ │ ├── activity_zfbhome_telescopic.xml │ │ ├── activity_zhifubao.xml │ │ ├── common_key.xml │ │ ├── content_zfb_top.xml │ │ ├── delete_key.xml │ │ ├── demo_item.xml │ │ ├── include_open.xml │ │ ├── include_toolbar_close.xml │ │ ├── include_toolbar_open.xml │ │ ├── item_text.xml │ │ ├── layout_keyboard.xml │ │ └── view_verify_code.xml │ │ ├── mipmap-xhdpi │ │ ├── ic_add.png │ │ ├── ic_card.png │ │ ├── ic_contact.png │ │ ├── ic_heart_0.png │ │ ├── ic_heart_1.png │ │ ├── ic_heart_2.png │ │ ├── ic_heart_3.png │ │ ├── ic_heart_4.png │ │ ├── ic_heart_5.png │ │ ├── ic_heart_6.png │ │ ├── ic_payment.png │ │ ├── ic_scan.png │ │ ├── ic_search.png │ │ ├── ic_transfer.png │ │ └── link.png │ │ ├── mipmap-xxhdpi │ │ ├── gray.png │ │ ├── green.png │ │ ├── ic_delete.png │ │ ├── ic_launcher.png │ │ ├── ic_share_fb.png │ │ ├── ic_share_kongjian.png │ │ ├── ic_share_pyq.png │ │ ├── ic_share_qq.png │ │ ├── ic_share_tw.png │ │ ├── ic_share_wechat.png │ │ ├── ic_share_weibo.png │ │ ├── keyboard_0.png │ │ ├── keyboard_1.png │ │ ├── keyboard_2.png │ │ ├── keyboard_3.png │ │ ├── keyboard_4.png │ │ ├── keyboard_5.png │ │ ├── keyboard_6.png │ │ ├── keyboard_7.png │ │ ├── keyboard_8.png │ │ ├── keyboard_9.png │ │ ├── keyboard_del.png │ │ ├── keyboard_del_press.png │ │ ├── link.png │ │ ├── pl_blue.png │ │ ├── pl_red.png │ │ ├── pl_yellow.png │ │ ├── right.png │ │ └── test.jpg │ │ └── values │ │ ├── attrs.xml │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── ids.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── com │ └── lemon │ └── customview │ └── ExampleUnitTest.java ├── build.gradle ├── gif └── 2018-09-18 14_42_53.gif ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | .externalNativeBuild 10 | -------------------------------------------------------------------------------- /.idea/caches/build_file_checksums.ser: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kriy/CustomView/d9f17e0e86da3d98be6c9716622a4ecab8a91b0d/.idea/caches/build_file_checksums.ser -------------------------------------------------------------------------------- /.idea/codeStyles/Project.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 15 | 16 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 19 | 20 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CustomView 2 | 不定期更新一些自定义控件 3 | 4 | 1.深度图,[博文](https://blog.csdn.net/hj2drf/article/details/82744822) 5 | 6 | ![image](https://github.com/Kriy/CustomView/blob/master/gif/2018-09-18%2014_42_53.gif) 7 | 8 | 2.时间线,此控件主要用于带有进度展示的场景或者类似的 9 | 10 | 3.跑马灯,常用文案轮播场景 11 | 12 | 4.TextView相关 13 | 14 | 4.1 倾斜TextView,可用于图片标签场景等 15 | 16 | 4.2 折叠TextView 17 | 18 | 4.3 加强版折叠TextView 19 | 20 | 4.4 数字变化TextView 21 | 22 | 4.5 渐变TextView 23 | 24 | 5.自定义数字键盘 25 | 26 | 6.验证码输入框 27 | 28 | 7.折叠Textview 29 | 30 | 8.圆角Imageview 31 | 32 | 9.3DView 33 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | apply plugin: 'kotlin-android' 3 | apply plugin: 'kotlin-android-extensions' 4 | 5 | android { 6 | compileSdkVersion 29 7 | buildToolsVersion '28.0.3' 8 | defaultConfig { 9 | applicationId "com.lemon.customview" 10 | minSdkVersion 18 11 | targetSdkVersion 29 12 | versionCode 1 13 | versionName "1.0" 14 | testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner' 15 | } 16 | buildTypes { 17 | release { 18 | minifyEnabled false 19 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 20 | } 21 | } 22 | compileOptions { 23 | targetCompatibility 1.8 24 | sourceCompatibility 1.8 25 | } 26 | } 27 | 28 | dependencies { 29 | implementation fileTree(include: ['*.jar'], dir: 'libs') 30 | implementation 'androidx.appcompat:appcompat:1.0.0' 31 | implementation 'androidx.constraintlayout:constraintlayout:1.1.3' 32 | implementation 'androidx.recyclerview:recyclerview:1.0.0' 33 | implementation 'com.google.android.material:material:1.0.0' 34 | implementation files('libs/jbox2d-library-2.3.1-SNAPSHOT.jar') 35 | implementation 'androidx.cardview:cardview:1.0.0' 36 | } 37 | -------------------------------------------------------------------------------- /app/libs/jbox2d-library-2.3.1-SNAPSHOT.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kriy/CustomView/d9f17e0e86da3d98be6c9716622a4ecab8a91b0d/app/libs/jbox2d-library-2.3.1-SNAPSHOT.jar -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in E:\andoridsoftware\sdk1122-lite\sdk1122-lite/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | 19 | # Uncomment this to preserve the line number information for 20 | # debugging stack traces. 21 | #-keepattributes SourceFile,LineNumberTable 22 | 23 | # If you keep the line number information, uncomment this to 24 | # hide the original source file name. 25 | #-renamesourcefileattribute SourceFile 26 | -------------------------------------------------------------------------------- /app/src/androidTest/java/com/lemon/customview/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.lemon.customview; 2 | 3 | import android.content.Context; 4 | import android.support.test.InstrumentationRegistry; 5 | import android.support.test.runner.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Instrumentation test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() throws Exception { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("com.lemon.customview", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/assets/fonts/AmaticaSC-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kriy/CustomView/d9f17e0e86da3d98be6c9716622a4ecab8a91b0d/app/src/main/assets/fonts/AmaticaSC-Regular.ttf -------------------------------------------------------------------------------- /app/src/main/assets/fonts/Lato-Black.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kriy/CustomView/d9f17e0e86da3d98be6c9716622a4ecab8a91b0d/app/src/main/assets/fonts/Lato-Black.ttf -------------------------------------------------------------------------------- /app/src/main/assets/fonts/Mirza-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kriy/CustomView/d9f17e0e86da3d98be6c9716622a4ecab8a91b0d/app/src/main/assets/fonts/Mirza-Regular.ttf -------------------------------------------------------------------------------- /app/src/main/assets/fonts/PoiretOne-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kriy/CustomView/d9f17e0e86da3d98be6c9716622a4ecab8a91b0d/app/src/main/assets/fonts/PoiretOne-Regular.ttf -------------------------------------------------------------------------------- /app/src/main/java/com/lemon/customview/activity/WebViewActivity.java: -------------------------------------------------------------------------------- 1 | package com.lemon.customview.activity; 2 | 3 | import android.os.Build; 4 | import android.os.Bundle; 5 | import androidx.annotation.Nullable; 6 | import androidx.appcompat.app.AppCompatActivity; 7 | import android.view.ViewGroup; 8 | import android.webkit.WebSettings; 9 | import android.webkit.WebView; 10 | import android.webkit.WebViewClient; 11 | 12 | public class WebViewActivity extends AppCompatActivity { 13 | 14 | WebView mWebView; 15 | 16 | @Override 17 | protected void onCreate(@Nullable Bundle savedInstanceState) { 18 | super.onCreate(savedInstanceState); 19 | mWebView = new WebView(WebViewActivity.this); 20 | setContentView(mWebView); 21 | 22 | String url = getIntent().getStringExtra("url"); 23 | WebSettings settings = mWebView.getSettings(); 24 | settings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK); 25 | settings.setDatabaseEnabled(true); 26 | settings.setAppCacheEnabled(true); 27 | settings.setDomStorageEnabled(true); 28 | settings.setJavaScriptEnabled(true); 29 | settings.setAllowContentAccess(true); 30 | settings.setAllowFileAccess(true); 31 | settings.setAllowFileAccessFromFileURLs(true); 32 | settings.setLoadWithOverviewMode(true); 33 | settings.setBuiltInZoomControls(false); 34 | if (Build.VERSION.SDK_INT >= 21) { 35 | settings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW); 36 | } 37 | 38 | mWebView.setWebViewClient(new WebViewClient()); 39 | mWebView.loadUrl(url); 40 | } 41 | 42 | @Override 43 | protected void onDestroy() { 44 | if (mWebView != null) { 45 | ViewGroup parent = (ViewGroup) mWebView.getParent(); 46 | if (parent != null) 47 | parent.removeView(mWebView); 48 | mWebView.stopLoading(); 49 | mWebView.clearHistory(); 50 | mWebView.removeAllViews(); 51 | mWebView.destroy(); 52 | } 53 | super.onDestroy(); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /app/src/main/java/com/lemon/customview/activity/material/MaterialActivity.java: -------------------------------------------------------------------------------- 1 | package com.lemon.customview.activity.material; 2 | 3 | import android.content.Intent; 4 | import android.os.Bundle; 5 | 6 | import androidx.annotation.Nullable; 7 | import androidx.appcompat.app.AppCompatActivity; 8 | 9 | import android.view.View; 10 | 11 | import com.lemon.customview.R; 12 | 13 | /** 14 | * Created by Terminator on 2019/4/7. 15 | */ 16 | public class MaterialActivity extends AppCompatActivity implements View.OnClickListener { 17 | 18 | @Override 19 | protected void onCreate(@Nullable Bundle savedInstanceState) { 20 | super.onCreate(savedInstanceState); 21 | setContentView(R.layout.activity_material); 22 | findViewById(R.id.btn_text_input_layout); 23 | } 24 | 25 | @Override 26 | public void onClick(View v) { 27 | switch (v.getId()) { 28 | case R.id.btn_text_input_layout: 29 | startActivity(new Intent(MaterialActivity.this, TextInputLayoutActivity.class)); 30 | break; 31 | default: 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /app/src/main/java/com/lemon/customview/activity/material/TextInputLayoutActivity.java: -------------------------------------------------------------------------------- 1 | package com.lemon.customview.activity.material; 2 | 3 | import android.os.Bundle; 4 | import androidx.annotation.Nullable; 5 | import androidx.appcompat.app.AppCompatActivity; 6 | 7 | import com.lemon.customview.R; 8 | 9 | /** 10 | * Created by Terminator on 2019/4/3. 11 | */ 12 | public class TextInputLayoutActivity extends AppCompatActivity { 13 | 14 | @Override 15 | protected void onCreate(@Nullable Bundle savedInstanceState) { 16 | super.onCreate(savedInstanceState); 17 | setContentView(R.layout.activity_text_input_layout); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /app/src/main/java/com/lemon/customview/activity/material/ZhiFuBaoActivity.java: -------------------------------------------------------------------------------- 1 | package com.lemon.customview.activity.material; 2 | 3 | import android.os.Bundle; 4 | import androidx.annotation.Nullable; 5 | import androidx.appcompat.app.AppCompatActivity; 6 | 7 | import com.lemon.customview.R; 8 | 9 | /** 10 | * Created by Terminator on 2019/4/8. 11 | */ 12 | public class ZhiFuBaoActivity extends AppCompatActivity { 13 | 14 | @Override 15 | protected void onCreate(@Nullable Bundle savedInstanceState) { 16 | super.onCreate(savedInstanceState); 17 | setContentView(R.layout.activity_zhifubao); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /app/src/main/java/com/lemon/customview/activity/view/KeyboardActivity.java: -------------------------------------------------------------------------------- 1 | package com.lemon.customview.activity.view; 2 | 3 | import android.os.Bundle; 4 | import androidx.annotation.Nullable; 5 | import androidx.appcompat.app.AppCompatActivity; 6 | import android.text.TextUtils; 7 | import android.widget.TextView; 8 | import android.widget.Toast; 9 | 10 | import com.lemon.customview.R; 11 | import com.lemon.customview.widget.KeyboardView; 12 | 13 | 14 | public class KeyboardActivity extends AppCompatActivity { 15 | 16 | TextView mTvInput; 17 | KeyboardView mKv; 18 | 19 | @Override 20 | protected void onCreate(@Nullable Bundle savedInstanceState) { 21 | super.onCreate(savedInstanceState); 22 | setContentView(R.layout.activity_keyboard); 23 | 24 | mTvInput = findViewById(R.id.tv_input); 25 | mKv = findViewById(R.id.kv); 26 | 27 | mKv.setOnItemClickListener(position -> { 28 | if (position == 10) { 29 | String content = mTvInput.getText().toString(); 30 | if (!TextUtils.isEmpty(content)) { 31 | mTvInput.setText(content.substring(0, content.length() - 1)); 32 | } 33 | } else if (position == 11) { 34 | mTvInput.append("0"); 35 | } else if (position == 12) { 36 | Toast.makeText(KeyboardActivity.this, "完成", Toast.LENGTH_SHORT).show(); 37 | } else { 38 | mTvInput.append(position + ""); 39 | } 40 | }); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /app/src/main/java/com/lemon/customview/activity/view/LinePathActivity.java: -------------------------------------------------------------------------------- 1 | package com.lemon.customview.activity.view; 2 | 3 | import android.graphics.Path; 4 | import android.os.Bundle; 5 | import androidx.annotation.Nullable; 6 | import androidx.appcompat.app.AppCompatActivity; 7 | import android.view.View; 8 | import android.view.ViewGroup; 9 | import android.widget.FrameLayout; 10 | 11 | import com.lemon.customview.R; 12 | import com.lemon.customview.widget.LinePathView; 13 | 14 | public class LinePathActivity extends AppCompatActivity { 15 | 16 | private FrameLayout mFrameLayout; 17 | 18 | @Override 19 | protected void onCreate(@Nullable Bundle savedInstanceState) { 20 | super.onCreate(savedInstanceState); 21 | setContentView(R.layout.activity_line_path); 22 | 23 | mFrameLayout = findViewById(R.id.fl_content); 24 | //mFrameLayout.removeAllViews(); 25 | 26 | mFrameLayout.post(() -> { 27 | setPath(); 28 | startAnimation(); 29 | }); 30 | } 31 | 32 | private void startAnimation() { 33 | for (int i = 0; i < mFrameLayout.getChildCount(); i++) { 34 | View childView = mFrameLayout.getChildAt(i); 35 | if (childView instanceof LinePathView) { 36 | ((LinePathView) childView).startAnimation(); 37 | } 38 | } 39 | } 40 | 41 | private void setPath() { 42 | Path path1 = new Path(); 43 | Path path2 = new Path(); 44 | Path path3; 45 | Path path4; 46 | Path path5; 47 | Path path6; 48 | 49 | path1.moveTo(310, 0); 50 | path2.moveTo(410, 0); 51 | 52 | path1.lineTo(310, 400); 53 | path1.lineTo(210, 500); 54 | path1.lineTo(210, 600); 55 | path1.lineTo(310, 700); 56 | path1.lineTo(310, 1280); 57 | 58 | path2.lineTo(410, 400); 59 | path2.lineTo(510, 500); 60 | path2.lineTo(510, 600); 61 | path2.lineTo(410, 700); 62 | path2.lineTo(410, 1280); 63 | 64 | path3 = new Path(path1); 65 | path3.offset(-100, 0); 66 | path5 = new Path(path1); 67 | path5.offset(-200, 0); 68 | path4 = new Path(path2); 69 | path4.offset(+100, 0); 70 | path6 = new Path(path2); 71 | path6.offset(+200, 0); 72 | 73 | for (int i = 0; i < 6; i++) { 74 | LinePathView pathView = new LinePathView(LinePathActivity.this); 75 | switch (i) { 76 | case 0: 77 | pathView.setPath(path1); 78 | break; 79 | case 1: 80 | pathView.setPath(path2); 81 | break; 82 | case 2: 83 | pathView.setPath(path3); 84 | pathView.setMode(LinePathView.TRAIN_MODE); 85 | break; 86 | case 3: 87 | pathView.setPath(path4); 88 | pathView.setMode(LinePathView.TRAIN_MODE); 89 | break; 90 | case 4: 91 | pathView.setPath(path5); 92 | break; 93 | case 5: 94 | pathView.setPath(path6); 95 | break; 96 | } 97 | pathView.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); 98 | mFrameLayout.addView(pathView, 0); 99 | } 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /app/src/main/java/com/lemon/customview/activity/view/MarqueeViewActivity.java: -------------------------------------------------------------------------------- 1 | package com.lemon.customview.activity.view; 2 | 3 | import android.os.Bundle; 4 | 5 | import androidx.annotation.Nullable; 6 | import androidx.appcompat.app.AppCompatActivity; 7 | 8 | import android.view.View; 9 | 10 | import com.lemon.customview.R; 11 | import com.lemon.customview.widget.MarqueeView; 12 | 13 | import java.util.ArrayList; 14 | import java.util.List; 15 | 16 | 17 | public class MarqueeViewActivity extends AppCompatActivity implements View.OnClickListener { 18 | 19 | private MarqueeView mMvMain1; 20 | private MarqueeView mMvMain2; 21 | private MarqueeView mMvMain3; 22 | private String content2; 23 | private String content3; 24 | private List list1 = new ArrayList<>(); 25 | 26 | @Override 27 | protected void onCreate(@Nullable Bundle savedInstanceState) { 28 | super.onCreate(savedInstanceState); 29 | setContentView(R.layout.activity_marquee_view); 30 | 31 | initData(); 32 | } 33 | 34 | private void initData() { 35 | mMvMain1 = findViewById(R.id.mv_main1); 36 | mMvMain2 = findViewById(R.id.mv_main2); 37 | mMvMain3 = findViewById(R.id.mv_main3); 38 | findViewById(R.id.bt_control0).setOnClickListener(this); 39 | findViewById(R.id.bt_control4).setOnClickListener(this); 40 | findViewById(R.id.bt_control24).setOnClickListener(this); 41 | findViewById(R.id.bt_control23).setOnClickListener(this); 42 | findViewById(R.id.bt_control).setOnClickListener(this); 43 | findViewById(R.id.bt_control2).setOnClickListener(this); 44 | findViewById(R.id.bt_control00).setOnClickListener(this); 45 | list1.add("北冥有鱼 其名为鲲"); 46 | list1.add("鲲之大 不知其几千里也; 化而为鸟 其名为鹏"); 47 | list1.add("故夫知效一官, 行比一乡, 德合一君,"); 48 | content2 = "要么孤独,要么庸俗 "; 49 | content3 = "你在桥上看风景 看风景的人 在楼上看你"; 50 | } 51 | 52 | @Override 53 | public void onClick(View v) { 54 | switch (v.getId()) { 55 | case R.id.bt_control0: 56 | mMvMain1.setContent(list1); 57 | mMvMain2.setContent(content2); 58 | mMvMain3.setContent(content3); 59 | break; 60 | case R.id.bt_control4: 61 | mMvMain2.setTextColor(R.color.colorAccent); 62 | break; 63 | case R.id.bt_control24: 64 | mMvMain2.setTextSize(17); 65 | break; 66 | case R.id.bt_control23: 67 | mMvMain2.setTextSpeed(5); 68 | break; 69 | case R.id.bt_control: 70 | mMvMain3.continueRoll(); 71 | break; 72 | case R.id.bt_control2: 73 | mMvMain3.stopRoll(); 74 | break; 75 | case R.id.bt_control00: 76 | mMvMain3.setTextDistance(50);//设置3的间距 77 | break; 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /app/src/main/java/com/lemon/customview/activity/view/MeiHeartViewActivity.java: -------------------------------------------------------------------------------- 1 | package com.lemon.customview.activity.view; 2 | 3 | import android.graphics.Bitmap; 4 | import android.graphics.BitmapFactory; 5 | import android.os.Bundle; 6 | 7 | import androidx.annotation.Nullable; 8 | import androidx.appcompat.app.AppCompatActivity; 9 | 10 | import android.util.SparseArray; 11 | import android.view.View; 12 | 13 | import com.lemon.customview.R; 14 | import com.lemon.customview.widget.Heart.HeartType; 15 | import com.lemon.customview.widget.Heart.MeiHeartView; 16 | 17 | public class MeiHeartViewActivity extends AppCompatActivity { 18 | private MeiHeartView mHeartView; 19 | 20 | @Override 21 | protected void onCreate(@Nullable Bundle savedInstanceState) { 22 | super.onCreate(savedInstanceState); 23 | setContentView(R.layout.activity_mei_heart_view); 24 | 25 | mHeartView = findViewById(R.id.heart_view); 26 | setHeartBitmap(); 27 | 28 | mHeartView.setOnClickListener(new View.OnClickListener() { 29 | @Override 30 | public void onClick(View v) { 31 | mHeartView.addHeart(); 32 | } 33 | }); 34 | 35 | intervalAddHeart(); 36 | } 37 | 38 | private void intervalAddHeart() { 39 | mHeartView.postDelayed(new Runnable() { 40 | @Override 41 | public void run() { 42 | mHeartView.performClick(); 43 | intervalAddHeart(); 44 | } 45 | }, 1000); 46 | } 47 | 48 | public void setHeartBitmap() { 49 | SparseArray bitmapArray = new SparseArray<>(); 50 | Bitmap bitmap1 = BitmapFactory.decodeResource(this.getResources(), R.mipmap.ic_heart_0); 51 | Bitmap bitmap2 = BitmapFactory.decodeResource(this.getResources(), R.mipmap.ic_heart_1); 52 | Bitmap bitmap3 = BitmapFactory.decodeResource(this.getResources(), R.mipmap.ic_heart_2); 53 | Bitmap bitmap4 = BitmapFactory.decodeResource(this.getResources(), R.mipmap.ic_heart_3); 54 | Bitmap bitmap5 = BitmapFactory.decodeResource(this.getResources(), R.mipmap.ic_heart_4); 55 | Bitmap bitmap6 = BitmapFactory.decodeResource(this.getResources(), R.mipmap.ic_heart_5); 56 | Bitmap bitmap7 = BitmapFactory.decodeResource(this.getResources(), R.mipmap.ic_heart_6); 57 | bitmapArray.put(HeartType.BLUE, bitmap1); 58 | bitmapArray.put(HeartType.GREEN, bitmap2); 59 | bitmapArray.put(HeartType.YELLOW, bitmap3); 60 | bitmapArray.put(HeartType.PINK, bitmap4); 61 | bitmapArray.put(HeartType.BROWN, bitmap5); 62 | bitmapArray.put(HeartType.PURPLE, bitmap6); 63 | bitmapArray.put(HeartType.RED, bitmap7); 64 | mHeartView.setHeartBitmap(bitmapArray); 65 | } 66 | 67 | 68 | } 69 | -------------------------------------------------------------------------------- /app/src/main/java/com/lemon/customview/activity/view/Roll3DViewActivity.java: -------------------------------------------------------------------------------- 1 | package com.lemon.customview.activity.view; 2 | 3 | import android.os.Bundle; 4 | 5 | import androidx.annotation.Nullable; 6 | import androidx.appcompat.app.AppCompatActivity; 7 | 8 | import com.lemon.customview.R; 9 | import com.lemon.customview.widget.Roll3DLinearLayout; 10 | import com.lemon.customview.widget.Roll3DView; 11 | 12 | 13 | public class Roll3DViewActivity extends AppCompatActivity { 14 | 15 | private Roll3DLinearLayout mItem1; 16 | private Roll3DLinearLayout mItem2; 17 | private Roll3DLinearLayout mItem3; 18 | private Roll3DLinearLayout mItem4; 19 | private Roll3DLinearLayout mItem5; 20 | 21 | @Override 22 | protected void onCreate(@Nullable Bundle savedInstanceState) { 23 | super.onCreate(savedInstanceState); 24 | setContentView(R.layout.activity_roll_3d_view); 25 | initView(); 26 | } 27 | 28 | private void initView() { 29 | mItem1 = findViewById(R.id.item1); 30 | mItem2 = findViewById(R.id.item2); 31 | mItem3 = findViewById(R.id.item3); 32 | mItem4 = findViewById(R.id.item4); 33 | mItem5 = findViewById(R.id.item5); 34 | Roll3DView roll3DView1 = mItem1.getRoll3DView(); 35 | Roll3DView roll3DView2 = mItem2.getRoll3DView(); 36 | Roll3DView roll3DView3 = mItem3.getRoll3DView(); 37 | Roll3DView roll3DView4 = mItem4.getRoll3DView(); 38 | Roll3DView roll3DView5 = mItem5.getRoll3DView(); 39 | 40 | roll3DView1.setRollMode(Roll3DView.RollMode.Roll2D); 41 | mItem1.setTitleText("2D平移"); 42 | 43 | roll3DView2.setRollMode(Roll3DView.RollMode.Whole3D); 44 | mItem2.setTitleText("3D翻转"); 45 | 46 | roll3DView3.setRollMode(Roll3DView.RollMode.SepartConbine); 47 | roll3DView3.setPartNumber(3); 48 | mItem3.setTitleText("开合效果"); 49 | 50 | roll3DView4.setRollMode(Roll3DView.RollMode.Jalousie); 51 | roll3DView4.setPartNumber(8); 52 | mItem4.setTitleText("百叶窗"); 53 | 54 | roll3DView5.setRollMode(Roll3DView.RollMode.RollInTurn); 55 | roll3DView5.setPartNumber(9); 56 | mItem5.setTitleText("轮转效果"); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /app/src/main/java/com/lemon/customview/activity/view/RoundImageViewActivity.java: -------------------------------------------------------------------------------- 1 | package com.lemon.customview.activity.view; 2 | 3 | import android.os.Bundle; 4 | import androidx.annotation.Nullable; 5 | import androidx.appcompat.app.AppCompatActivity; 6 | 7 | import com.lemon.customview.R; 8 | 9 | public class RoundImageViewActivity extends AppCompatActivity { 10 | 11 | @Override 12 | protected void onCreate(@Nullable Bundle savedInstanceState) { 13 | super.onCreate(savedInstanceState); 14 | setContentView(R.layout.activity_round_image_view); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /app/src/main/java/com/lemon/customview/activity/view/ShapeImageViewActivity.java: -------------------------------------------------------------------------------- 1 | package com.lemon.customview.activity.view; 2 | 3 | import android.os.Bundle; 4 | import androidx.annotation.Nullable; 5 | import androidx.appcompat.app.AppCompatActivity; 6 | 7 | import com.lemon.customview.R; 8 | 9 | public class ShapeImageViewActivity extends AppCompatActivity{ 10 | 11 | @Override 12 | protected void onCreate(@Nullable Bundle savedInstanceState) { 13 | super.onCreate(savedInstanceState); 14 | setContentView(R.layout.activity_shape_image_view); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /app/src/main/java/com/lemon/customview/activity/view/TextPathViewActivity.java: -------------------------------------------------------------------------------- 1 | package com.lemon.customview.activity.view; 2 | 3 | import android.content.Context; 4 | import android.hardware.Sensor; 5 | import android.hardware.SensorEvent; 6 | import android.hardware.SensorEventListener; 7 | import android.hardware.SensorManager; 8 | import android.os.Bundle; 9 | import androidx.annotation.Nullable; 10 | import androidx.appcompat.app.AppCompatActivity; 11 | import android.view.Gravity; 12 | import android.view.View; 13 | import android.widget.FrameLayout; 14 | import android.widget.ImageView; 15 | 16 | import com.lemon.customview.R; 17 | import com.lemon.customview.widget.new_path.MoBikeView; 18 | 19 | public class TextPathViewActivity extends AppCompatActivity implements SensorEventListener{ 20 | 21 | private MoBikeView mMobikeView; 22 | 23 | private SensorManager mSensorManager; 24 | private Sensor mSensor; 25 | 26 | private int[] mImgs = { 27 | R.mipmap.ic_share_fb, 28 | R.mipmap.ic_share_kongjian, 29 | R.mipmap.ic_share_pyq, 30 | R.mipmap.ic_share_qq, 31 | R.mipmap.ic_share_tw, 32 | R.mipmap.ic_share_wechat, 33 | R.mipmap.ic_share_weibo 34 | }; 35 | 36 | @Override 37 | protected void onCreate(@Nullable Bundle savedInstanceState) { 38 | super.onCreate(savedInstanceState); 39 | setContentView(R.layout.activity_text_path_view); 40 | 41 | mMobikeView = findViewById(R.id.mo_bike); 42 | 43 | mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); 44 | mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); 45 | 46 | addViews(); 47 | 48 | mMobikeView.setOnClickListener(new View.OnClickListener() { 49 | @Override 50 | public void onClick(View v) { 51 | mMobikeView.onRandomChanged(); 52 | } 53 | }); 54 | } 55 | 56 | @Override 57 | protected void onResume() { 58 | super.onResume(); 59 | mSensorManager.registerListener(this, mSensor, SensorManager.SENSOR_DELAY_UI); 60 | } 61 | 62 | @Override 63 | protected void onPause() { 64 | super.onPause(); 65 | mSensorManager.unregisterListener(this); 66 | } 67 | 68 | private void addViews() { 69 | FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT, 70 | FrameLayout.LayoutParams.WRAP_CONTENT); 71 | lp.gravity = Gravity.CENTER; 72 | for (int mImg : mImgs) { 73 | ImageView iv = new ImageView(this); 74 | iv.setImageResource(mImg); 75 | iv.setTag(R.id.wd_view_circle_tag, true); 76 | mMobikeView.addView(iv, lp); 77 | } 78 | } 79 | 80 | @Override 81 | public void onSensorChanged(SensorEvent event) { 82 | if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) { 83 | float x = event.values[0]; 84 | float y = event.values[1] * 2.0f; 85 | mMobikeView.onSensorChanged(-x, y); 86 | } 87 | } 88 | 89 | @Override 90 | public void onAccuracyChanged(Sensor sensor, int accuracy) { 91 | 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /app/src/main/java/com/lemon/customview/activity/view/TheoryActivity.java: -------------------------------------------------------------------------------- 1 | package com.lemon.customview.activity.view; 2 | 3 | import android.content.Intent; 4 | import android.os.Bundle; 5 | 6 | import androidx.annotation.Nullable; 7 | import androidx.appcompat.app.AppCompatActivity; 8 | 9 | import android.view.View; 10 | 11 | import com.lemon.customview.R; 12 | import com.lemon.customview.activity.WebViewActivity; 13 | 14 | 15 | public class TheoryActivity extends AppCompatActivity implements View.OnClickListener { 16 | 17 | @Override 18 | protected void onCreate(@Nullable Bundle savedInstanceState) { 19 | super.onCreate(savedInstanceState); 20 | setContentView(R.layout.activity_theory); 21 | findViewById(R.id.btn_one).setOnClickListener(this); 22 | findViewById(R.id.btn_two).setOnClickListener(this); 23 | } 24 | 25 | @Override 26 | public void onClick(View v) { 27 | switch (v.getId()) { 28 | case R.id.btn_one: 29 | // https://juejin.im/entry/595f0383f265da6c3a54d6bf 30 | Intent intent = new Intent(TheoryActivity.this, WebViewActivity.class); 31 | intent.putExtra("url", "https://juejin.im/entry/595f0383f265da6c3a54d6bf"); 32 | startActivity(intent); 33 | break; 34 | case R.id.btn_two: 35 | break; 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /app/src/main/java/com/lemon/customview/activity/view/TimeLineMarkerViewActivity.java: -------------------------------------------------------------------------------- 1 | package com.lemon.customview.activity.view; 2 | 3 | import android.os.Bundle; 4 | import androidx.annotation.Nullable; 5 | import androidx.appcompat.app.AppCompatActivity; 6 | 7 | import com.lemon.customview.R; 8 | 9 | public class TimeLineMarkerViewActivity extends AppCompatActivity { 10 | 11 | @Override 12 | protected void onCreate(@Nullable Bundle savedInstanceState) { 13 | super.onCreate(savedInstanceState); 14 | setContentView(R.layout.activity_time_line_marker_view); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /app/src/main/java/com/lemon/customview/activity/view/VerifyCodeViewActivity.java: -------------------------------------------------------------------------------- 1 | package com.lemon.customview.activity.view; 2 | 3 | import android.os.Bundle; 4 | 5 | import androidx.annotation.Nullable; 6 | import androidx.appcompat.app.AppCompatActivity; 7 | 8 | import android.view.View; 9 | import android.widget.Toast; 10 | 11 | import com.lemon.customview.R; 12 | import com.lemon.customview.widget.VerifyCodeView; 13 | 14 | public class VerifyCodeViewActivity extends AppCompatActivity { 15 | 16 | @Override 17 | protected void onCreate(@Nullable Bundle savedInstanceState) { 18 | super.onCreate(savedInstanceState); 19 | setContentView(R.layout.activity_verify_code_view); 20 | 21 | ((VerifyCodeView) findViewById(R.id.verify_code_1)).setInputCompleteListener(new VerifyCodeView.InputCompleteListener() { 22 | @Override 23 | public void inputComplete() { 24 | Toast.makeText(VerifyCodeViewActivity.this, "输入完成", Toast.LENGTH_SHORT).show(); 25 | } 26 | 27 | @Override 28 | public void invalidContent() { 29 | 30 | } 31 | }); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /app/src/main/java/com/lemon/customview/activity/view/imageview/ImageViewActivity.kt: -------------------------------------------------------------------------------- 1 | package com.lemon.customview.activity.view.imageview 2 | 3 | import android.content.Intent 4 | import android.os.Bundle 5 | import android.view.View 6 | import androidx.appcompat.app.AppCompatActivity 7 | import com.lemon.customview.R 8 | import com.lemon.customview.activity.view.RoundImageViewActivity 9 | import com.lemon.customview.activity.view.ShapeImageViewActivity 10 | import kotlinx.android.synthetic.main.activity_image_view.* 11 | 12 | class ImageViewActivity : AppCompatActivity(), View.OnClickListener { 13 | 14 | override fun onCreate(savedInstanceState: Bundle?) { 15 | super.onCreate(savedInstanceState) 16 | setContentView(R.layout.activity_image_view) 17 | 18 | btn_round_image_view.setOnClickListener(this) 19 | btn_shape_image_view.setOnClickListener(this) 20 | } 21 | 22 | override fun onClick(v: View) { 23 | when (v.id) { 24 | R.id.btn_round_image_view -> startActivity( 25 | Intent( 26 | this@ImageViewActivity, 27 | RoundImageViewActivity::class.java 28 | ) 29 | ) 30 | R.id.btn_shape_image_view -> startActivity( 31 | Intent( 32 | this@ImageViewActivity, 33 | ShapeImageViewActivity::class.java 34 | ) 35 | ) 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /app/src/main/java/com/lemon/customview/activity/view/textview/AlphaTextViewActivity.kt: -------------------------------------------------------------------------------- 1 | package com.lemon.customview.activity.view.textview 2 | 3 | import android.os.Bundle 4 | import androidx.appcompat.app.AppCompatActivity 5 | import com.lemon.customview.R 6 | import kotlinx.android.synthetic.main.activity_alpha_text_view.* 7 | 8 | class AlphaTextViewActivity : AppCompatActivity() { 9 | 10 | override fun onCreate(savedInstanceState: Bundle?) { 11 | super.onCreate(savedInstanceState) 12 | setContentView(R.layout.activity_alpha_text_view) 13 | 14 | 15 | tv_alpha.setDuration(3000) 16 | tv_alpha.setOnClickListener { 17 | tv_alpha.toggle() 18 | } 19 | btn.setOnClickListener { 20 | tv_alpha.setText("Alpha TextView Activity TextView", true) 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /app/src/main/java/com/lemon/customview/activity/view/textview/FoldTextViewActivity.java: -------------------------------------------------------------------------------- 1 | package com.lemon.customview.activity.view.textview; 2 | 3 | import android.os.Bundle; 4 | import androidx.annotation.Nullable; 5 | import androidx.appcompat.app.AppCompatActivity; 6 | import android.view.View; 7 | import android.widget.FrameLayout; 8 | import android.widget.TextView; 9 | import android.widget.Toast; 10 | 11 | import com.lemon.customview.R; 12 | 13 | 14 | public class FoldTextViewActivity extends AppCompatActivity implements View.OnClickListener{ 15 | 16 | @Override 17 | protected void onCreate(@Nullable Bundle savedInstanceState) { 18 | super.onCreate(savedInstanceState); 19 | setContentView(R.layout.activity_fold_textview); 20 | 21 | TextView text = findViewById(R.id.text); 22 | TextView text1 = findViewById(R.id.text1); 23 | TextView text2 = findViewById(R.id.text2); 24 | TextView text3 = findViewById(R.id.text3); 25 | text.setOnClickListener(this); 26 | text2.setOnClickListener(this); 27 | findViewById(R.id.parent1).setOnClickListener(this); 28 | findViewById(R.id.parent3).setOnClickListener(this); 29 | 30 | text.setText("111111123阿斯顿发阿斯顿发送到大。厦法定阿萨【德法师打发斯蒂芬撒地】方阿萨德法师打发斯问问蒂芬撒地方阿萨德法师打发斯蒂。芬撒地方发送到发送到发送到发送到发送到发送,到发送到发送到发送到,发送111111123阿斯顿发阿斯顿发送到大。厦法定阿萨【德法师打发斯蒂芬撒地】方阿萨德法师打发斯问问蒂芬撒地方阿萨德法师打发斯蒂。芬撒地方发送到发送到发送到发送到发送到发送,到发送到发送到发送到,发送"); 31 | text1.setText("111111123阿斯顿发阿斯顿发送到大。厦法定阿萨【德法师打发斯蒂芬撒地】方阿萨德法师打发斯问问蒂芬撒地方阿萨德法师打发斯蒂。芬撒地方发送到发送到发送到发送到发送到发送,到发送到发送到发送到,发送111111123阿斯顿发阿斯顿发送到大。厦法定阿萨【德法师打发斯蒂芬撒地】方阿萨德法师打发斯问问蒂芬撒地方阿萨德法师打发斯蒂。芬撒地方发送到发送到发送到发送到发送到发送,到发送到发送到发送到,发送"); 32 | text2.setText("111111123阿斯顿发阿斯顿发送到大。厦法定阿萨【德法师打发斯蒂芬撒地】方阿萨德法师打发斯问问蒂芬撒地方阿萨德法师打发斯蒂。芬撒地方发送到发送到发送到发送到发送到发送,到发送到发送到发送到,发送111111123阿斯顿发阿斯顿发送到大。厦法定阿萨【德法师打发斯蒂芬撒地】方阿萨德法师打发斯问问蒂芬撒地方阿萨德法师打发斯蒂。芬撒地方发送到发送到发送到发送到发送到发送,到发送到发送到发送到,发送"); 33 | text3.setText("111111123阿斯顿发阿斯顿发送到大。厦法定阿萨【德法师打发斯蒂芬撒地】方阿萨德法师打发斯问问蒂芬撒地方阿萨德法师打发斯蒂。芬撒地方发送到发送到发送到发送到发送到发送,到发送到发送到发送到,发送111111123阿斯顿发阿斯顿发送到大。厦法定阿萨【德法师打发斯蒂芬撒地】方阿萨德法师打发斯问问蒂芬撒地方阿萨德法师打发斯蒂。芬撒地方发送到发送到发送到发送到发送到发送,到发送到发送到发送到,发送"); 34 | } 35 | 36 | @Override 37 | public void onClick(View v) { 38 | switch (v.getId()) { 39 | case R.id.text: 40 | Toast.makeText(FoldTextViewActivity.this, "textView点击事件", Toast.LENGTH_SHORT).show(); 41 | break; 42 | case R.id.parent1: 43 | Toast.makeText(FoldTextViewActivity.this, "父View点击事件", Toast.LENGTH_SHORT).show(); 44 | break; 45 | case R.id.text2: 46 | Toast.makeText(FoldTextViewActivity.this, "textView点击事件", Toast.LENGTH_SHORT).show(); 47 | break; 48 | case R.id.parent3: 49 | Toast.makeText(FoldTextViewActivity.this, "父View点击事件", Toast.LENGTH_SHORT).show(); 50 | break; 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /app/src/main/java/com/lemon/customview/activity/view/textview/NumberTextViewActivity.kt: -------------------------------------------------------------------------------- 1 | package com.lemon.customview.activity.view.textview 2 | 3 | import android.os.Bundle 4 | import androidx.appcompat.app.AppCompatActivity 5 | import com.lemon.customview.R 6 | import kotlinx.android.synthetic.main.activity_number_text_view.* 7 | 8 | class NumberTextViewActivity : AppCompatActivity() { 9 | 10 | 11 | override fun onCreate(savedInstanceState: Bundle?) { 12 | super.onCreate(savedInstanceState) 13 | setContentView(R.layout.activity_number_text_view) 14 | 15 | ntv_1.setNumberString("非数字测试没有效果") 16 | 17 | 18 | btn_1.setOnClickListener { 19 | ntv_2.setPrefixString("$") 20 | ntv_2.setNumberString("100") 21 | } 22 | btn_2.setOnClickListener { 23 | ntv_3.setPostfixString("%") 24 | ntv_3.setNumberString("100") 25 | } 26 | btn_3.setOnClickListener { 27 | ntv_4.setNumberString("100") 28 | } 29 | ntv_5.setDuration(5000) 30 | ntv_5.setNumberString("1", "100") 31 | } 32 | 33 | } -------------------------------------------------------------------------------- /app/src/main/java/com/lemon/customview/activity/view/textview/SlantedTextViewActivity.java: -------------------------------------------------------------------------------- 1 | package com.lemon.customview.activity.view.textview; 2 | 3 | import android.os.Bundle; 4 | import androidx.annotation.Nullable; 5 | import androidx.appcompat.app.AppCompatActivity; 6 | 7 | import com.lemon.customview.R; 8 | 9 | public class SlantedTextViewActivity extends AppCompatActivity { 10 | 11 | @Override 12 | protected void onCreate(@Nullable Bundle savedInstanceState) { 13 | super.onCreate(savedInstanceState); 14 | setContentView(R.layout.activity_slanted_textview); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /app/src/main/java/com/lemon/customview/activity/view/textview/TextViewActivity.kt: -------------------------------------------------------------------------------- 1 | package com.lemon.customview.activity.view.textview 2 | 3 | import android.content.Intent 4 | import android.os.Bundle 5 | import android.view.View 6 | import androidx.appcompat.app.AppCompatActivity 7 | import com.lemon.customview.R 8 | import com.lemon.customview.activity.view.ExpandableTextViewActivity 9 | import com.lemon.customview.activity.view.MarqueeViewActivity 10 | import kotlinx.android.synthetic.main.activity_text_view.* 11 | 12 | class TextViewActivity : AppCompatActivity(), View.OnClickListener { 13 | 14 | override fun onCreate(savedInstanceState: Bundle?) { 15 | super.onCreate(savedInstanceState) 16 | setContentView(R.layout.activity_text_view) 17 | 18 | btn_slanted.setOnClickListener(this) 19 | btn_fold_text_view.setOnClickListener(this) 20 | btn_expand_text_view.setOnClickListener(this) 21 | btn_number_text_view.setOnClickListener(this) 22 | btn_alpha_text_view.setOnClickListener(this) 23 | btn_h_text_view.setOnClickListener(this) 24 | } 25 | 26 | override fun onClick(v: View) { 27 | when (v.id) { 28 | R.id.btn_slanted -> startActivity( 29 | Intent( 30 | this@TextViewActivity, 31 | SlantedTextViewActivity::class.java 32 | ) 33 | ) 34 | R.id.btn_fold_text_view -> startActivity( 35 | Intent( 36 | this@TextViewActivity, 37 | FoldTextViewActivity::class.java 38 | ) 39 | ) 40 | R.id.btn_expand_text_view -> startActivity( 41 | Intent( 42 | this@TextViewActivity, 43 | ExpandableTextViewActivity::class.java 44 | ) 45 | ) 46 | R.id.btn_number_text_view -> startActivity( 47 | Intent( 48 | this@TextViewActivity, 49 | NumberTextViewActivity::class.java 50 | ) 51 | ) 52 | R.id.btn_alpha_text_view -> startActivity( 53 | Intent( 54 | this@TextViewActivity, 55 | AlphaTextViewActivity::class.java 56 | ) 57 | ) 58 | R.id.btn_h_text_view -> startActivity( 59 | Intent( 60 | this@TextViewActivity, 61 | HTextViewActivity::class.java 62 | ) 63 | ) 64 | } 65 | } 66 | } -------------------------------------------------------------------------------- /app/src/main/java/com/lemon/customview/bean/DepthDataBean.java: -------------------------------------------------------------------------------- 1 | package com.lemon.customview.bean; 2 | 3 | public class DepthDataBean { 4 | 5 | private float mPrice; 6 | private float mVolume; 7 | 8 | public float getVolume() { 9 | return mVolume; 10 | } 11 | 12 | public void setVolume(float volume) { 13 | this.mVolume = volume; 14 | } 15 | 16 | public float getPrice() { 17 | return mPrice; 18 | } 19 | 20 | public void setPrice(float price) { 21 | this.mPrice = price; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /app/src/main/java/com/lemon/customview/listener/TextWatcherListener.java: -------------------------------------------------------------------------------- 1 | package com.lemon.customview.listener; 2 | 3 | import android.text.TextWatcher; 4 | 5 | public abstract class TextWatcherListener implements TextWatcher { 6 | @Override 7 | public void beforeTextChanged(CharSequence s, int start, int count, int after) { 8 | 9 | } 10 | 11 | @Override 12 | public void onTextChanged(CharSequence s, int start, int before, int count) { 13 | 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /app/src/main/java/com/lemon/customview/model/CharacterDiffResult.java: -------------------------------------------------------------------------------- 1 | package com.lemon.customview.model; 2 | 3 | public class CharacterDiffResult { 4 | public char c; 5 | public int fromIndex; 6 | public int moveIndex; 7 | } 8 | -------------------------------------------------------------------------------- /app/src/main/java/com/lemon/customview/model/ViewModel.java: -------------------------------------------------------------------------------- 1 | package com.lemon.customview.model; 2 | 3 | public class ViewModel { 4 | 5 | private String title; 6 | 7 | public ViewModel(String title) { 8 | this.title = title; 9 | } 10 | 11 | public String getTitle() { 12 | return title; 13 | } 14 | 15 | public void setTitle(String title) { 16 | this.title = title; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /app/src/main/java/com/lemon/customview/model/ViewModelWithFlag.java: -------------------------------------------------------------------------------- 1 | package com.lemon.customview.model; 2 | 3 | import com.lemon.customview.widget.ExpandableTextView.ExpandableTextView; 4 | import com.lemon.customview.widget.ExpandableTextView.StatusType; 5 | 6 | public class ViewModelWithFlag implements ExpandableTextView.ExpandableStatusFix { 7 | 8 | private StatusType status; 9 | 10 | public ViewModelWithFlag(String title) { 11 | this.title = title; 12 | } 13 | 14 | private String title; 15 | 16 | public String getTitle() { 17 | return title; 18 | } 19 | 20 | public void setTitle(String title) { 21 | this.title = title; 22 | } 23 | 24 | @Override 25 | public void setStatus(StatusType status) { 26 | this.status = status; 27 | } 28 | 29 | @Override 30 | public StatusType getStatus() { 31 | return status; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /app/src/main/java/com/lemon/customview/other/KeyboardDecoration.java: -------------------------------------------------------------------------------- 1 | package com.lemon.customview.other; 2 | 3 | import android.graphics.Rect; 4 | import androidx.recyclerview.widget.RecyclerView; 5 | import android.view.View; 6 | 7 | public class KeyboardDecoration extends RecyclerView.ItemDecoration { 8 | 9 | private int mSpanCount; 10 | private int mSpacing; 11 | private boolean mIncludeEdge; 12 | 13 | public KeyboardDecoration(int mSpanCount, int mSpacing, boolean mIncludeEdge) { 14 | this.mSpanCount = mSpanCount; 15 | this.mSpacing = mSpacing; 16 | this.mIncludeEdge = mIncludeEdge; 17 | } 18 | 19 | @Override 20 | 21 | public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { 22 | int position = parent.getChildAdapterPosition(view); 23 | int column = position % mSpanCount; 24 | 25 | if (mIncludeEdge) { 26 | outRect.left = mSpacing - column * mSpacing / mSpanCount; 27 | outRect.right = (column + 1) * mSpacing / mSpanCount; 28 | if (position < mSpanCount) { 29 | outRect.top = mSpacing; 30 | } 31 | outRect.bottom = mSpacing; 32 | } else { 33 | outRect.left = column * mSpacing / mSpanCount; 34 | outRect.right = mSpacing - (column + 1) * mSpacing / mSpanCount; 35 | if (position >= mSpanCount) { 36 | outRect.top = mSpacing; 37 | } 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /app/src/main/java/com/lemon/customview/utils/ReflectUtil.java: -------------------------------------------------------------------------------- 1 | package com.lemon.customview.utils; 2 | 3 | import java.lang.reflect.Field; 4 | import java.lang.reflect.Method; 5 | 6 | public class ReflectUtil { 7 | 8 | /** 9 | * 获取类里指定的变量 10 | * 11 | * @param thisClass 12 | * @param fieldName 13 | * @return 14 | */ 15 | public static Field getField(Class thisClass, String fieldName) { 16 | if (thisClass == null) { 17 | return null; 18 | } 19 | 20 | try { 21 | return thisClass.getDeclaredField(fieldName); 22 | } catch (Throwable e) { 23 | return null; 24 | } 25 | } 26 | 27 | /** 28 | * 获取对象里变量的值 29 | * 30 | * @param instance 31 | * @param fieldName 32 | * @return 返回空则可能值不存在,或变量不存在 33 | */ 34 | public static Object getValue(Object instance, String fieldName) { 35 | Field field = getField(instance.getClass(), fieldName); 36 | if (field == null) { 37 | return null; 38 | } 39 | // 参数值为true,禁用访问控制检查 40 | field.setAccessible(true); 41 | try { 42 | return field.get(instance); 43 | } catch (Throwable e) { 44 | return null; 45 | } 46 | } 47 | 48 | /** 49 | * 获取静态变量的值 50 | * 51 | * @param clazz 52 | * @param fieldName 53 | * @return 返回空则可能值不存在,或变量不存在 54 | */ 55 | public static Object getValue(Class clazz, String fieldName) { 56 | Field field = getField(clazz, fieldName); 57 | if (field == null) { 58 | return null; 59 | } 60 | // 参数值为true,禁用访问控制检查 61 | field.setAccessible(true); 62 | try { 63 | return field.get(null); 64 | } catch (Throwable e) { 65 | return null; 66 | } 67 | } 68 | 69 | /** 70 | * 获取类里的方法 71 | * 72 | * @param thisClass 73 | * @param methodName 74 | * @param parameterTypes 75 | * @return 76 | * @throws NoSuchMethodException 77 | */ 78 | public static Method getMethod(Class thisClass, String methodName, Class[] parameterTypes) { 79 | if (thisClass == null) { 80 | return null; 81 | } 82 | 83 | try { 84 | Method method = thisClass.getDeclaredMethod(methodName, parameterTypes); 85 | if (method == null) { 86 | return null; 87 | } 88 | method.setAccessible(true); 89 | return method; 90 | } catch (Throwable e) { 91 | return null; 92 | } 93 | } 94 | 95 | /** 96 | * 执行对象里的方法 97 | * 98 | * @param instance 99 | * @param methodName 100 | * @param args 方法参数 101 | * @return 返回值 102 | * @throws Throwable 方法不存在或者执行失败跑出异常 103 | */ 104 | public static Object invokeMethod(Object instance, String methodName, Object... args) throws Throwable { 105 | Class[] parameterTypes = null; 106 | if (args != null) { 107 | parameterTypes = new Class[args.length]; 108 | for (int i = 0; i < args.length; i++) { 109 | if (args[i] != null) { 110 | parameterTypes[i] = args[i].getClass(); 111 | } 112 | } 113 | } 114 | Method method = getMethod(instance.getClass(), methodName, parameterTypes); 115 | return method.invoke(instance, args); 116 | } 117 | 118 | /** 119 | * 执行静态方法 120 | * 121 | * @param clazz 122 | * @param methodName 123 | * @param args 方法参数 124 | * @return 返回值 125 | * @throws Throwable 方法不存在或者执行失败跑出异常 126 | */ 127 | public static Object invokeMethod(Class clazz, String methodName, Object... args) throws Throwable { 128 | Class[] parameterTypes = null; 129 | if (args != null) { 130 | parameterTypes = new Class[args.length]; 131 | for (int i = 0; i < args.length; i++) { 132 | if (args[i] != null) { 133 | parameterTypes[i] = args[i].getClass(); 134 | } 135 | } 136 | } 137 | Method method = getMethod(clazz, methodName, parameterTypes); 138 | return method.invoke(clazz, args); 139 | } 140 | } 141 | -------------------------------------------------------------------------------- /app/src/main/java/com/lemon/customview/utils/ResourceUtil.java: -------------------------------------------------------------------------------- 1 | package com.lemon.customview.utils; 2 | 3 | import android.content.Context; 4 | import android.content.res.AssetManager; 5 | import android.content.res.Resources; 6 | import android.graphics.Typeface; 7 | import android.util.Log; 8 | 9 | import androidx.annotation.ColorRes; 10 | import androidx.annotation.DimenRes; 11 | import androidx.core.content.ContextCompat; 12 | 13 | import java.util.HashMap; 14 | import java.util.Map; 15 | 16 | /** 17 | * Created by DF on 2017/9/6. 18 | */ 19 | 20 | public class ResourceUtil { 21 | 22 | private static final float DENSITY = Resources.getSystem().getDisplayMetrics().density; 23 | 24 | public static int dp2Px(int dp) { 25 | return Math.round(dp * DENSITY); 26 | } 27 | 28 | /** 29 | * dp转化成px 30 | * 31 | * @param context 32 | * @param dpValue 33 | * @return 34 | */ 35 | public static int dp2px(Context context, float dpValue) { 36 | final float scale = context.getResources().getDisplayMetrics().density; 37 | return (int) (dpValue * scale + 0.5f); 38 | } 39 | 40 | /** 41 | * px转成dp 42 | * 43 | * @param context 44 | * @param pxValue 45 | * @return 46 | */ 47 | public static int px2dp(Context context, float pxValue) { 48 | final float scale = context.getResources().getDisplayMetrics().density; 49 | return (int) (pxValue / scale + 0.5f); 50 | } 51 | 52 | /** 53 | * px转成sp 54 | * 55 | * @param context 56 | * @param pxValue 57 | * @return 58 | */ 59 | public static int px2sp(Context context, float pxValue) { 60 | final float scale = context.getResources().getDisplayMetrics().density; 61 | return (int) (pxValue / scale + 0.5f); 62 | } 63 | 64 | 65 | public static int sp2px(Context context, float spValue) { 66 | final float scale = context.getResources().getDisplayMetrics().density; 67 | return (int) (spValue * scale + 0.5f); 68 | } 69 | 70 | public static int getColor(Context context, @ColorRes int resId) { 71 | return ContextCompat.getColor(context, resId); 72 | } 73 | 74 | public static float getDimension(Context context, @DimenRes int resId) { 75 | return context.getResources().getDimension(resId); 76 | } 77 | 78 | 79 | 80 | private static ResourceUtil instance; 81 | 82 | private AssetManager assetManager; 83 | 84 | private Map fonts; 85 | 86 | private ResourceUtil(AssetManager assetManager) { 87 | this.assetManager = assetManager; 88 | this.fonts = new HashMap<>(); 89 | } 90 | 91 | public static ResourceUtil getInstance(AssetManager assetManager) { 92 | if (instance == null) { 93 | instance = new ResourceUtil(assetManager); 94 | } 95 | return instance; 96 | } 97 | 98 | public Typeface getFont(String asset) { 99 | if (fonts.containsKey(asset)) 100 | return fonts.get(asset); 101 | 102 | Typeface font = null; 103 | 104 | try { 105 | font = Typeface.createFromAsset(assetManager, asset); 106 | fonts.put(asset, font); 107 | } catch (RuntimeException e) { 108 | Log.e("TAG", "getFont: Can't create font from asset.", e); 109 | } 110 | 111 | return font; 112 | } 113 | 114 | } 115 | -------------------------------------------------------------------------------- /app/src/main/java/com/lemon/customview/utils/Util.java: -------------------------------------------------------------------------------- 1 | package com.lemon.customview.utils; 2 | 3 | import android.content.Context; 4 | import android.content.SharedPreferences; 5 | 6 | import com.lemon.customview.model.CharacterDiffResult; 7 | 8 | import java.io.Closeable; 9 | import java.util.ArrayList; 10 | import java.util.HashSet; 11 | import java.util.List; 12 | import java.util.Set; 13 | 14 | public class Util { 15 | 16 | public static int getScreenWidth(Context context) { 17 | return context.getResources().getDisplayMetrics().widthPixels; 18 | } 19 | 20 | public static int getScreenHeight(Context context) { 21 | return context.getResources().getDisplayMetrics().heightPixels; 22 | } 23 | 24 | public static int dp2px(Context context, float dp) { 25 | return (int) (context.getResources().getDisplayMetrics().density * dp + 0.5f); 26 | } 27 | 28 | public static void saveProperty(SharedPreferences sharedPreferences, String key, int value) { 29 | SharedPreferences.Editor editor = sharedPreferences.edit(); 30 | editor.putInt(key, value); 31 | editor.apply(); 32 | } 33 | 34 | public static void saveProperty(SharedPreferences sharedPreferences, String key, boolean value) { 35 | SharedPreferences.Editor editor = sharedPreferences.edit(); 36 | editor.putBoolean(key, value); 37 | editor.apply(); 38 | } 39 | 40 | public static void saveProperty(SharedPreferences sharedPreferences, String key, String value) { 41 | SharedPreferences.Editor editor = sharedPreferences.edit(); 42 | editor.putString(key, value); 43 | editor.apply(); 44 | } 45 | 46 | public static void clearProperties(SharedPreferences sharedPreferences) { 47 | SharedPreferences.Editor editor = sharedPreferences.edit(); 48 | editor.clear(); 49 | editor.apply(); 50 | } 51 | 52 | public static void closeQuietly(Closeable closeable) { 53 | if (closeable != null) { 54 | try { 55 | closeable.close(); 56 | } catch (RuntimeException rethrown) { 57 | throw rethrown; 58 | } catch (Exception ignored) { 59 | } 60 | } 61 | } 62 | 63 | public static List diff(CharSequence oldText, CharSequence newText) { 64 | 65 | List differentList = new ArrayList<>(); 66 | Set skip = new HashSet<>(); 67 | 68 | for (int i = 0; i < oldText.length(); i++) { 69 | char c = oldText.charAt(i); 70 | for (int j = 0; j < newText.length(); j++) { 71 | if (!skip.contains(j) && c == newText.charAt(j)) { 72 | skip.add(j); 73 | CharacterDiffResult different = new CharacterDiffResult(); 74 | different.c = c; 75 | different.fromIndex = i; 76 | different.moveIndex = j; 77 | differentList.add(different); 78 | break; 79 | } 80 | } 81 | } 82 | return differentList; 83 | } 84 | 85 | public static int needMove(int index, List differentList) { 86 | for (CharacterDiffResult different : differentList) { 87 | if (different.fromIndex == index) { 88 | return different.moveIndex; 89 | } 90 | } 91 | return -1; 92 | } 93 | 94 | public static boolean stayHere(int index, List differentList) { 95 | for (CharacterDiffResult different : differentList) { 96 | if (different.moveIndex == index) { 97 | return true; 98 | } 99 | } 100 | return false; 101 | } 102 | 103 | /** 104 | * @return 105 | */ 106 | public static float getOffset(int from, int move, float progress, float startX, float oldStartX, float[] gaps, float[] oldGaps) { 107 | 108 | float dist = startX; 109 | for (int i = 0; i < move; i++) { 110 | dist += gaps[i]; 111 | } 112 | 113 | float cur = oldStartX; 114 | for (int i = 0; i < from; i++) { 115 | cur += oldGaps[i]; 116 | } 117 | 118 | return cur + (dist - cur) * progress; 119 | 120 | } 121 | 122 | } 123 | -------------------------------------------------------------------------------- /app/src/main/java/com/lemon/customview/widget/ExpandableTextView/FormatData.java: -------------------------------------------------------------------------------- 1 | package com.lemon.customview.widget.ExpandableTextView; 2 | 3 | import java.util.List; 4 | 5 | public class FormatData { 6 | 7 | private String formatedContent; 8 | private List positionDatas; 9 | 10 | public String getFormatedContent() { 11 | return formatedContent; 12 | } 13 | 14 | public void setFormatedContent(String formatedContent) { 15 | this.formatedContent = formatedContent; 16 | } 17 | 18 | public List getPositionDatas() { 19 | return positionDatas; 20 | } 21 | 22 | public void setPositionDatas(List positionDatas) { 23 | this.positionDatas = positionDatas; 24 | } 25 | 26 | public static class PositionData { 27 | private int start; 28 | private int end; 29 | private String url; 30 | private LinkType type; 31 | //自定义法规则的aim 32 | private String selfAim; 33 | //自定义规则的内容 34 | private String selfContent; 35 | 36 | public String getSelfAim() { 37 | return selfAim; 38 | } 39 | 40 | public void setSelfAim(String selfAim) { 41 | this.selfAim = selfAim; 42 | } 43 | 44 | public String getSelfContent() { 45 | return selfContent; 46 | } 47 | 48 | public void setSelfContent(String selfContent) { 49 | this.selfContent = selfContent; 50 | } 51 | 52 | public LinkType getType() { 53 | return type; 54 | } 55 | 56 | public void setType(LinkType type) { 57 | this.type = type; 58 | } 59 | 60 | public String getUrl() { 61 | return url; 62 | } 63 | 64 | public void setUrl(String url) { 65 | this.url = url; 66 | } 67 | 68 | public PositionData(int start, int end, String url, LinkType type) { 69 | this.start = start; 70 | this.end = end; 71 | this.url = url; 72 | this.type = type; 73 | } 74 | 75 | public PositionData(int start, int end, String selfAim,String selfContent, LinkType type) { 76 | this.start = start; 77 | this.end = end; 78 | this.selfAim = selfAim; 79 | this.selfContent = selfContent; 80 | this.type = type; 81 | } 82 | 83 | public int getStart() { 84 | return start; 85 | } 86 | 87 | public void setStart(int start) { 88 | this.start = start; 89 | } 90 | 91 | public int getEnd() { 92 | return end; 93 | } 94 | 95 | public void setEnd(int end) { 96 | this.end = end; 97 | } 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /app/src/main/java/com/lemon/customview/widget/ExpandableTextView/LinkType.java: -------------------------------------------------------------------------------- 1 | package com.lemon.customview.widget.ExpandableTextView; 2 | 3 | public enum LinkType { 4 | //普通链接 5 | LINK_TYPE, 6 | //@用户 7 | MENTION_TYPE, 8 | //自定义规则 9 | SELF 10 | } 11 | -------------------------------------------------------------------------------- /app/src/main/java/com/lemon/customview/widget/ExpandableTextView/StatusType.java: -------------------------------------------------------------------------------- 1 | package com.lemon.customview.widget.ExpandableTextView; 2 | 3 | public enum StatusType { 4 | //展开 5 | STATUS_EXPAND, 6 | //收起 7 | STATUS_CONTRACT 8 | } 9 | -------------------------------------------------------------------------------- /app/src/main/java/com/lemon/customview/widget/Heart/HeartType.java: -------------------------------------------------------------------------------- 1 | package com.lemon.customview.widget.Heart; 2 | 3 | public interface HeartType { 4 | 5 | int BLUE = 0x00; 6 | int GREEN = 0x01; 7 | int YELLOW = 0x02; 8 | int PINK = 0x03; 9 | int BROWN = 0x04; 10 | int PURPLE = 0x05; 11 | int RED = 0x06; 12 | 13 | } 14 | -------------------------------------------------------------------------------- /app/src/main/java/com/lemon/customview/widget/Heart/NewHeart.java: -------------------------------------------------------------------------------- 1 | package com.lemon.customview.widget.Heart; 2 | 3 | public class NewHeart { 4 | //坐标点 5 | public float x; 6 | public float y; 7 | //进度(0~1) 8 | public float progress; 9 | //当前心集合的索引 10 | public int index; 11 | } 12 | -------------------------------------------------------------------------------- /app/src/main/java/com/lemon/customview/widget/Heart/SimpleSurfaceView.java: -------------------------------------------------------------------------------- 1 | package com.lemon.customview.widget.Heart; 2 | 3 | import android.content.Context; 4 | import android.graphics.Canvas; 5 | import android.graphics.Paint; 6 | import android.util.AttributeSet; 7 | import android.view.SurfaceHolder; 8 | import android.view.SurfaceView; 9 | 10 | /** 11 | * Created by DF on 2017/9/11. 12 | */ 13 | 14 | public class SimpleSurfaceView extends SurfaceView implements SurfaceHolder.Callback, Runnable { 15 | 16 | // 子线程标志位 17 | private boolean isRunning; 18 | 19 | //画笔 20 | private Paint mPaint; 21 | 22 | public SimpleSurfaceView(Context context) { 23 | super(context, null); 24 | } 25 | 26 | public SimpleSurfaceView(Context context, AttributeSet attrs) { 27 | super(context, attrs); 28 | init(); 29 | } 30 | 31 | 32 | private void init() { 33 | mPaint = new Paint(); 34 | mPaint.setAntiAlias(true); 35 | //... 36 | getHolder().addCallback(this); 37 | setFocusable(true); 38 | setFocusableInTouchMode(true); 39 | this.setKeepScreenOn(true); 40 | } 41 | 42 | @Override 43 | public void surfaceCreated(SurfaceHolder holder) { 44 | isRunning = true; 45 | new Thread(this).start(); 46 | } 47 | 48 | @Override 49 | public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { 50 | } 51 | 52 | @Override 53 | public void surfaceDestroyed(SurfaceHolder holder) { 54 | isRunning = false; 55 | } 56 | 57 | @Override 58 | public void run() { 59 | while (isRunning) { 60 | Canvas canvas = null; 61 | try { 62 | canvas = getHolder().lockCanvas(); 63 | if (canvas != null) { 64 | // draw something 65 | drawSomething(canvas); 66 | } 67 | } catch (Exception e) { 68 | e.printStackTrace(); 69 | } finally { 70 | if (canvas != null) { 71 | getHolder().unlockCanvasAndPost(canvas); 72 | } 73 | } 74 | } 75 | } 76 | 77 | /** 78 | * draw something 79 | * 80 | * @param canvas 81 | */ 82 | private void drawSomething(Canvas canvas) { 83 | 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /app/src/main/java/com/lemon/customview/widget/KeyboardLayout.java: -------------------------------------------------------------------------------- 1 | package com.lemon.customview.widget; 2 | 3 | import android.content.Context; 4 | import android.graphics.drawable.Drawable; 5 | import androidx.core.content.ContextCompat; 6 | import android.util.AttributeSet; 7 | import android.view.View; 8 | import android.view.ViewGroup; 9 | 10 | public class KeyboardLayout extends ViewGroup implements View.OnClickListener{ 11 | 12 | private String[] keys = new String[]{"1", "2", "3", "4", "5", "6", "7", "8", "9", "", "0", "-1"}; 13 | 14 | // int keyViewHeight 15 | 16 | public KeyboardLayout(Context context) { 17 | super(context); 18 | } 19 | 20 | public KeyboardLayout(Context context, AttributeSet attrs) { 21 | super(context, attrs); 22 | } 23 | 24 | public KeyboardLayout(Context context, AttributeSet attrs, int defStyleAttr) { 25 | super(context, attrs, defStyleAttr); 26 | } 27 | 28 | @Override 29 | public void onClick(View v) { 30 | 31 | } 32 | 33 | @Override 34 | protected void onLayout(boolean changed, int l, int t, int r, int b) { 35 | 36 | } 37 | 38 | private Drawable getDrawable(int resId){ 39 | return ContextCompat.getDrawable(getContext(), resId); 40 | } 41 | 42 | private int getColor(int id){ 43 | return ContextCompat.getColor(getContext(), id); 44 | } 45 | 46 | private int getMeasure(int size){ 47 | return MeasureSpec.makeMeasureSpec(size, MeasureSpec.EXACTLY); 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /app/src/main/java/com/lemon/customview/widget/KeyboardView.java: -------------------------------------------------------------------------------- 1 | package com.lemon.customview.widget; 2 | 3 | import android.content.Context; 4 | import androidx.recyclerview.widget.GridLayoutManager; 5 | import androidx.recyclerview.widget.RecyclerView; 6 | import android.util.AttributeSet; 7 | import android.view.View; 8 | import android.view.ViewGroup; 9 | import android.widget.RelativeLayout; 10 | import android.widget.TextView; 11 | 12 | import com.lemon.customview.R; 13 | import com.lemon.customview.other.KeyboardDecoration; 14 | import com.lemon.customview.utils.ResourceUtil; 15 | 16 | public class KeyboardView extends RelativeLayout { 17 | 18 | private MyAdapter mAdapter; 19 | private String[] keys = new String[]{"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "0", "完成"}; 20 | private static final int TYPE_COMMON = 0x0001; 21 | private static final int TYPE_DELETE = 0x0002; 22 | 23 | private OnItemClickListener mOnItemClickListener; 24 | 25 | public KeyboardView(Context context) { 26 | this(context, null); 27 | } 28 | 29 | public KeyboardView(Context context, AttributeSet attrs) { 30 | this(context, attrs, 0); 31 | } 32 | 33 | public KeyboardView(Context context, AttributeSet attrs, int defStyleAttr) { 34 | super(context, attrs, defStyleAttr); 35 | init(); 36 | } 37 | 38 | private void init() { 39 | View view = View.inflate(getContext(), R.layout.layout_keyboard, null); 40 | addView(view, new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)); 41 | RecyclerView rv = (RecyclerView) findViewById(R.id.recycler_view); 42 | mAdapter = new MyAdapter(); 43 | rv.setLayoutManager(new GridLayoutManager(getContext(), 3)); 44 | rv.addItemDecoration(new KeyboardDecoration(3, ResourceUtil.dp2px(getContext(), 5f), true)); 45 | rv.setAdapter(mAdapter); 46 | } 47 | 48 | private static class MyViewHolder extends RecyclerView.ViewHolder { 49 | 50 | MyViewHolder(View itemView) { 51 | super(itemView); 52 | } 53 | } 54 | 55 | public void setOnItemClickListener(OnItemClickListener listener) { 56 | this.mOnItemClickListener = listener; 57 | } 58 | 59 | private class MyAdapter extends RecyclerView.Adapter { 60 | 61 | @Override 62 | public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 63 | View itemView; 64 | switch (viewType) { 65 | case TYPE_DELETE: 66 | itemView = View.inflate(parent.getContext(), R.layout.delete_key, null); 67 | break; 68 | default: 69 | itemView = View.inflate(parent.getContext(), R.layout.common_key, null); 70 | break; 71 | } 72 | return new MyViewHolder(itemView); 73 | } 74 | 75 | @Override 76 | public void onBindViewHolder(final MyViewHolder holder, int position) { 77 | switch (holder.getItemViewType()) { 78 | case TYPE_COMMON: 79 | ((TextView) holder.itemView.findViewById(R.id.tv_key)).setText(keys[position]); 80 | holder.itemView.findViewById(R.id.ll_key).setOnClickListener(new OnClickListener() { 81 | @Override 82 | public void onClick(View v) { 83 | if (mOnItemClickListener != null) { 84 | mOnItemClickListener.onItemClick(holder.getAdapterPosition() + 1); 85 | } 86 | } 87 | }); 88 | break; 89 | case TYPE_DELETE: 90 | holder.itemView.findViewById(R.id.ll_delete).setOnClickListener(new OnClickListener() { 91 | @Override 92 | public void onClick(View v) { 93 | if (mOnItemClickListener != null) { 94 | mOnItemClickListener.onItemClick(holder.getAdapterPosition() + 1); 95 | } 96 | } 97 | }); 98 | break; 99 | } 100 | } 101 | 102 | @Override 103 | public int getItemCount() { 104 | return keys.length; 105 | } 106 | 107 | @Override 108 | public int getItemViewType(int position) { 109 | if (position == 9) 110 | return TYPE_DELETE; 111 | else 112 | return TYPE_COMMON; 113 | } 114 | } 115 | 116 | public interface OnItemClickListener { 117 | void onItemClick(int position); 118 | } 119 | 120 | } 121 | -------------------------------------------------------------------------------- /app/src/main/java/com/lemon/customview/widget/Roll3DLinearLayout.java: -------------------------------------------------------------------------------- 1 | package com.lemon.customview.widget; 2 | 3 | import android.content.Context; 4 | import android.graphics.Bitmap; 5 | import android.graphics.drawable.BitmapDrawable; 6 | import android.util.AttributeSet; 7 | import android.view.View; 8 | import android.widget.Button; 9 | import android.widget.LinearLayout; 10 | import android.widget.TextView; 11 | 12 | import com.lemon.customview.R; 13 | 14 | public class Roll3DLinearLayout extends LinearLayout implements View.OnClickListener{ 15 | 16 | private Context context; 17 | private Roll3DView roll3DView; 18 | private TextView titleTv; 19 | 20 | public Roll3DLinearLayout(Context context) { 21 | this(context, null); 22 | } 23 | 24 | public Roll3DLinearLayout(Context context, AttributeSet attrs) { 25 | this(context, attrs, 0); 26 | } 27 | 28 | public Roll3DLinearLayout(Context context, AttributeSet attrs, int defStyleAttr) { 29 | super(context, attrs, defStyleAttr); 30 | init(context); 31 | } 32 | 33 | private void init(Context context) { 34 | this.context = context; 35 | View.inflate(context, R.layout.demo_item, this); 36 | 37 | Button toLeft = findViewById(R.id.left_btn); 38 | Button toRight = findViewById(R.id.right_btn); 39 | Button toUp = findViewById(R.id.roll_up_btn); 40 | Button toDown = findViewById(R.id.roll_down_btn); 41 | roll3DView = findViewById(R.id.three_d_view); 42 | titleTv = findViewById(R.id.title_tv); 43 | 44 | 45 | toLeft.setOnClickListener(this); 46 | toRight.setOnClickListener(this); 47 | toUp.setOnClickListener(this); 48 | toDown.setOnClickListener(this); 49 | 50 | BitmapDrawable bgDrawable1 = (BitmapDrawable) getResources().getDrawable(R.drawable.img1); 51 | BitmapDrawable bgDrawable2 = (BitmapDrawable) getResources().getDrawable(R.drawable.img2); 52 | BitmapDrawable bgDrawable3 = (BitmapDrawable) getResources().getDrawable(R.drawable.img3); 53 | BitmapDrawable bgDrawable4 = (BitmapDrawable) getResources().getDrawable(R.drawable.img4); 54 | BitmapDrawable bgDrawable5 = (BitmapDrawable) getResources().getDrawable(R.drawable.img5); 55 | 56 | 57 | Bitmap bitmap1 = bgDrawable1.getBitmap(); 58 | Bitmap bitmap2 = bgDrawable2.getBitmap(); 59 | Bitmap bitmap3 = bgDrawable3.getBitmap(); 60 | Bitmap bitmap4 = bgDrawable4.getBitmap(); 61 | Bitmap bitmap5 = bgDrawable5.getBitmap(); 62 | 63 | roll3DView.addImageBitmap(bitmap1); 64 | roll3DView.addImageBitmap(bitmap2); 65 | roll3DView.addImageBitmap(bitmap3); 66 | roll3DView.addImageBitmap(bitmap4); 67 | roll3DView.addImageBitmap(bitmap5); 68 | 69 | roll3DView.setRollMode(Roll3DView.RollMode.Whole3D); 70 | } 71 | 72 | @Override 73 | public void onClick(View v) { 74 | switch (v.getId()) { 75 | case R.id.left_btn: 76 | roll3DView.setRollDirection(0); 77 | roll3DView.toPre(); 78 | break; 79 | case R.id.right_btn: 80 | roll3DView.setRollDirection(0); 81 | roll3DView.toNext(); 82 | break; 83 | case R.id.roll_up_btn: 84 | roll3DView.setRollDirection(1); 85 | roll3DView.toPre(); 86 | break; 87 | case R.id.roll_down_btn: 88 | roll3DView.setRollDirection(1); 89 | roll3DView.toNext(); 90 | break; 91 | } 92 | } 93 | 94 | public Roll3DView getRoll3DView() { 95 | return roll3DView; 96 | } 97 | 98 | public void setTitleText(String titleText) { 99 | titleTv.setText(titleText); 100 | } 101 | 102 | } 103 | -------------------------------------------------------------------------------- /app/src/main/java/com/lemon/customview/widget/htextview/animatetext/EvaporateText.java: -------------------------------------------------------------------------------- 1 | package com.lemon.customview.widget.htextview.animatetext; 2 | 3 | import android.animation.ValueAnimator; 4 | import android.graphics.Canvas; 5 | import android.graphics.Rect; 6 | import android.view.animation.AccelerateDecelerateInterpolator; 7 | 8 | import com.lemon.customview.utils.Util; 9 | 10 | public class EvaporateText extends HText { 11 | 12 | float charTime = 300; 13 | int mostCount = 20; 14 | private int mTextHeight; 15 | private float progress; 16 | 17 | @Override 18 | protected void initVariables() { 19 | } 20 | 21 | @Override 22 | protected void animateStart(CharSequence text) { 23 | int n = mText.length(); 24 | n = n <= 0 ? 1 : n; 25 | long duration = (long) (charTime + charTime / mostCount * (n - 1)); 26 | ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, duration).setDuration(duration); 27 | valueAnimator.setInterpolator(new AccelerateDecelerateInterpolator()); 28 | valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { 29 | @Override 30 | public void onAnimationUpdate(ValueAnimator animation) { 31 | progress = (float) animation.getAnimatedValue(); 32 | mHTextView.invalidate(); 33 | } 34 | }); 35 | valueAnimator.start(); 36 | } 37 | 38 | @Override 39 | protected void animatePrepare(CharSequence text) { 40 | Rect bounds = new Rect(); 41 | mPaint.getTextBounds(mText.toString(), 0, mText.length(), bounds); 42 | mTextHeight = bounds.height(); 43 | } 44 | 45 | @Override 46 | protected void drawFrame(Canvas canvas) { 47 | 48 | } 49 | 50 | @Override 51 | public void onDraw(Canvas canvas) { 52 | float offset = startX; 53 | float oldOffset = oldStartX; 54 | int maxLength = Math.max(mText.length(), mOldText.length()); 55 | for (int i = 0; i < maxLength; i++) { 56 | // draw old text 57 | if (i < mOldText.length()) { 58 | float pp = progress / (charTime + charTime / mostCount * (mText.length() - 1)); 59 | mOldPaint.setTextSize(mTextSize); 60 | int move = Util.needMove(i, differentList); 61 | if (move != -1) { 62 | mOldPaint.setAlpha(255); 63 | float p = pp * 2f; 64 | p = p > 1 ? 1 : p; 65 | float distX = Util.getOffset(i, move, p, startX, oldStartX, gaps, oldGaps); 66 | canvas.drawText(mOldText.charAt(i) + "", 0, 1, distX, startY, mOldPaint); 67 | } else { 68 | mOldPaint.setAlpha((int) ((1 - pp) * 255)); 69 | float y = startY - pp * mTextHeight; 70 | float width = mOldPaint.measureText(mOldText.charAt(i) + ""); 71 | canvas.drawText(mOldText.charAt(i) + "", 0, 1, oldOffset + (oldGaps[i] - width) / 2, y, mOldPaint); 72 | } 73 | oldOffset += oldGaps[i]; 74 | } 75 | // draw new text 76 | if (i < mText.length()) { 77 | if (!Util.stayHere(i, differentList)) { 78 | int alpha = (int) (255f / charTime * (progress - charTime * i / mostCount)); 79 | alpha = alpha > 255 ? 255 : alpha; 80 | alpha = alpha < 0 ? 0 : alpha; 81 | mPaint.setAlpha(alpha); 82 | mPaint.setTextSize(mTextSize); 83 | float pp = progress / (charTime + charTime / mostCount * (mText.length() - 1)); 84 | float y = mTextHeight + startY - pp * mTextHeight; 85 | 86 | float width = mPaint.measureText(mText.charAt(i) + ""); 87 | canvas.drawText(mText.charAt(i) + "", 0, 1, offset + (gaps[i] - width) / 2, y, mPaint); 88 | } 89 | offset += gaps[i]; 90 | } 91 | } 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /app/src/main/java/com/lemon/customview/widget/htextview/animatetext/HText.java: -------------------------------------------------------------------------------- 1 | package com.lemon.customview.widget.htextview.animatetext; 2 | 3 | import android.graphics.Canvas; 4 | import android.graphics.Paint; 5 | import android.util.AttributeSet; 6 | 7 | import com.lemon.customview.model.CharacterDiffResult; 8 | import com.lemon.customview.utils.Util; 9 | import com.lemon.customview.widget.htextview.HTextView; 10 | 11 | import java.util.ArrayList; 12 | import java.util.List; 13 | 14 | public abstract class HText implements IHText { 15 | 16 | protected Paint mPaint, mOldPaint; 17 | 18 | /** 19 | * the gap between characters 20 | */ 21 | protected float[] gaps = new float[100]; 22 | protected float[] oldGaps = new float[100]; 23 | 24 | /** 25 | * current text size 26 | */ 27 | protected float mTextSize; 28 | 29 | protected CharSequence mText; 30 | protected CharSequence mOldText; 31 | 32 | protected List differentList = new ArrayList<>(); 33 | 34 | protected float oldStartX = 0; 35 | protected float startX = 0; 36 | protected float startY = 0; 37 | 38 | protected HTextView mHTextView; 39 | 40 | 41 | @Override public void init(HTextView hTextView, AttributeSet attrs, int defStyle) { 42 | mHTextView = hTextView; 43 | mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); 44 | mPaint.setColor(mHTextView.getCurrentTextColor()); 45 | mPaint.setStyle(Paint.Style.FILL); 46 | mPaint.setTypeface(mHTextView.getTypeface()); 47 | 48 | mOldPaint = new Paint(Paint.ANTI_ALIAS_FLAG); 49 | mOldPaint.setColor(mHTextView.getCurrentTextColor()); 50 | mOldPaint.setStyle(Paint.Style.FILL); 51 | mOldPaint.setTypeface(mHTextView.getTypeface()); 52 | 53 | mText = mHTextView.getText(); 54 | mOldText = mHTextView.getText(); 55 | 56 | mTextSize = mHTextView.getTextSize(); 57 | 58 | initVariables(); 59 | mHTextView.postDelayed(new Runnable() { 60 | @Override public void run() { 61 | prepareAnimate(); 62 | } 63 | },50); 64 | } 65 | 66 | @Override public void animateText(CharSequence text) { 67 | mHTextView.setText(text); 68 | mOldText = mText; 69 | mText = text; 70 | prepareAnimate(); 71 | animatePrepare(text); 72 | animateStart(text); 73 | } 74 | 75 | @Override public void onDraw(Canvas canvas) { 76 | mPaint.setColor(mHTextView.getCurrentTextColor()); 77 | mOldPaint.setColor(mHTextView.getCurrentTextColor()); 78 | drawFrame(canvas); 79 | } 80 | 81 | public void setTextColor(int color){ 82 | mHTextView.setTextColor(color); 83 | } 84 | 85 | private void prepareAnimate() { 86 | mTextSize = mHTextView.getTextSize(); 87 | mPaint.setTextSize(mTextSize); 88 | for (int i = 0; i < mText.length(); i++) { 89 | gaps[i] = mPaint.measureText(mText.charAt(i) + ""); 90 | } 91 | 92 | mOldPaint.setTextSize(mTextSize); 93 | for (int i = 0; i < mOldText.length(); i++) { 94 | oldGaps[i] = mOldPaint.measureText(mOldText.charAt(i) + ""); 95 | } 96 | 97 | oldStartX = (mHTextView.getMeasuredWidth() - mHTextView.getCompoundPaddingLeft() - mHTextView.getPaddingLeft() - mOldPaint 98 | .measureText(mOldText.toString())) / 2f; 99 | startX = (mHTextView.getMeasuredWidth() - mHTextView.getCompoundPaddingLeft() - mHTextView.getPaddingLeft() - mPaint 100 | .measureText(mText.toString())) / 2f; 101 | startY = mHTextView.getBaseline(); 102 | 103 | differentList.clear(); 104 | differentList.addAll(Util.diff(mOldText, mText)); 105 | } 106 | 107 | public void reset(CharSequence text) { 108 | animatePrepare(text); 109 | mHTextView.invalidate(); 110 | } 111 | 112 | protected abstract void initVariables(); 113 | protected abstract void animateStart(CharSequence text); 114 | protected abstract void animatePrepare(CharSequence text); 115 | protected abstract void drawFrame(Canvas canvas); 116 | 117 | } 118 | -------------------------------------------------------------------------------- /app/src/main/java/com/lemon/customview/widget/htextview/animatetext/IHText.java: -------------------------------------------------------------------------------- 1 | package com.lemon.customview.widget.htextview.animatetext; 2 | 3 | import android.graphics.Canvas; 4 | import android.util.AttributeSet; 5 | 6 | import com.lemon.customview.widget.htextview.HTextView; 7 | 8 | public interface IHText { 9 | void init(HTextView hTextView, AttributeSet attrs, int defStyle); 10 | 11 | void animateText(CharSequence text); 12 | 13 | void onDraw(Canvas canvas); 14 | 15 | void reset(CharSequence text); 16 | } 17 | -------------------------------------------------------------------------------- /app/src/main/java/com/lemon/customview/widget/htextview/animatetext/RainBowText.java: -------------------------------------------------------------------------------- 1 | package com.lemon.customview.widget.htextview.animatetext; 2 | 3 | import android.graphics.Canvas; 4 | import android.graphics.LinearGradient; 5 | import android.graphics.Matrix; 6 | import android.graphics.Shader; 7 | 8 | import com.lemon.customview.utils.ResourceUtil; 9 | 10 | public class RainBowText extends HText { 11 | private int mTextWidth; 12 | private LinearGradient mLinearGradient; 13 | private Matrix mMatrix; 14 | private float mTranslate; 15 | private int dx; 16 | private int[] colors = 17 | new int[]{0xFFFF2B22, 0xFFFF7F22, 0xFFEDFF22, 0xFF22FF22, 0xFF22F4FF, 0xFF2239FF, 0xFF5400F7}; 18 | 19 | @Override 20 | protected void initVariables() { 21 | mMatrix = new Matrix(); 22 | dx = ResourceUtil.dp2Px(7); 23 | } 24 | 25 | public void setColors(int colors[]) { 26 | this.colors = colors; 27 | } 28 | 29 | @Override 30 | protected void animateStart(CharSequence text) { 31 | 32 | mHTextView.invalidate(); 33 | } 34 | 35 | @Override 36 | protected void animatePrepare(CharSequence text) { 37 | mTextWidth = (int) mPaint.measureText(mText, 0, mText.length()); 38 | mTextWidth = Math.max(ResourceUtil.dp2Px(100), mTextWidth); 39 | if (mTextWidth > 0) { 40 | mLinearGradient = new LinearGradient(0, 0, mTextWidth, 0, 41 | colors, null, Shader.TileMode.MIRROR); 42 | mPaint.setShader(mLinearGradient); 43 | } 44 | } 45 | 46 | @Override 47 | protected void drawFrame(Canvas canvas) { 48 | if (mMatrix != null && mLinearGradient != null) { 49 | mTranslate += dx; 50 | mMatrix.setTranslate(mTranslate, 0); 51 | mLinearGradient.setLocalMatrix(mMatrix); 52 | canvas.drawText(mText, 0, mText.length(), startX, startY, mPaint); 53 | mHTextView.postInvalidateDelayed(100); 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /app/src/main/java/com/lemon/customview/widget/htextview/animatetext/ScaleText.java: -------------------------------------------------------------------------------- 1 | package com.lemon.customview.widget.htextview.animatetext; 2 | 3 | import android.animation.ValueAnimator; 4 | import android.graphics.Canvas; 5 | import android.view.animation.AccelerateDecelerateInterpolator; 6 | 7 | import com.lemon.customview.utils.Util; 8 | 9 | public class ScaleText extends HText { 10 | 11 | float mostCount = 20; 12 | float charTime = 400; 13 | private long duration; 14 | private float progress; 15 | 16 | @Override protected void initVariables() { 17 | 18 | } 19 | 20 | @Override protected void animateStart(CharSequence text) { 21 | int n = mText.length(); 22 | n = n <= 0 ? 1 : n; 23 | duration = (long) (charTime + charTime / mostCount * (n - 1)); 24 | ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, duration).setDuration(duration); 25 | valueAnimator.setInterpolator(new AccelerateDecelerateInterpolator()); 26 | valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { 27 | @Override public void onAnimationUpdate(ValueAnimator animation) { 28 | progress = (float) animation.getAnimatedValue(); 29 | mHTextView.invalidate(); 30 | } 31 | }); 32 | valueAnimator.start(); 33 | } 34 | 35 | @Override protected void animatePrepare(CharSequence text) { 36 | 37 | } 38 | 39 | @Override public void drawFrame(Canvas canvas) { 40 | float offset = startX; 41 | float oldOffset = oldStartX; 42 | 43 | int maxLength = Math.max(mText.length(), mOldText.length()); 44 | for (int i = 0; i < maxLength; i++) { 45 | // draw old text 46 | if (i < mOldText.length()) { 47 | float percent = progress / duration; 48 | int move = Util.needMove(i, differentList); 49 | if (move != -1) { 50 | mOldPaint.setTextSize(mTextSize); 51 | mOldPaint.setAlpha(255); 52 | float p = percent * 2f; 53 | p = p > 1 ? 1 : p; 54 | float distX = Util.getOffset(i, move, p, startX, oldStartX, gaps, oldGaps); 55 | canvas.drawText(mOldText.charAt(i) + "", 0, 1, distX, startY, mOldPaint); 56 | } else { 57 | mOldPaint.setAlpha((int) ((1 - percent) * 255)); 58 | mOldPaint.setTextSize(mTextSize * (1 - percent)); 59 | float width = mOldPaint.measureText(mOldText.charAt(i) + ""); 60 | canvas.drawText(mOldText.charAt(i) + "", 0, 1, oldOffset + (oldGaps[i] - width) / 2, startY, mOldPaint); 61 | } 62 | oldOffset += oldGaps[i]; 63 | } 64 | // draw new text 65 | if (i < mText.length()) { 66 | if (!Util.stayHere(i, differentList)) { 67 | int alpha = (int) (255f / charTime * (progress - charTime * i / mostCount)); 68 | if(alpha > 255) alpha = 255; 69 | if(alpha < 0) alpha = 0; 70 | 71 | float size = mTextSize * 1f / charTime * (progress - charTime * i / mostCount); 72 | if (size > mTextSize) size = mTextSize; 73 | if (size < 0) size = 0; 74 | mPaint.setAlpha(alpha); 75 | mPaint.setTextSize(size); 76 | float width = mPaint.measureText(mText.charAt(i) + ""); 77 | canvas.drawText(mText.charAt(i) + "", 0, 1, offset + (gaps[i] - width) / 2, startY, mPaint); 78 | } 79 | offset += gaps[i]; 80 | } 81 | } 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /app/src/main/java/com/lemon/customview/widget/htextview/animatetext/TyperText.java: -------------------------------------------------------------------------------- 1 | package com.lemon.customview.widget.htextview.animatetext; 2 | 3 | import android.graphics.Canvas; 4 | 5 | public class TyperText extends HText { 6 | private int currentLength; 7 | 8 | @Override 9 | protected void initVariables() { 10 | 11 | } 12 | 13 | @Override 14 | protected void animateStart(CharSequence text) { 15 | currentLength = 0; 16 | mHTextView.invalidate(); 17 | } 18 | 19 | @Override 20 | protected void animatePrepare(CharSequence text) { 21 | 22 | } 23 | 24 | @Override 25 | protected void drawFrame(Canvas canvas) { 26 | canvas.drawText(mText, 0, currentLength, startX, startY, mPaint); 27 | if (currentLength < mText.length()) { 28 | currentLength++; 29 | mHTextView.postInvalidateDelayed(100); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /app/src/main/java/com/lemon/customview/widget/new_path/BezierPraiseView.java: -------------------------------------------------------------------------------- 1 | package com.lemon.customview.widget.new_path; 2 | 3 | import android.annotation.SuppressLint; 4 | import android.content.Context; 5 | import android.os.Handler; 6 | import android.os.Message; 7 | import androidx.annotation.Nullable; 8 | import android.util.AttributeSet; 9 | import android.widget.FrameLayout; 10 | 11 | import java.util.Random; 12 | 13 | public class BezierPraiseView extends FrameLayout { 14 | 15 | private BezierPraiseAnimator mBezierPraiseAnimator; 16 | private Random mRandom; 17 | 18 | @SuppressLint("HandlerLeak") 19 | private Handler mHandler = new Handler() { 20 | @Override 21 | public void handleMessage(Message msg) { 22 | super.handleMessage(msg); 23 | if (getWidth() <= 0 || getHeight() <= 0) return; 24 | mBezierPraiseAnimator.startAnimation(mRandom.nextInt(getWidth()), mRandom.nextInt(getHeight())); 25 | mHandler.sendEmptyMessageDelayed(1, 200); 26 | } 27 | }; 28 | 29 | public BezierPraiseView(Context context) { 30 | this(context, null); 31 | } 32 | 33 | public BezierPraiseView(Context context, @Nullable AttributeSet attrs) { 34 | this(context, attrs, 0); 35 | } 36 | 37 | public BezierPraiseView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { 38 | super(context, attrs, defStyleAttr); 39 | mBezierPraiseAnimator = new BezierPraiseAnimator(this); 40 | mRandom = new Random(); 41 | } 42 | 43 | @Override 44 | public void onWindowFocusChanged(boolean hasWindowFocus) { 45 | super.onWindowFocusChanged(hasWindowFocus); 46 | if (hasWindowFocus) { 47 | mHandler.sendEmptyMessage(1); 48 | } else { 49 | mBezierPraiseAnimator.cancelAnimation(); 50 | mHandler.removeCallbacksAndMessages(null); 51 | } 52 | } 53 | 54 | @Override 55 | protected void onDetachedFromWindow() { 56 | super.onDetachedFromWindow(); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /app/src/main/java/com/lemon/customview/widget/new_path/MoBikeView.java: -------------------------------------------------------------------------------- 1 | package com.lemon.customview.widget.new_path; 2 | 3 | import android.content.Context; 4 | import android.graphics.Canvas; 5 | import androidx.annotation.NonNull; 6 | import androidx.annotation.Nullable; 7 | import android.util.AttributeSet; 8 | import android.widget.FrameLayout; 9 | 10 | public class MoBikeView extends FrameLayout { 11 | 12 | private MoBike mMobike; 13 | 14 | public MoBikeView(@NonNull Context context) { 15 | this(context, null); 16 | } 17 | 18 | public MoBikeView(@NonNull Context context, @Nullable AttributeSet attrs) { 19 | this(context, attrs, 0); 20 | } 21 | 22 | public MoBikeView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) { 23 | super(context, attrs, defStyleAttr); 24 | setWillNotDraw(false); 25 | mMobike = new MoBike(this); 26 | } 27 | 28 | @Override 29 | protected void onSizeChanged(int w, int h, int oldw, int oldh) { 30 | super.onSizeChanged(w, h, oldw, oldh); 31 | mMobike.onSizeChange(w, h); 32 | } 33 | 34 | @Override 35 | protected void onLayout(boolean changed, int left, int top, int right, int bottom) { 36 | super.onLayout(changed, left, top, right, bottom); 37 | mMobike.onLayout(changed); 38 | } 39 | 40 | @Override 41 | protected void onDraw(Canvas canvas) { 42 | super.onDraw(canvas); 43 | mMobike.onDraw(); 44 | } 45 | 46 | public MoBike getMobike() { 47 | return mMobike; 48 | } 49 | 50 | public void onSensorChanged(float x, float y) { 51 | mMobike.onSensorChanged(x, y); 52 | } 53 | 54 | public void onRandomChanged() { 55 | mMobike.onRandomChanged(); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /app/src/main/java/com/lemon/customview/widget/new_path/PraiseEvaluator.java: -------------------------------------------------------------------------------- 1 | package com.lemon.customview.widget.new_path; 2 | 3 | import android.animation.TypeEvaluator; 4 | import android.graphics.PointF; 5 | 6 | 7 | public class PraiseEvaluator implements TypeEvaluator { 8 | 9 | // 贝塞尔曲线的控制点 10 | private PointF controlF1; 11 | private PointF controlF2; 12 | 13 | public PraiseEvaluator(PointF controlF1) { 14 | this.controlF1 = controlF1; 15 | } 16 | 17 | public PraiseEvaluator(PointF controlF1, PointF controlF2) { 18 | this.controlF1 = controlF1; 19 | this.controlF2 = controlF2; 20 | } 21 | 22 | @Override 23 | public PointF evaluate(float time, PointF startValue, PointF endValue) { 24 | //估值 25 | float currentX = 0; 26 | float currentY = 0; 27 | if (controlF2 == null) { 28 | // 二阶贝塞尔曲线 29 | currentX = arithmeticProduct(1 - time, 2) * startValue.x 30 | + 2 * time * (1 - time) * controlF1.x 31 | + arithmeticProduct(time, 2) * endValue.x; 32 | currentY = arithmeticProduct(1 - time, 2) * startValue.y 33 | + 2 * time * (1 - time) * controlF1.y 34 | + arithmeticProduct(time, 2) * endValue.y; 35 | } else { 36 | // 三阶贝塞尔曲线 37 | currentX = arithmeticProduct(1 - time, 3) * (startValue.x) 38 | + 3 * arithmeticProduct(1 - time, 2) * time * (controlF1.x) 39 | + 3 * (1 - time) * arithmeticProduct(time, 2) * (controlF2.x) 40 | + arithmeticProduct(time, 3) * (endValue.x); 41 | currentY = arithmeticProduct(1 - time, 3) * (startValue.y) 42 | + 3 * arithmeticProduct(1 - time, 2) * time * (controlF1.y) 43 | + 3 * (1 - time) * arithmeticProduct(time, 2) * (controlF2.y) 44 | + arithmeticProduct(time, 3) * (endValue.y); 45 | } 46 | return new PointF(currentX, currentY); 47 | } 48 | 49 | // 返回浮点数的开方值 50 | private float arithmeticProduct(float value, float square) { 51 | double pow = Math.pow(value, square); 52 | return (float) pow; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/cell_edit_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/cell_edit_bg1.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/common_key_selector.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/delete_key_selector.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/fire.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kriy/CustomView/d9f17e0e86da3d98be6c9716622a4ecab8a91b0d/app/src/main/res/drawable/fire.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/fire_smoke.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/fragment.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kriy/CustomView/d9f17e0e86da3d98be6c9716622a4ecab8a91b0d/app/src/main/res/drawable/fragment.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/heart_default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kriy/CustomView/d9f17e0e86da3d98be6c9716622a4ecab8a91b0d/app/src/main/res/drawable/heart_default.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/img1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kriy/CustomView/d9f17e0e86da3d98be6c9716622a4ecab8a91b0d/app/src/main/res/drawable/img1.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/img2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kriy/CustomView/d9f17e0e86da3d98be6c9716622a4ecab8a91b0d/app/src/main/res/drawable/img2.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/img3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kriy/CustomView/d9f17e0e86da3d98be6c9716622a4ecab8a91b0d/app/src/main/res/drawable/img3.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/img4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kriy/CustomView/d9f17e0e86da3d98be6c9716622a4ecab8a91b0d/app/src/main/res/drawable/img4.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/img5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kriy/CustomView/d9f17e0e86da3d98be6c9716622a4ecab8a91b0d/app/src/main/res/drawable/img5.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/mei_ic_praise_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kriy/CustomView/d9f17e0e86da3d98be6c9716622a4ecab8a91b0d/app/src/main/res/drawable/mei_ic_praise_1.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/mei_ic_praise_10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kriy/CustomView/d9f17e0e86da3d98be6c9716622a4ecab8a91b0d/app/src/main/res/drawable/mei_ic_praise_10.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/mei_ic_praise_11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kriy/CustomView/d9f17e0e86da3d98be6c9716622a4ecab8a91b0d/app/src/main/res/drawable/mei_ic_praise_11.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/mei_ic_praise_12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kriy/CustomView/d9f17e0e86da3d98be6c9716622a4ecab8a91b0d/app/src/main/res/drawable/mei_ic_praise_12.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/mei_ic_praise_13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kriy/CustomView/d9f17e0e86da3d98be6c9716622a4ecab8a91b0d/app/src/main/res/drawable/mei_ic_praise_13.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/mei_ic_praise_14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kriy/CustomView/d9f17e0e86da3d98be6c9716622a4ecab8a91b0d/app/src/main/res/drawable/mei_ic_praise_14.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/mei_ic_praise_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kriy/CustomView/d9f17e0e86da3d98be6c9716622a4ecab8a91b0d/app/src/main/res/drawable/mei_ic_praise_2.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/mei_ic_praise_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kriy/CustomView/d9f17e0e86da3d98be6c9716622a4ecab8a91b0d/app/src/main/res/drawable/mei_ic_praise_3.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/mei_ic_praise_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kriy/CustomView/d9f17e0e86da3d98be6c9716622a4ecab8a91b0d/app/src/main/res/drawable/mei_ic_praise_4.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/mei_ic_praise_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kriy/CustomView/d9f17e0e86da3d98be6c9716622a4ecab8a91b0d/app/src/main/res/drawable/mei_ic_praise_5.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/mei_ic_praise_6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kriy/CustomView/d9f17e0e86da3d98be6c9716622a4ecab8a91b0d/app/src/main/res/drawable/mei_ic_praise_6.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/mei_ic_praise_7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kriy/CustomView/d9f17e0e86da3d98be6c9716622a4ecab8a91b0d/app/src/main/res/drawable/mei_ic_praise_7.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/mei_ic_praise_8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kriy/CustomView/d9f17e0e86da3d98be6c9716622a4ecab8a91b0d/app/src/main/res/drawable/mei_ic_praise_8.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/mei_ic_praise_9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kriy/CustomView/d9f17e0e86da3d98be6c9716622a4ecab8a91b0d/app/src/main/res/drawable/mei_ic_praise_9.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/shape_search.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 11 | 12 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/smoke.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kriy/CustomView/d9f17e0e86da3d98be6c9716622a4ecab8a91b0d/app/src/main/res/drawable/smoke.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/sparkle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kriy/CustomView/d9f17e0e86da3d98be6c9716622a4ecab8a91b0d/app/src/main/res/drawable/sparkle.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/ss_heart1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kriy/CustomView/d9f17e0e86da3d98be6c9716622a4ecab8a91b0d/app/src/main/res/drawable/ss_heart1.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/ss_heart2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kriy/CustomView/d9f17e0e86da3d98be6c9716622a4ecab8a91b0d/app/src/main/res/drawable/ss_heart2.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/ss_heart3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kriy/CustomView/d9f17e0e86da3d98be6c9716622a4ecab8a91b0d/app/src/main/res/drawable/ss_heart3.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/ss_heart4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kriy/CustomView/d9f17e0e86da3d98be6c9716622a4ecab8a91b0d/app/src/main/res/drawable/ss_heart4.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/ss_heart5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kriy/CustomView/d9f17e0e86da3d98be6c9716622a4ecab8a91b0d/app/src/main/res/drawable/ss_heart5.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/timeline_bg_blue.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/wenzi0000.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kriy/CustomView/d9f17e0e86da3d98be6c9716622a4ecab8a91b0d/app/src/main/res/drawable/wenzi0000.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/wenzi0001.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kriy/CustomView/d9f17e0e86da3d98be6c9716622a4ecab8a91b0d/app/src/main/res/drawable/wenzi0001.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/wenzi0002.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kriy/CustomView/d9f17e0e86da3d98be6c9716622a4ecab8a91b0d/app/src/main/res/drawable/wenzi0002.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/wenzi0003.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kriy/CustomView/d9f17e0e86da3d98be6c9716622a4ecab8a91b0d/app/src/main/res/drawable/wenzi0003.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/wenzi0004.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kriy/CustomView/d9f17e0e86da3d98be6c9716622a4ecab8a91b0d/app/src/main/res/drawable/wenzi0004.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/wenzi0005.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kriy/CustomView/d9f17e0e86da3d98be6c9716622a4ecab8a91b0d/app/src/main/res/drawable/wenzi0005.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/wenzi0006.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kriy/CustomView/d9f17e0e86da3d98be6c9716622a4ecab8a91b0d/app/src/main/res/drawable/wenzi0006.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/wenzi0007.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kriy/CustomView/d9f17e0e86da3d98be6c9716622a4ecab8a91b0d/app/src/main/res/drawable/wenzi0007.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/wenzi0008.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kriy/CustomView/d9f17e0e86da3d98be6c9716622a4ecab8a91b0d/app/src/main/res/drawable/wenzi0008.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/wenzi0009.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kriy/CustomView/d9f17e0e86da3d98be6c9716622a4ecab8a91b0d/app/src/main/res/drawable/wenzi0009.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/wenzi0010.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kriy/CustomView/d9f17e0e86da3d98be6c9716622a4ecab8a91b0d/app/src/main/res/drawable/wenzi0010.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/wenzi0011.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kriy/CustomView/d9f17e0e86da3d98be6c9716622a4ecab8a91b0d/app/src/main/res/drawable/wenzi0011.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/wenzi0012.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kriy/CustomView/d9f17e0e86da3d98be6c9716622a4ecab8a91b0d/app/src/main/res/drawable/wenzi0012.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/wenzi0013.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kriy/CustomView/d9f17e0e86da3d98be6c9716622a4ecab8a91b0d/app/src/main/res/drawable/wenzi0013.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/wenzi0014.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kriy/CustomView/d9f17e0e86da3d98be6c9716622a4ecab8a91b0d/app/src/main/res/drawable/wenzi0014.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/wenzi0015.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kriy/CustomView/d9f17e0e86da3d98be6c9716622a4ecab8a91b0d/app/src/main/res/drawable/wenzi0015.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/wenzi0016.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kriy/CustomView/d9f17e0e86da3d98be6c9716622a4ecab8a91b0d/app/src/main/res/drawable/wenzi0016.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/wenzi0017.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kriy/CustomView/d9f17e0e86da3d98be6c9716622a4ecab8a91b0d/app/src/main/res/drawable/wenzi0017.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/wenzi0018.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kriy/CustomView/d9f17e0e86da3d98be6c9716622a4ecab8a91b0d/app/src/main/res/drawable/wenzi0018.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/wenzi0019.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kriy/CustomView/d9f17e0e86da3d98be6c9716622a4ecab8a91b0d/app/src/main/res/drawable/wenzi0019.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/wenzi0020.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kriy/CustomView/d9f17e0e86da3d98be6c9716622a4ecab8a91b0d/app/src/main/res/drawable/wenzi0020.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/wenzi0021.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kriy/CustomView/d9f17e0e86da3d98be6c9716622a4ecab8a91b0d/app/src/main/res/drawable/wenzi0021.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/wenzi0022.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kriy/CustomView/d9f17e0e86da3d98be6c9716622a4ecab8a91b0d/app/src/main/res/drawable/wenzi0022.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/wenzi0023.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kriy/CustomView/d9f17e0e86da3d98be6c9716622a4ecab8a91b0d/app/src/main/res/drawable/wenzi0023.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/wenzi0024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kriy/CustomView/d9f17e0e86da3d98be6c9716622a4ecab8a91b0d/app/src/main/res/drawable/wenzi0024.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/wenzi0025.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kriy/CustomView/d9f17e0e86da3d98be6c9716622a4ecab8a91b0d/app/src/main/res/drawable/wenzi0025.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/wenzi0026.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kriy/CustomView/d9f17e0e86da3d98be6c9716622a4ecab8a91b0d/app/src/main/res/drawable/wenzi0026.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/wenzi0027.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kriy/CustomView/d9f17e0e86da3d98be6c9716622a4ecab8a91b0d/app/src/main/res/drawable/wenzi0027.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/wenzi0028.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kriy/CustomView/d9f17e0e86da3d98be6c9716622a4ecab8a91b0d/app/src/main/res/drawable/wenzi0028.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/wenzi0029.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kriy/CustomView/d9f17e0e86da3d98be6c9716622a4ecab8a91b0d/app/src/main/res/drawable/wenzi0029.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/wenzi0030.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kriy/CustomView/d9f17e0e86da3d98be6c9716622a4ecab8a91b0d/app/src/main/res/drawable/wenzi0030.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/wenzi0031.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kriy/CustomView/d9f17e0e86da3d98be6c9716622a4ecab8a91b0d/app/src/main/res/drawable/wenzi0031.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/wenzi0032.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kriy/CustomView/d9f17e0e86da3d98be6c9716622a4ecab8a91b0d/app/src/main/res/drawable/wenzi0032.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/wenzi0033.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kriy/CustomView/d9f17e0e86da3d98be6c9716622a4ecab8a91b0d/app/src/main/res/drawable/wenzi0033.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/wenzi0034.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kriy/CustomView/d9f17e0e86da3d98be6c9716622a4ecab8a91b0d/app/src/main/res/drawable/wenzi0034.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/wenzi0035.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kriy/CustomView/d9f17e0e86da3d98be6c9716622a4ecab8a91b0d/app/src/main/res/drawable/wenzi0035.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/wenzi0036.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kriy/CustomView/d9f17e0e86da3d98be6c9716622a4ecab8a91b0d/app/src/main/res/drawable/wenzi0036.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/wenzi0037.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kriy/CustomView/d9f17e0e86da3d98be6c9716622a4ecab8a91b0d/app/src/main/res/drawable/wenzi0037.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/wenzi0038.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kriy/CustomView/d9f17e0e86da3d98be6c9716622a4ecab8a91b0d/app/src/main/res/drawable/wenzi0038.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/wenzi0039.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kriy/CustomView/d9f17e0e86da3d98be6c9716622a4ecab8a91b0d/app/src/main/res/drawable/wenzi0039.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/wenzi0040.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kriy/CustomView/d9f17e0e86da3d98be6c9716622a4ecab8a91b0d/app/src/main/res/drawable/wenzi0040.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/wenzi0041.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kriy/CustomView/d9f17e0e86da3d98be6c9716622a4ecab8a91b0d/app/src/main/res/drawable/wenzi0041.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/wenzi0042.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kriy/CustomView/d9f17e0e86da3d98be6c9716622a4ecab8a91b0d/app/src/main/res/drawable/wenzi0042.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/wenzi0043.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kriy/CustomView/d9f17e0e86da3d98be6c9716622a4ecab8a91b0d/app/src/main/res/drawable/wenzi0043.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/wenzi0044.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kriy/CustomView/d9f17e0e86da3d98be6c9716622a4ecab8a91b0d/app/src/main/res/drawable/wenzi0044.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/wenzi0045.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kriy/CustomView/d9f17e0e86da3d98be6c9716622a4ecab8a91b0d/app/src/main/res/drawable/wenzi0045.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/wenzi0046.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kriy/CustomView/d9f17e0e86da3d98be6c9716622a4ecab8a91b0d/app/src/main/res/drawable/wenzi0046.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/wenzi0047.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kriy/CustomView/d9f17e0e86da3d98be6c9716622a4ecab8a91b0d/app/src/main/res/drawable/wenzi0047.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/wenzi0048.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kriy/CustomView/d9f17e0e86da3d98be6c9716622a4ecab8a91b0d/app/src/main/res/drawable/wenzi0048.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/wenzi0049.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kriy/CustomView/d9f17e0e86da3d98be6c9716622a4ecab8a91b0d/app/src/main/res/drawable/wenzi0049.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/wenzi0050.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kriy/CustomView/d9f17e0e86da3d98be6c9716622a4ecab8a91b0d/app/src/main/res/drawable/wenzi0050.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/wenzi0051.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kriy/CustomView/d9f17e0e86da3d98be6c9716622a4ecab8a91b0d/app/src/main/res/drawable/wenzi0051.png -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_alpha_text_view.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 12 | 13 |