├── .circleci └── config.yml ├── .gitignore ├── .idea ├── caches │ └── build_file_checksums.ser ├── codeStyles │ └── Project.xml ├── dbnavigator.xml ├── encodings.xml ├── gradle.xml ├── misc.xml ├── modules.xml ├── runConfigurations.xml └── vcs.xml ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── hakobastvatsatryan │ │ └── sample │ │ └── ExampleInstrumentedTest.kt │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── hakobastvatsatryan │ │ │ └── sample │ │ │ └── MainActivity.kt │ └── res │ │ ├── drawable-v24 │ │ └── ic_launcher_foreground.xml │ │ ├── drawable │ │ ├── bg_first_dropdown_text_view_expanded.xml │ │ ├── bg_first_dropdown_text_view_regular.xml │ │ ├── bg_second_dropdown_text_view_expanded.xml │ │ ├── bg_second_dropdown_text_view_regular.xml │ │ ├── bg_third_dropdown_text_view_expanded.xml │ │ ├── bg_third_dropdown_text_view_regular.xml │ │ └── ic_launcher_background.xml │ │ ├── layout │ │ └── activity_main.xml │ │ ├── mipmap-anydpi-v26 │ │ ├── ic_launcher.xml │ │ └── ic_launcher_round.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ └── values │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── hakobastvatsatryan │ └── sample │ └── ExampleUnitTest.kt ├── build.gradle ├── dropdown-textview ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── hakobastvatsatryan │ │ └── dropdowntextview │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── hakobastvatsatryan │ │ │ ├── AnimationUtils.kt │ │ │ └── DropdownTextView.kt │ └── res │ │ ├── drawable-hdpi │ │ └── ic_arrow.png │ │ ├── drawable-mdpi │ │ └── ic_arrow.png │ │ ├── drawable-xhdpi │ │ └── ic_arrow.png │ │ ├── drawable-xxhdpi │ │ └── ic_arrow.png │ │ ├── layout │ │ └── view_dropdown_text_view.xml │ │ └── values │ │ ├── attrs.xml │ │ ├── dimens.xml │ │ └── strings.xml │ └── test │ └── java │ └── hakobastvatsatryan │ └── dropdowntextview │ └── ExampleUnitTest.java ├── example-screens ├── example-1.gif └── example-2.gif ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | #version: 2.1 2 | # 3 | #orbs: 4 | # android: circleci/android@0.2.0 5 | # 6 | #jobs: 7 | # build: 8 | # executor: android/android 9 | # steps: 10 | # - checkout 11 | # - run: 12 | # name: Build release package 13 | # command: ./gradlew assembleRelease 14 | # - run: 15 | # name: Deploy to Bintray 16 | # command: ./gradlew bintrayUpload 17 | # 18 | #workflows: 19 | # version: 2 20 | # deploy: 21 | # jobs: 22 | # - build: 23 | # filters: 24 | # tags: 25 | # only: /^v.*/ 26 | # branches: 27 | # only: master -------------------------------------------------------------------------------- /.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/hakobast/DropdownTextView/3ff35055afc1b2caac9eb5328c1740e8fc55006c/.idea/caches/build_file_checksums.ser -------------------------------------------------------------------------------- /.idea/codeStyles/Project.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 11 | 12 | 13 | 14 | 15 | 21 | 22 | 26 | 27 | 28 | 29 | 30 |
31 | 32 | 33 | 34 | xmlns:android 35 | 36 | ^$ 37 | 38 | 39 | 40 |
41 |
42 | 43 | 44 | 45 | xmlns:.* 46 | 47 | ^$ 48 | 49 | 50 | BY_NAME 51 | 52 |
53 |
54 | 55 | 56 | 57 | .*:id 58 | 59 | http://schemas.android.com/apk/res/android 60 | 61 | 62 | 63 |
64 |
65 | 66 | 67 | 68 | .*:name 69 | 70 | http://schemas.android.com/apk/res/android 71 | 72 | 73 | 74 |
75 |
76 | 77 | 78 | 79 | name 80 | 81 | ^$ 82 | 83 | 84 | 85 |
86 |
87 | 88 | 89 | 90 | style 91 | 92 | ^$ 93 | 94 | 95 | 96 |
97 |
98 | 99 | 100 | 101 | .* 102 | 103 | ^$ 104 | 105 | 106 | BY_NAME 107 | 108 |
109 |
110 | 111 | 112 | 113 | .* 114 | 115 | http://schemas.android.com/apk/res/android 116 | 117 | 118 | ANDROID_ATTRIBUTE_ORDER 119 | 120 |
121 |
122 | 123 | 124 | 125 | .* 126 | 127 | .* 128 | 129 | 130 | BY_NAME 131 | 132 |
133 |
134 |
135 |
136 |
137 |
-------------------------------------------------------------------------------- /.idea/dbnavigator.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 21 | 22 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 22 | 37 | 38 | 39 | 40 | 41 | 42 | 44 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DropdownTextView 2 | Simple drop-down TextView for Android 3 | 4 | ## Intro 5 | 6 | ![](example-screens/example-1.gif) 7 | ![](example-screens/example-2.gif) 8 | 9 | ## Usage 10 | 11 | Adds drop-down to your layout via XML 12 | 13 | ```xml 14 | 20 | 21 | 22 | 43 | 44 | 45 | ``` 46 | 47 | Adds drop-down to your layout pragmatically 48 | 49 | ```kotlin 50 | val dropdown = DropdownTextView.Builder(this) 51 | .setTitleTextRes(R.string.your_title_text) 52 | .setTitleTextColorRes(R.color.your_title_text_color) 53 | .setTitleTextColorExpandedRes(R.color.your_title_text_color_expanded) 54 | .setTitleTextSizeRes(R.dimen.your_title_text_size) 55 | .setTitleFontRes(R.font.your_title_font) 56 | .setContentTextRes(R.string.your_content_text) 57 | .setContentTextColorRes(R.color.your_content_text_color) 58 | .setContentTextSizeRes(R.color.your_content_text_size) 59 | .setContentFontRes(R.color.your_content_text_font) 60 | .setContentPaddingRes(R.dimen.your_content_padding) 61 | .setHtmlContent(htmlText) 62 | .setHtmlContent(htmlText, handler) 63 | .setLinkTextColorRes(R.color.your_text_link_color) 64 | .setLinkUnderline(isUnderlineVisible) 65 | .setArrowDrawableRes(R.drawable.your_drawable_icon) // icon should be faced to the right 66 | .setRegularBackgroundDrawableRes(R.drawable.your_regular_background) 67 | .setExpandedBackgroundDrawableRes(R.drawable.your_expanded_background) 68 | .setPanelPaddingRes(R.dimen.your_panel_padding) 69 | .setExpandDuration(your_expand_duration) 70 | .build() 71 | 72 | root.addView(dropdown) // You can specify layout params for dropdown 73 | ``` 74 | 75 | ## Download 76 | Gradle: 77 | ```groovy 78 | compile 'com.github.hakobast:dropdown-textview:0.3.1' 79 | ``` 80 | Maven: 81 | ```xml 82 | 83 | com.github.hakobast 84 | dropdown-textview 85 | 0.3.1 86 | pom 87 | 88 | ``` 89 | 90 | ## Contact 91 | 92 | - **Email**: hakob.astvacatryan@gmail.com 93 | - **Twitter**: https://twitter.com/hak_ast 94 | 95 | ## License 96 | 97 | Copyright 2018 Hakob Astvatsatryan 98 | 99 | Licensed under the Apache License, Version 2.0 (the "License"); 100 | you may not use this file except in compliance with the License. 101 | You may obtain a copy of the License at 102 | 103 | http://www.apache.org/licenses/LICENSE-2.0 104 | 105 | Unless required by applicable law or agreed to in writing, software 106 | distributed under the License is distributed on an "AS IS" BASIS, 107 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 108 | See the License for the specific language governing permissions and 109 | limitations under the License. 110 | -------------------------------------------------------------------------------- /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 | defaultConfig { 8 | applicationId "hakobastvatsatryan.sample" 9 | minSdkVersion 19 10 | targetSdkVersion 29 11 | versionCode 1 12 | versionName "1.0" 13 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 14 | } 15 | buildTypes { 16 | release { 17 | minifyEnabled false 18 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 19 | } 20 | } 21 | } 22 | 23 | dependencies { 24 | implementation fileTree(include: ['*.jar'], dir: 'libs') 25 | 26 | /* Test */ 27 | testImplementation 'junit:junit:4.12' 28 | androidTestImplementation 'androidx.test:runner:1.1.1' 29 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1' 30 | 31 | /* AndroidX */ 32 | implementation 'androidx.appcompat:appcompat:1.0.2' 33 | implementation 'androidx.constraintlayout:constraintlayout:1.1.3' 34 | 35 | /* Kotlin */ 36 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 37 | 38 | /* DropdownTextView */ 39 | implementation project(':dropdown-textview') 40 | } 41 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /app/src/androidTest/java/hakobastvatsatryan/sample/ExampleInstrumentedTest.kt: -------------------------------------------------------------------------------- 1 | package hakobastvatsatryan.sample 2 | 3 | import androidx.test.InstrumentationRegistry 4 | import androidx.test.runner.AndroidJUnit4 5 | 6 | import org.junit.Test 7 | import org.junit.runner.RunWith 8 | 9 | import org.junit.Assert.* 10 | 11 | /** 12 | * Instrumented test, which will execute on an Android device. 13 | * 14 | * See [testing documentation](http://d.android.com/tools/testing). 15 | */ 16 | @RunWith(AndroidJUnit4::class) 17 | class ExampleInstrumentedTest { 18 | @Test 19 | fun useAppContext() { 20 | // Context of the app under test. 21 | val appContext = InstrumentationRegistry.getTargetContext() 22 | assertEquals("hakobastvatsatryan.sample", appContext.packageName) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /app/src/main/java/hakobastvatsatryan/sample/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package hakobastvatsatryan.sample 2 | 3 | import androidx.appcompat.app.AppCompatActivity 4 | import android.os.Bundle 5 | import android.util.Log 6 | import android.view.ViewGroup 7 | import android.widget.LinearLayout 8 | import hakobastvatsatryan.DropdownTextView 9 | 10 | typealias lp = LinearLayout.LayoutParams 11 | 12 | class MainActivity : AppCompatActivity() { 13 | 14 | private val text = "Click to visit Page " 15 | 16 | 17 | override fun onCreate(savedInstanceState: Bundle?) { 18 | super.onCreate(savedInstanceState) 19 | setContentView(R.layout.activity_main) 20 | 21 | val secondDropdownTextView: DropdownTextView = findViewById(R.id.second_dropdown_text_view) 22 | secondDropdownTextView.setTitleText(R.string.dropdown_title_text) 23 | secondDropdownTextView.setContentText(R.string.dropdown_content_text) 24 | 25 | val thirdDropdownTextViewSecond = DropdownTextView.Builder(this) 26 | .setTitleTextColorRes(R.color.third_drop_down_text_view_title) 27 | .setTitleTextColorExpandedRes(R.color.third_drop_down_text_view_title_expanded) 28 | .setTitleTextRes(R.string.dropdown_title_text) 29 | .setContentTextColorRes(R.color.third_drop_down_text_view_content) 30 | .setLinkUnderline(false) 31 | .setLinkTextColorRes(R.color.first_drop_down_text_view_title) 32 | .setHtmlContent(text){ url -> 33 | Log.d("LINK", "LINK $url") 34 | } 35 | .setRegularBackgroundDrawableRes(R.drawable.bg_third_dropdown_text_view_regular) 36 | .setExpandedBackgroundDrawableRes(R.drawable.bg_third_dropdown_text_view_expanded) 37 | .build() 38 | 39 | val root: ViewGroup = findViewById(R.id.root_view) 40 | root.addView(thirdDropdownTextViewSecond, lp(lp.MATCH_PARENT, lp.WRAP_CONTENT).apply { 41 | resources.getDimension(R.dimen.margin_10).toInt().apply { 42 | setMargins(this, this, this, this) 43 | } 44 | }) 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 12 | 13 | 19 | 22 | 25 | 26 | 27 | 28 | 34 | 35 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_first_dropdown_text_view_expanded.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_first_dropdown_text_view_regular.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_second_dropdown_text_view_expanded.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_second_dropdown_text_view_regular.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_third_dropdown_text_view_expanded.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_third_dropdown_text_view_regular.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 11 | 16 | 21 | 26 | 31 | 36 | 41 | 46 | 51 | 56 | 61 | 66 | 71 | 76 | 81 | 86 | 91 | 96 | 101 | 106 | 111 | 116 | 121 | 126 | 131 | 136 | 141 | 146 | 151 | 156 | 161 | 166 | 171 | 172 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 14 | 15 | 27 | 28 | 36 | 37 | 44 | 45 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hakobast/DropdownTextView/3ff35055afc1b2caac9eb5328c1740e8fc55006c/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hakobast/DropdownTextView/3ff35055afc1b2caac9eb5328c1740e8fc55006c/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hakobast/DropdownTextView/3ff35055afc1b2caac9eb5328c1740e8fc55006c/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hakobast/DropdownTextView/3ff35055afc1b2caac9eb5328c1740e8fc55006c/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hakobast/DropdownTextView/3ff35055afc1b2caac9eb5328c1740e8fc55006c/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hakobast/DropdownTextView/3ff35055afc1b2caac9eb5328c1740e8fc55006c/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hakobast/DropdownTextView/3ff35055afc1b2caac9eb5328c1740e8fc55006c/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hakobast/DropdownTextView/3ff35055afc1b2caac9eb5328c1740e8fc55006c/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hakobast/DropdownTextView/3ff35055afc1b2caac9eb5328c1740e8fc55006c/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hakobast/DropdownTextView/3ff35055afc1b2caac9eb5328c1740e8fc55006c/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #3F51B5 4 | #303F9F 5 | #FF4081 6 | 7 | #FFDFF5FF 8 | #323b40 9 | 10 | #FFDFF5FF 11 | #FF212C34 12 | 13 | #34495e 14 | #077057 15 | #2c3e50 16 | 17 | -------------------------------------------------------------------------------- /app/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 22dp 4 | 22dp 5 | 10dp 6 | -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | DropdownTextView 3 | Far away from behind 4 | Buying the right telescope to take your love of astronomy to the next level is a big next step in the development of your passion for the stars. In many ways, it is a big step from someone who is just fooling around with astronomy to a serious student of the science. 5 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 13 | 14 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /app/src/test/java/hakobastvatsatryan/sample/ExampleUnitTest.kt: -------------------------------------------------------------------------------- 1 | package hakobastvatsatryan.sample 2 | 3 | import org.junit.Test 4 | 5 | import org.junit.Assert.* 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * See [testing documentation](http://d.android.com/tools/testing). 11 | */ 12 | class ExampleUnitTest { 13 | @Test 14 | fun addition_isCorrect() { 15 | assertEquals(4, 2 + 2) 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | ext.kotlin_version = '1.3.70' 3 | repositories { 4 | google() 5 | jcenter() 6 | } 7 | dependencies { 8 | classpath 'com.android.tools.build:gradle:3.6.1' 9 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 10 | 11 | classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.4' 12 | classpath 'com.github.dcendents:android-maven-gradle-plugin:1.5' 13 | } 14 | } 15 | 16 | allprojects { 17 | repositories { 18 | google() 19 | jcenter() 20 | } 21 | } 22 | 23 | task clean(type: Delete) { 24 | delete rootProject.buildDir 25 | } -------------------------------------------------------------------------------- /dropdown-textview/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /dropdown-textview/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | apply plugin: 'kotlin-android' 3 | apply plugin: 'maven-publish' 4 | apply plugin: 'com.jfrog.bintray' 5 | 6 | publishing { 7 | publications { 8 | MyPublication(MavenPublication) { 9 | groupId 'com.github.hakobast' 10 | artifactId 'dropdown-textview' 11 | version "0.3.1" 12 | } 13 | } 14 | } 15 | 16 | bintray { 17 | user = project.hasProperty('bintrayUser') ? project.property('bintrayUser') : System.getenv('BINTRAY_USER') 18 | key = project.hasProperty('bintrayApiKey') ? project.property('bintrayApiKey') : System.getenv('BINTRAY_API_KEY') 19 | 20 | pkg { 21 | repo = 'maven' 22 | name = 'dropdown-textview' 23 | licenses = ['Apache-2.0'] 24 | githubRepo = 'https://github.com/hakobast/DropdownTextView' 25 | vcsUrl = 'https://github.com/hakobast/DropdownTextView.git' 26 | publications = ['MyPublication'] 27 | publish = true 28 | version { 29 | name = '0.3.1' 30 | desc = "Test" 31 | released = new Date() 32 | vcsTag = "0.3.1" 33 | } 34 | } 35 | } 36 | 37 | android { 38 | compileSdkVersion 29 39 | 40 | defaultConfig { 41 | minSdkVersion 19 42 | targetSdkVersion 29 43 | versionCode 1 44 | versionName "0.3.1" 45 | 46 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 47 | } 48 | 49 | buildTypes { 50 | release { 51 | minifyEnabled false 52 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 53 | } 54 | } 55 | 56 | } 57 | 58 | dependencies { 59 | implementation fileTree(dir: 'libs', include: ['*.jar']) 60 | 61 | /* Test */ 62 | testImplementation 'junit:junit:4.12' 63 | androidTestImplementation 'androidx.test:runner:1.2.0' 64 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' 65 | 66 | /* AndroidX */ 67 | implementation 'androidx.appcompat:appcompat:1.1.0' 68 | 69 | /* Kotlin */ 70 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 71 | } 72 | 73 | tasks.withType(Javadoc).all { 74 | enabled = false 75 | } -------------------------------------------------------------------------------- /dropdown-textview/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /dropdown-textview/src/androidTest/java/hakobastvatsatryan/dropdowntextview/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package hakobastvatsatryan.dropdowntextview; 2 | 3 | import android.content.Context; 4 | import androidx.test.InstrumentationRegistry; 5 | import androidx.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 | * Instrumented 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("hakobastvatsatryan.dropdowntextview.test", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /dropdown-textview/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /dropdown-textview/src/main/java/hakobastvatsatryan/AnimationUtils.kt: -------------------------------------------------------------------------------- 1 | package hakobastvatsatryan 2 | 3 | import android.animation.Animator 4 | import android.animation.PropertyValuesHolder 5 | import android.animation.ValueAnimator 6 | 7 | /** 8 | * Created by hakobastvatsatryan on 1/30/18. 9 | */ 10 | 11 | open class AnimListenerImpl : Animator.AnimatorListener { 12 | override fun onAnimationRepeat(animation: Animator?) {} 13 | override fun onAnimationEnd(animation: Animator?) {} 14 | override fun onAnimationCancel(animation: Animator?) {} 15 | override fun onAnimationStart(animation: Animator?) {} 16 | } 17 | 18 | inline fun changeValue(from: V, 19 | to: V, 20 | duration: Long, 21 | crossinline update: (value: V) -> Unit, 22 | crossinline complete: (() -> Unit) 23 | ) { 24 | val vH: PropertyValuesHolder = when (from) { 25 | is Int -> PropertyValuesHolder.ofInt("prop", from as Int, to as Int) 26 | is Float -> PropertyValuesHolder.ofFloat("prop", from as Float, to as Float) 27 | else -> throw UnsupportedOperationException("$from type not supported") 28 | } 29 | 30 | ValueAnimator.ofPropertyValuesHolder(vH).apply { 31 | this.duration = duration 32 | addUpdateListener { 33 | update(this.getAnimatedValue("prop") as V) 34 | } 35 | addListener(object : AnimListenerImpl() { 36 | override fun onAnimationEnd(animation: Animator?) { 37 | complete() 38 | } 39 | }) 40 | start() 41 | } 42 | } 43 | 44 | inline fun changeValue(from: V, 45 | to: V, 46 | duration: Long, 47 | crossinline update: (value: V) -> Unit 48 | ) { 49 | val vH: PropertyValuesHolder = when (from) { 50 | is Int -> PropertyValuesHolder.ofInt("prop", from as Int, to as Int) 51 | is Float -> PropertyValuesHolder.ofFloat("prop", from as Float, to as Float) 52 | else -> throw UnsupportedOperationException("$from and $to types are not supported") 53 | } 54 | 55 | ValueAnimator.ofPropertyValuesHolder(vH).apply { 56 | this.duration = duration 57 | addUpdateListener { 58 | update(this.getAnimatedValue("prop") as V) 59 | } 60 | start() 61 | } 62 | } -------------------------------------------------------------------------------- /dropdown-textview/src/main/java/hakobastvatsatryan/DropdownTextView.kt: -------------------------------------------------------------------------------- 1 | package hakobastvatsatryan 2 | 3 | import android.content.Context 4 | import androidx.core.content.ContextCompat 5 | import androidx.core.content.res.ResourcesCompat 6 | import android.util.AttributeSet 7 | import android.util.TypedValue 8 | import android.view.View 9 | import android.widget.LinearLayout 10 | import android.widget.TextView 11 | import android.os.Bundle 12 | import android.os.Parcelable 13 | import android.text.Html 14 | import android.text.SpannableStringBuilder 15 | import android.text.TextPaint 16 | import android.text.method.LinkMovementMethod 17 | import android.text.style.ClickableSpan 18 | import android.text.style.URLSpan 19 | import androidx.annotation.* 20 | import hakobastvatsatryan.dropdowntextview.R 21 | 22 | 23 | /** 24 | * Created by hakob on 12/6/16. 25 | */ 26 | 27 | class DropdownTextView : LinearLayout { 28 | 29 | private lateinit var panelView: View 30 | private lateinit var titleTextView: TextView 31 | private lateinit var contentTextView: TextView 32 | private lateinit var arrowView: View 33 | 34 | private var isExpanded: Boolean = false 35 | private var titleText: String? = null 36 | private var contentText: String? = null 37 | private var expandDuration: Int = -1 38 | private var titleTextColor: Int? = null 39 | private var titleTextColorExpanded: Int? = null 40 | private var titleTextSizeRes: Int = -1 41 | private var titleFontRes: Int = -1 42 | private var contentTextColor: Int? = null 43 | private var contentTextSizeRes: Int = -1 44 | private var contentFontRes: Int = -1 45 | private var rawHtmlContent: String? = null 46 | private var spannableHtmlContent: String? = null 47 | private var linkHandler: ((url: String) -> Unit)? = null 48 | private var linkTextColor: Int? = null 49 | private var isLinkUnderline: Boolean = true 50 | private var arrowDrawableRes: Int = -1 51 | private var bgRegularDrawableRes: Int = -1 52 | private var bgExpandedDrawableRes: Int = -1 53 | private var panelPaddingRes: Int = -1 54 | private var contentPaddingRes: Int = -1 55 | 56 | private constructor(context: Context, builder: Builder) : super(context) { 57 | readBuilder(builder) 58 | initialize() 59 | } 60 | 61 | constructor(context: Context, attrs: AttributeSet) : super(context, attrs) { 62 | if (!isInEditMode) { 63 | readAttributes(attrs) 64 | initialize() 65 | } 66 | } 67 | 68 | constructor(context: Context, attrs: AttributeSet, defStyle: Int) : super( 69 | context, 70 | attrs, 71 | defStyle 72 | ) { 73 | if (!isInEditMode) { 74 | readAttributes(attrs) 75 | initialize() 76 | } 77 | } 78 | 79 | fun expand(animate: Boolean) { 80 | if (isExpanded) { 81 | return 82 | } 83 | 84 | expandInternal(animate) 85 | } 86 | 87 | fun collapse(animate: Boolean) { 88 | if (!isExpanded) { 89 | return 90 | } 91 | 92 | collapseInternal(animate) 93 | } 94 | 95 | fun setTitleText(text: String) { 96 | titleTextView.text = text 97 | } 98 | 99 | fun setTitleText(@StringRes stringRes: Int) { 100 | titleTextView.setText(stringRes) 101 | } 102 | 103 | fun setContentText(text: String) { 104 | contentTextView.text = text 105 | } 106 | 107 | fun setContentText(@StringRes stringRes: Int) { 108 | contentTextView.setText(stringRes) 109 | } 110 | 111 | @Suppress("DEPRECATION") 112 | fun setHtmlContent(text: String) { 113 | contentTextView.setText(Html.fromHtml(text), TextView.BufferType.SPANNABLE) 114 | contentTextView.movementMethod = LinkMovementMethod.getInstance() 115 | } 116 | 117 | @Suppress("DEPRECATION") 118 | fun setHtmlContent(text: String, clickHandler: (url: String) -> Unit) { 119 | val html = Html.fromHtml(text) 120 | val spannableBuilder = SpannableStringBuilder(html) 121 | val urlSPans = spannableBuilder.getSpans(0, html.length, URLSpan::class.java) 122 | urlSPans.forEach { 123 | makeClickable(spannableBuilder, it, isLinkUnderline) { url -> 124 | clickHandler(url) 125 | } 126 | } 127 | 128 | contentTextView.text = spannableBuilder 129 | contentTextView.movementMethod = LinkMovementMethod.getInstance() 130 | } 131 | 132 | private fun makeClickable(spannableBuilder: SpannableStringBuilder, 133 | span: URLSpan, 134 | makeUnderline: Boolean, 135 | clickHandler: (url: String) -> Unit 136 | ) { 137 | val clickableSpan = object : ClickableSpan() { 138 | override fun onClick(widget: View) { 139 | clickHandler(span.url) 140 | } 141 | 142 | override fun updateDrawState(ds: TextPaint) { 143 | super.updateDrawState(ds) 144 | ds.isUnderlineText = makeUnderline 145 | } 146 | } 147 | spannableBuilder.setSpan( 148 | clickableSpan, 149 | spannableBuilder.getSpanStart(span), 150 | spannableBuilder.getSpanEnd(span), 151 | spannableBuilder.getSpanFlags(span) 152 | ) 153 | spannableBuilder.removeSpan(span) 154 | } 155 | 156 | fun getTitleTextView(): TextView { 157 | return titleTextView 158 | } 159 | 160 | fun getContentTextView(): TextView { 161 | return contentTextView 162 | } 163 | 164 | override fun onSaveInstanceState(): Parcelable? { 165 | val bundle = Bundle() 166 | bundle.putParcelable("superState", super.onSaveInstanceState()) 167 | bundle.putBoolean("expanded", this.isExpanded) 168 | return bundle 169 | } 170 | 171 | override fun onRestoreInstanceState(state: Parcelable?) { 172 | var superState: Parcelable? = null 173 | if (state is Bundle) { 174 | isExpanded = state.getBoolean("expanded") 175 | superState = state.getParcelable("superState") 176 | } 177 | 178 | super.onRestoreInstanceState(superState) 179 | } 180 | 181 | private fun readBuilder(builder: Builder) { 182 | titleText = resources.getString(builder.titleTextRes) 183 | titleTextColor = ContextCompat.getColor(context, builder.titleTextColorRes) 184 | titleTextColorExpanded = ContextCompat.getColor(context, builder.titleTextColorExpandedRes) 185 | titleTextSizeRes = builder.titleTextSizeRes 186 | titleFontRes = builder.titleFontRes 187 | 188 | contentText = if (builder.contentTextRes > 0) resources.getString(builder.contentTextRes) else null 189 | contentTextColor = ContextCompat.getColor(context, builder.contentTextColorRes) 190 | contentTextSizeRes = builder.contentTextSizeRes 191 | 192 | contentFontRes = builder.contentFontRes 193 | rawHtmlContent = builder.rawHtmlContent 194 | spannableHtmlContent = builder.spannableHtmlContent 195 | linkHandler = builder.linkHandler 196 | 197 | linkTextColor = if (builder.linkTextColorRes > 0) ContextCompat.getColor(context, builder.linkTextColorRes) else null 198 | isLinkUnderline = builder.isLinkUnderline 199 | 200 | bgRegularDrawableRes = builder.bgRegularDrawableRes 201 | bgExpandedDrawableRes = builder.bgExpandedDrawableRes 202 | 203 | panelPaddingRes = if (builder.panelPaddingRes == -1) R.dimen.panel_default_padding else builder.panelPaddingRes 204 | contentPaddingRes = if (builder.contentPaddingRes == -1) R.dimen.content_default_padding else builder.contentPaddingRes 205 | 206 | arrowDrawableRes = if (builder.arrowDrawableRes == -1) R.drawable.ic_arrow else builder.arrowDrawableRes 207 | 208 | expandDuration = if (builder.expandDuration == -1) 300 else builder.expandDuration 209 | } 210 | 211 | private fun readAttributes(attrs: AttributeSet) { 212 | val a = context.theme.obtainStyledAttributes( 213 | attrs, 214 | R.styleable.DropdownTextView, 215 | 0, 0 216 | ) 217 | 218 | val typeValue = TypedValue() 219 | 220 | a.getValue(R.styleable.DropdownTextView_title_text, typeValue) 221 | titleText = when (typeValue.type) { 222 | TypedValue.TYPE_STRING -> typeValue.string as String? 223 | TypedValue.TYPE_REFERENCE -> resources.getString(typeValue.resourceId) 224 | else -> null 225 | } 226 | 227 | a.getValue(R.styleable.DropdownTextView_title_text_color, typeValue) 228 | titleTextColor = when (typeValue.type) { 229 | TypedValue.TYPE_REFERENCE -> ContextCompat.getColor(context, typeValue.resourceId) 230 | else -> typeValue.data 231 | } 232 | 233 | a.getValue(R.styleable.DropdownTextView_title_text_color_expanded, typeValue) 234 | titleTextColorExpanded = when (typeValue.type) { 235 | TypedValue.TYPE_REFERENCE -> ContextCompat.getColor(context, typeValue.resourceId) 236 | else -> typeValue.data 237 | } 238 | 239 | titleTextSizeRes = a.getResourceId(R.styleable.DropdownTextView_title_text_size, -1) 240 | titleFontRes = a.getResourceId(R.styleable.DropdownTextView_title_font, -1) 241 | 242 | a.getValue(R.styleable.DropdownTextView_content_text, typeValue) 243 | contentText = when (typeValue.type) { 244 | TypedValue.TYPE_STRING -> typeValue.string as String? 245 | TypedValue.TYPE_REFERENCE -> resources.getString(typeValue.resourceId) 246 | else -> null 247 | } 248 | 249 | a.getValue(R.styleable.DropdownTextView_content_text_color, typeValue) 250 | contentTextColor = when (typeValue.type) { 251 | TypedValue.TYPE_REFERENCE -> ContextCompat.getColor(context, typeValue.resourceId) 252 | else -> typeValue.data 253 | } 254 | 255 | a.getValue(R.styleable.DropdownTextView_link_text_color, typeValue) 256 | linkTextColor = when (typeValue.type) { 257 | TypedValue.TYPE_REFERENCE -> ContextCompat.getColor(context, typeValue.resourceId) 258 | else -> typeValue.data 259 | } 260 | 261 | a.getValue(R.styleable.DropdownTextView_underline_link, typeValue) 262 | isLinkUnderline = when (typeValue.type) { 263 | TypedValue.TYPE_INT_BOOLEAN -> typeValue.data == 1 264 | else -> true 265 | } 266 | 267 | contentTextSizeRes = a.getResourceId(R.styleable.DropdownTextView_content_text_size, -1) 268 | contentFontRes = a.getResourceId(R.styleable.DropdownTextView_content_font, -1) 269 | 270 | bgRegularDrawableRes = a.getResourceId(R.styleable.DropdownTextView_bg_drawable_regular, -1) 271 | bgExpandedDrawableRes = a.getResourceId( 272 | R.styleable.DropdownTextView_bg_drawable_expanded, 273 | -1 274 | ) 275 | 276 | panelPaddingRes = a.getResourceId( 277 | R.styleable.DropdownTextView_panel_padding, 278 | R.dimen.panel_default_padding 279 | ) 280 | contentPaddingRes = a.getResourceId( 281 | R.styleable.DropdownTextView_content_padding, 282 | R.dimen.content_default_padding 283 | ) 284 | 285 | arrowDrawableRes = a.getResourceId( 286 | R.styleable.DropdownTextView_arrow_drawable, 287 | R.drawable.ic_arrow 288 | ) 289 | 290 | expandDuration = a.getInteger(R.styleable.DropdownTextView_expand_duration, 300) 291 | } 292 | 293 | private fun initialize() { 294 | inflateView() 295 | bindView() 296 | setResources() 297 | 298 | post { 299 | if (isExpanded) { 300 | expandInternal(false) 301 | } else { 302 | collapseInternal(false) 303 | } 304 | setArrowViewState(isExpanded, false) 305 | setBackgroundState(isExpanded) 306 | } 307 | } 308 | 309 | private fun bindView() { 310 | panelView = findViewById(R.id.panel_view) 311 | titleTextView = findViewById(R.id.title_text_view) 312 | contentTextView = findViewById(R.id.content_text_view) 313 | arrowView = findViewById(R.id.arrow_view) 314 | 315 | panelView.setOnClickListener { 316 | if (isExpanded) { 317 | collapse(true) 318 | } else { 319 | expand(true) 320 | } 321 | } 322 | } 323 | 324 | private fun setResources() { 325 | arrowView.setBackgroundResource(arrowDrawableRes) 326 | titleTextView.text = titleText 327 | contentTextView.text = contentText 328 | 329 | titleTextColor?.let { titleTextView.setTextColor(it) } 330 | if (titleTextSizeRes != -1) { 331 | titleTextView.setTextSize( 332 | TypedValue.COMPLEX_UNIT_PX, 333 | context.resources.getDimension(titleTextSizeRes) 334 | ) 335 | } 336 | if (titleFontRes != -1) { 337 | titleTextView.typeface = ResourcesCompat.getFont(context, titleFontRes) 338 | } 339 | 340 | contentTextColor?.let { contentTextView.setTextColor(it) } 341 | if (contentTextSizeRes != -1) { 342 | contentTextView.setTextSize( 343 | TypedValue.COMPLEX_UNIT_PX, 344 | context.resources.getDimension(contentTextSizeRes) 345 | ) 346 | } 347 | if (contentFontRes != -1) { 348 | contentTextView.typeface = ResourcesCompat.getFont(context, contentFontRes) 349 | } 350 | 351 | rawHtmlContent?.let { 352 | setHtmlContent(it) 353 | } 354 | 355 | spannableHtmlContent?.let { 356 | setHtmlContent(it, linkHandler!!) 357 | } 358 | 359 | linkTextColor?.let { 360 | contentTextView.setLinkTextColor(it) 361 | } 362 | 363 | context.resources.getDimension(panelPaddingRes).toInt().apply { 364 | panelView.setPadding(this, this, this, this) 365 | } 366 | context.resources.getDimension(contentPaddingRes).toInt().apply { 367 | contentTextView.setPadding(this, this, this, this) 368 | } 369 | 370 | 371 | } 372 | 373 | private fun inflateView() { 374 | View.inflate(context, R.layout.view_dropdown_text_view, this) 375 | } 376 | 377 | private fun expandInternal(animate: Boolean) { 378 | setHeightToContentHeight(animate) 379 | setArrowViewState(true, animate) 380 | setBackgroundState(true) 381 | setTitleTextState(true) 382 | isExpanded = true 383 | } 384 | 385 | private fun collapseInternal(animate: Boolean) { 386 | setHeightToZero(animate) 387 | setArrowViewState(false, animate) 388 | setBackgroundState(false) 389 | setTitleTextState(false) 390 | isExpanded = false 391 | } 392 | 393 | private fun setBackgroundState(expand: Boolean) { 394 | if (!expand && bgRegularDrawableRes != -1) { 395 | setBackgroundResource(bgRegularDrawableRes) 396 | } else if (bgExpandedDrawableRes != -1) { 397 | setBackgroundResource(bgExpandedDrawableRes) 398 | } 399 | } 400 | 401 | private fun setTitleTextState(expand: Boolean) { 402 | if (expand) { 403 | (titleTextColorExpanded ?: titleTextColor)?.let { titleTextView.setTextColor(it) } 404 | } else { 405 | titleTextColor?.let { titleTextView.setTextColor(it) } 406 | } 407 | } 408 | 409 | private fun setArrowViewState(expand: Boolean, animate: Boolean) { 410 | val angle = if (resources.configuration.layoutDirection == View.LAYOUT_DIRECTION_RTL) { 411 | if (expand) 90.0f else 180.0f 412 | } else { 413 | if (expand) 90.0f else 0.0f 414 | } 415 | 416 | arrowView.animate() 417 | .rotation(angle) 418 | .setDuration((if (animate) expandDuration else 0).toLong()) 419 | .start() 420 | } 421 | 422 | private fun setHeightToZero(animate: Boolean) { 423 | val targetHeight = panelView.height 424 | if (animate) { 425 | animate(this, height, targetHeight, expandDuration) 426 | } else { 427 | setContentHeight(targetHeight) 428 | } 429 | } 430 | 431 | private fun setHeightToContentHeight(animate: Boolean) { 432 | measureContentTextView() 433 | val targetHeight = panelView.height + contentTextView.measuredHeight 434 | if (animate) { 435 | animate(this, height, targetHeight, expandDuration) 436 | } else { 437 | setContentHeight(targetHeight) 438 | } 439 | } 440 | 441 | private fun setContentHeight(height: Int) { 442 | layoutParams.height = height 443 | requestLayout() 444 | } 445 | 446 | private fun animate(view: View, from: Int, to: Int, duration: Int) { 447 | changeValue(from, to, duration.toLong()) { 448 | view.layoutParams.height = it 449 | view.requestLayout() 450 | invalidate() 451 | } 452 | } 453 | 454 | private fun measureContentTextView() { 455 | val widthMS = MeasureSpec.makeMeasureSpec(width, MeasureSpec.AT_MOST) 456 | val heightMS = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED) 457 | contentTextView.measure(widthMS, heightMS) 458 | } 459 | 460 | class Builder(private val context: Context) { 461 | 462 | var expandDuration: Int = -1 463 | private set 464 | var titleTextRes: Int = -1 465 | private set 466 | var titleTextColorRes: Int = -1 467 | private set 468 | var titleTextColorExpandedRes: Int = -1 469 | private set 470 | var titleTextSizeRes: Int = -1 471 | private set 472 | var titleFontRes: Int = -1 473 | private set 474 | var contentTextRes: Int = -1 475 | private set 476 | var contentTextColorRes: Int = -1 477 | private set 478 | var linkTextColorRes: Int = -1 479 | private set 480 | var isLinkUnderline: Boolean = true 481 | private set 482 | var linkHandler: ((url: String) -> Unit)? = null 483 | private set 484 | var contentTextSizeRes: Int = -1 485 | private set 486 | var rawHtmlContent: String? = null 487 | private set 488 | var spannableHtmlContent: String? = null 489 | private set 490 | var contentFontRes: Int = -1 491 | private set 492 | var arrowDrawableRes: Int = -1 493 | private set 494 | var bgRegularDrawableRes: Int = -1 495 | private set 496 | var bgExpandedDrawableRes: Int = -1 497 | private set 498 | var panelPaddingRes: Int = -1 499 | private set 500 | var contentPaddingRes: Int = -1 501 | private set 502 | 503 | fun setExpandDuration(duration: Int): Builder { 504 | this.expandDuration = duration 505 | return this 506 | } 507 | 508 | fun setTitleTextRes(@StringRes colorRes: Int): Builder { 509 | this.titleTextRes = colorRes 510 | return this 511 | } 512 | 513 | fun setTitleTextColorRes(@ColorRes colorRes: Int): Builder { 514 | this.titleTextColorRes = colorRes 515 | return this 516 | } 517 | 518 | fun setTitleTextColorExpandedRes(@ColorRes colorRes: Int): Builder { 519 | this.titleTextColorExpandedRes = colorRes 520 | return this 521 | } 522 | 523 | fun setTitleTextSizeRes(@DimenRes sizeRes: Int): Builder { 524 | this.titleTextSizeRes = sizeRes 525 | return this 526 | } 527 | 528 | fun setTitleFontRes(@FontRes fontRes: Int): Builder { 529 | this.titleFontRes = fontRes 530 | return this 531 | } 532 | 533 | fun setContentTextRes(@StringRes colorRes: Int): Builder { 534 | this.contentTextRes = colorRes 535 | return this 536 | } 537 | 538 | fun setContentTextColorRes(@ColorRes colorRes: Int): Builder { 539 | this.contentTextColorRes = colorRes 540 | return this 541 | } 542 | 543 | fun setLinkTextColorRes(@ColorRes colorRes: Int): Builder { 544 | this.linkTextColorRes = colorRes 545 | return this 546 | } 547 | 548 | fun setLinkUnderline(value: Boolean): Builder { 549 | this.isLinkUnderline = value 550 | return this 551 | } 552 | 553 | fun setContentTextSizeRes(@DimenRes sizeRes: Int): Builder { 554 | this.contentTextSizeRes = sizeRes 555 | return this 556 | } 557 | 558 | fun setHtmlContent(text: String): Builder { 559 | this.rawHtmlContent = text 560 | return this 561 | } 562 | 563 | fun setHtmlContent(text: String, linkHandler: (url: String) -> Unit): Builder { 564 | this.spannableHtmlContent = text 565 | this.linkHandler = linkHandler 566 | return this 567 | } 568 | 569 | fun setContentFontRes(@FontRes fontRes: Int): Builder { 570 | this.contentFontRes = fontRes 571 | return this 572 | } 573 | 574 | fun setArrowDrawableRes(@DrawableRes drawableRes: Int): Builder { 575 | this.arrowDrawableRes = drawableRes 576 | return this 577 | } 578 | 579 | fun setRegularBackgroundDrawableRes(@DrawableRes drawableRes: Int): Builder { 580 | this.bgRegularDrawableRes = drawableRes 581 | return this 582 | } 583 | 584 | fun setExpandedBackgroundDrawableRes(@DrawableRes drawableRes: Int): Builder { 585 | this.bgExpandedDrawableRes = drawableRes 586 | return this 587 | } 588 | 589 | fun setPanelPaddingRes(@DimenRes paddingRes: Int): Builder { 590 | this.panelPaddingRes = paddingRes 591 | return this 592 | } 593 | 594 | fun setContentPaddingRes(@DimenRes paddingRes: Int): Builder { 595 | this.contentPaddingRes = paddingRes 596 | return this 597 | } 598 | 599 | fun build(): DropdownTextView { 600 | return DropdownTextView(context, this) 601 | } 602 | } 603 | } -------------------------------------------------------------------------------- /dropdown-textview/src/main/res/drawable-hdpi/ic_arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hakobast/DropdownTextView/3ff35055afc1b2caac9eb5328c1740e8fc55006c/dropdown-textview/src/main/res/drawable-hdpi/ic_arrow.png -------------------------------------------------------------------------------- /dropdown-textview/src/main/res/drawable-mdpi/ic_arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hakobast/DropdownTextView/3ff35055afc1b2caac9eb5328c1740e8fc55006c/dropdown-textview/src/main/res/drawable-mdpi/ic_arrow.png -------------------------------------------------------------------------------- /dropdown-textview/src/main/res/drawable-xhdpi/ic_arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hakobast/DropdownTextView/3ff35055afc1b2caac9eb5328c1740e8fc55006c/dropdown-textview/src/main/res/drawable-xhdpi/ic_arrow.png -------------------------------------------------------------------------------- /dropdown-textview/src/main/res/drawable-xxhdpi/ic_arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hakobast/DropdownTextView/3ff35055afc1b2caac9eb5328c1740e8fc55006c/dropdown-textview/src/main/res/drawable-xxhdpi/ic_arrow.png -------------------------------------------------------------------------------- /dropdown-textview/src/main/res/layout/view_dropdown_text_view.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 15 | 16 | 26 | 27 | 34 | 35 | 36 | 37 | 43 | 44 | -------------------------------------------------------------------------------- /dropdown-textview/src/main/res/values/attrs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /dropdown-textview/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 25dp 4 | 12dp 5 | 12dp 6 | -------------------------------------------------------------------------------- /dropdown-textview/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | DropdownTextView 3 | 4 | -------------------------------------------------------------------------------- /dropdown-textview/src/test/java/hakobastvatsatryan/dropdowntextview/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package hakobastvatsatryan.dropdowntextview; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * @see Testing documentation 11 | */ 12 | public class ExampleUnitTest { 13 | @Test 14 | public void addition_isCorrect() throws Exception { 15 | assertEquals(4, 2 + 2); 16 | } 17 | } -------------------------------------------------------------------------------- /example-screens/example-1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hakobast/DropdownTextView/3ff35055afc1b2caac9eb5328c1740e8fc55006c/example-screens/example-1.gif -------------------------------------------------------------------------------- /example-screens/example-2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hakobast/DropdownTextView/3ff35055afc1b2caac9eb5328c1740e8fc55006c/example-screens/example-2.gif -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | android.enableJetifier=true 13 | android.useAndroidX=true 14 | org.gradle.jvmargs=-Xmx1536m 15 | # When configured, Gradle will run in incubating parallel mode. 16 | # This option should only be used with decoupled projects. More details, visit 17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 18 | # org.gradle.parallel=true 19 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hakobast/DropdownTextView/3ff35055afc1b2caac9eb5328c1740e8fc55006c/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Mar 20 15:46:28 ART 2020 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip 7 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 10 | DEFAULT_JVM_OPTS="" 11 | 12 | APP_NAME="Gradle" 13 | APP_BASE_NAME=`basename "$0"` 14 | 15 | # Use the maximum available, or set MAX_FD != -1 to use that value. 16 | MAX_FD="maximum" 17 | 18 | warn ( ) { 19 | echo "$*" 20 | } 21 | 22 | die ( ) { 23 | echo 24 | echo "$*" 25 | echo 26 | exit 1 27 | } 28 | 29 | # OS specific support (must be 'true' or 'false'). 30 | cygwin=false 31 | msys=false 32 | darwin=false 33 | case "`uname`" in 34 | CYGWIN* ) 35 | cygwin=true 36 | ;; 37 | Darwin* ) 38 | darwin=true 39 | ;; 40 | MINGW* ) 41 | msys=true 42 | ;; 43 | esac 44 | 45 | # Attempt to set APP_HOME 46 | # Resolve links: $0 may be a link 47 | PRG="$0" 48 | # Need this for relative symlinks. 49 | while [ -h "$PRG" ] ; do 50 | ls=`ls -ld "$PRG"` 51 | link=`expr "$ls" : '.*-> \(.*\)$'` 52 | if expr "$link" : '/.*' > /dev/null; then 53 | PRG="$link" 54 | else 55 | PRG=`dirname "$PRG"`"/$link" 56 | fi 57 | done 58 | SAVED="`pwd`" 59 | cd "`dirname \"$PRG\"`/" >/dev/null 60 | APP_HOME="`pwd -P`" 61 | cd "$SAVED" >/dev/null 62 | 63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 64 | 65 | # Determine the Java command to use to start the JVM. 66 | if [ -n "$JAVA_HOME" ] ; then 67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 68 | # IBM's JDK on AIX uses strange locations for the executables 69 | JAVACMD="$JAVA_HOME/jre/sh/java" 70 | else 71 | JAVACMD="$JAVA_HOME/bin/java" 72 | fi 73 | if [ ! -x "$JAVACMD" ] ; then 74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 75 | 76 | Please set the JAVA_HOME variable in your environment to match the 77 | location of your Java installation." 78 | fi 79 | else 80 | JAVACMD="java" 81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 82 | 83 | Please set the JAVA_HOME variable in your environment to match the 84 | location of your Java installation." 85 | fi 86 | 87 | # Increase the maximum file descriptors if we can. 88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then 89 | MAX_FD_LIMIT=`ulimit -H -n` 90 | if [ $? -eq 0 ] ; then 91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 92 | MAX_FD="$MAX_FD_LIMIT" 93 | fi 94 | ulimit -n $MAX_FD 95 | if [ $? -ne 0 ] ; then 96 | warn "Could not set maximum file descriptor limit: $MAX_FD" 97 | fi 98 | else 99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 100 | fi 101 | fi 102 | 103 | # For Darwin, add options to specify how the application appears in the dock 104 | if $darwin; then 105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 106 | fi 107 | 108 | # For Cygwin, switch paths to Windows format before running java 109 | if $cygwin ; then 110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 112 | JAVACMD=`cygpath --unix "$JAVACMD"` 113 | 114 | # We build the pattern for arguments to be converted via cygpath 115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 116 | SEP="" 117 | for dir in $ROOTDIRSRAW ; do 118 | ROOTDIRS="$ROOTDIRS$SEP$dir" 119 | SEP="|" 120 | done 121 | OURCYGPATTERN="(^($ROOTDIRS))" 122 | # Add a user-defined pattern to the cygpath arguments 123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 125 | fi 126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 127 | i=0 128 | for arg in "$@" ; do 129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 131 | 132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 134 | else 135 | eval `echo args$i`="\"$arg\"" 136 | fi 137 | i=$((i+1)) 138 | done 139 | case $i in 140 | (0) set -- ;; 141 | (1) set -- "$args0" ;; 142 | (2) set -- "$args0" "$args1" ;; 143 | (3) set -- "$args0" "$args1" "$args2" ;; 144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 150 | esac 151 | fi 152 | 153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 154 | function splitJvmOpts() { 155 | JVM_OPTS=("$@") 156 | } 157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 159 | 160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 161 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app', ':dropdown-textview' 2 | --------------------------------------------------------------------------------