├── app
├── .gitignore
├── src
│ ├── main
│ │ ├── res
│ │ │ ├── drawable
│ │ │ │ └── pro.jpeg
│ │ │ ├── values
│ │ │ │ ├── strings.xml
│ │ │ │ ├── styles.xml
│ │ │ │ └── colors.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
│ │ │ └── layout
│ │ │ │ ├── activity_main.xml
│ │ │ │ └── item_one.xml
│ │ ├── AndroidManifest.xml
│ │ └── java
│ │ │ └── com
│ │ │ └── kevinho
│ │ │ └── view
│ │ │ └── tvrecyclerviewdemo
│ │ │ ├── DefaultItemDecoration.java
│ │ │ ├── MainActivity.java
│ │ │ └── SimpleTVRecyclerViewAdapter.java
│ ├── test
│ │ └── java
│ │ │ └── com
│ │ │ └── kevinho
│ │ │ └── view
│ │ │ └── tvrecyclerviewdemo
│ │ │ └── ExampleUnitTest.java
│ └── androidTest
│ │ └── java
│ │ └── com
│ │ └── kevinho
│ │ └── view
│ │ └── tvrecyclerviewdemo
│ │ └── ExampleInstrumentedTest.java
├── proguard-rules.pro
└── build.gradle
├── tvrecyclerview
├── .gitignore
├── src
│ ├── main
│ │ ├── res
│ │ │ ├── values
│ │ │ │ └── strings.xml
│ │ │ └── drawable
│ │ │ │ ├── rv_item_bg.xml
│ │ │ │ └── rv_item_border.xml
│ │ ├── AndroidManifest.xml
│ │ └── java
│ │ │ └── com
│ │ │ └── kevinho
│ │ │ └── view
│ │ │ └── tvrecyclerview
│ │ │ ├── TVRecyclerViewAdapter.java
│ │ │ └── TVRecyclerView.java
│ ├── test
│ │ └── java
│ │ │ └── com
│ │ │ └── kevinho
│ │ │ └── view
│ │ │ └── tvrecyclerview
│ │ │ └── ExampleUnitTest.java
│ └── androidTest
│ │ └── java
│ │ └── com
│ │ └── kevinho
│ │ └── view
│ │ └── tvrecyclerview
│ │ └── ExampleInstrumentedTest.java
├── proguard-rules.pro
└── build.gradle
├── settings.gradle
├── .idea
├── copyright
│ └── profiles_settings.xml
├── vcs.xml
├── runConfigurations.xml
├── modules.xml
├── gradle.xml
├── compiler.xml
└── misc.xml
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── .gitignore
├── gradle.properties
├── LICENSE
├── gradlew.bat
├── README.md
└── gradlew
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/tvrecyclerview/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app', ':tvrecyclerview'
2 |
--------------------------------------------------------------------------------
/.idea/copyright/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/pro.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kevinhqf/TVRecyclerView/HEAD/app/src/main/res/drawable/pro.jpeg
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | TVRecyclerViewDemo
3 |
4 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kevinhqf/TVRecyclerView/HEAD/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/tvrecyclerview/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | TVRecyclerView
3 |
4 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kevinhqf/TVRecyclerView/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kevinhqf/TVRecyclerView/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kevinhqf/TVRecyclerView/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kevinhqf/TVRecyclerView/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kevinhqf/TVRecyclerView/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kevinhqf/TVRecyclerView/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kevinhqf/TVRecyclerView/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kevinhqf/TVRecyclerView/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kevinhqf/TVRecyclerView/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kevinhqf/TVRecyclerView/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/.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/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/tvrecyclerview/src/main/res/drawable/rv_item_bg.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Thu Nov 02 16:56:17 CST 2017
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-3.3-all.zip
7 |
--------------------------------------------------------------------------------
/tvrecyclerview/src/main/res/drawable/rv_item_border.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/tvrecyclerview/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/app/src/test/java/com/kevinho/view/tvrecyclerviewdemo/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.kevinho.view.tvrecyclerviewdemo;
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 | }
--------------------------------------------------------------------------------
/tvrecyclerview/src/test/java/com/kevinho/view/tvrecyclerview/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.kevinho.view.tvrecyclerview;
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 | }
--------------------------------------------------------------------------------
/.idea/runConfigurations.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
11 |
12 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 | #af51616b
7 | #0793ea
8 | #07eabd
9 | #ea0756
10 | #e2ea07
11 | #07ea5a
12 | #ea8b07
13 | #b907ea
14 | #5f30ec
15 | #ec55f4
16 | #f14616
17 |
18 |
--------------------------------------------------------------------------------
/.idea/gradle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/.idea/compiler.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/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 | org.gradle.jvmargs=-Xmx1536m
13 |
14 | # When configured, Gradle will run in incubating parallel mode.
15 | # This option should only be used with decoupled projects. More details, visit
16 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
17 | # org.gradle.parallel=true
18 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/app/src/main/java/com/kevinho/view/tvrecyclerviewdemo/DefaultItemDecoration.java:
--------------------------------------------------------------------------------
1 | package com.kevinho.view.tvrecyclerviewdemo;
2 |
3 | import android.graphics.Rect;
4 | import android.support.v7.widget.RecyclerView;
5 |
6 | /**
7 | * the recyclerView decoration
8 | */
9 | public class DefaultItemDecoration extends RecyclerView.ItemDecoration {
10 |
11 | int left = 0;
12 | int top = 0;
13 | int right = 0;
14 | int bottom = 0;
15 |
16 | public DefaultItemDecoration(int left, int top, int right, int bottom) {
17 | this.left = left;
18 | this.top = top;
19 | this.right = right;
20 | this.bottom = bottom;
21 | }
22 |
23 | @Override
24 | public void getItemOffsets(Rect outRect, int itemPosition, RecyclerView parent) {
25 |
26 | outRect.set(left, top, right, bottom);
27 |
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_one.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
12 |
13 |
23 |
--------------------------------------------------------------------------------
/app/src/androidTest/java/com/kevinho/view/tvrecyclerviewdemo/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package com.kevinho.view.tvrecyclerviewdemo;
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.kevinho.view.tvrecyclerviewdemo", appContext.getPackageName());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/tvrecyclerview/src/androidTest/java/com/kevinho/view/tvrecyclerview/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package com.kevinho.view.tvrecyclerview;
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.kevinho.view.tvrecyclerview.test", appContext.getPackageName());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/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 C:\Workspace\Data\Android\sdk/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 |
--------------------------------------------------------------------------------
/tvrecyclerview/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 C:\Workspace\Data\Android\sdk/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/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 25
5 | buildToolsVersion '25.0.3'
6 | defaultConfig {
7 | applicationId "com.kevinho.view.tvrecyclerviewdemo"
8 | minSdkVersion 19
9 | targetSdkVersion 25
10 | versionCode 1
11 | versionName "1.0"
12 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
13 | }
14 | buildTypes {
15 | release {
16 | minifyEnabled false
17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
18 | }
19 | }
20 | }
21 |
22 | dependencies {
23 | compile fileTree(include: ['*.jar'], dir: 'libs')
24 | androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
25 | exclude group: 'com.android.support', module: 'support-annotations'
26 | })
27 | testCompile 'junit:junit:4.12'
28 | compile 'com.android.support:recyclerview-v7:26.0.0-alpha1'
29 | compile project(':tvrecyclerview')
30 | }
31 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 KevinHo
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/app/src/main/java/com/kevinho/view/tvrecyclerviewdemo/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.kevinho.view.tvrecyclerviewdemo;
2 |
3 | import android.app.Activity;
4 | import android.content.Context;
5 | import android.os.Bundle;
6 | import android.support.v7.widget.GridLayoutManager;
7 | import android.support.v7.widget.StaggeredGridLayoutManager;
8 | import android.util.AttributeSet;
9 |
10 | import com.kevinho.view.tvrecyclerview.TVRecyclerView;
11 |
12 | public class MainActivity extends Activity {
13 |
14 |
15 | TVRecyclerView rv;
16 |
17 | @Override
18 | protected void onCreate(Bundle savedInstanceState) {
19 | super.onCreate(savedInstanceState);
20 | setContentView(R.layout.activity_main);
21 | initView();
22 | }
23 |
24 | private void initView() {
25 | rv = (TVRecyclerView) findViewById(R.id.rv_list);
26 | GridLayoutManager manager = new GridLayoutManager(this, 3, GridLayoutManager.HORIZONTAL, false);
27 | manager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
28 | @Override
29 | public int getSpanSize(int position) {
30 | if (position % 5 == 0)
31 | return 2;
32 | return 1;
33 | }
34 | });
35 | rv.setLayoutManager(manager);
36 | rv.setAdapter(new SimpleTVRecyclerViewAdapter(this));
37 | rv.addItemDecoration(new DefaultItemDecoration(5,5, 0, 0));
38 | }
39 |
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/.idea/misc.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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/tvrecyclerview/src/main/java/com/kevinho/view/tvrecyclerview/TVRecyclerViewAdapter.java:
--------------------------------------------------------------------------------
1 | package com.kevinho.view.tvrecyclerview;
2 |
3 | import android.content.Context;
4 | import android.support.v7.widget.RecyclerView;
5 | import android.view.View;
6 | import android.view.ViewGroup;
7 |
8 |
9 |
10 | public abstract class TVRecyclerViewAdapter extends RecyclerView.Adapter {
11 |
12 | private OnItemClickListener mOnItemClickListener;
13 |
14 | public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
15 | mOnItemClickListener = onItemClickListener;
16 | }
17 |
18 | @Override
19 | public void onBindViewHolder(VH holder, final int position) {
20 | holder.itemView.setFocusable(true);
21 |
22 | holder.itemView.setOnClickListener(new View.OnClickListener() {
23 | @Override
24 | public void onClick(View v) {
25 | if (mOnItemClickListener != null) {
26 | mOnItemClickListener.onItemClick(v, position);
27 | }
28 | }
29 | });
30 | holder.itemView.setOnFocusChangeListener(new View.OnFocusChangeListener() {
31 | @Override
32 | public void onFocusChange(View v, boolean hasFocus) {
33 | if (hasFocus) {
34 | focusIn(v,position);
35 | } else {
36 | focusOut(v,position);
37 | }
38 | // 重绘,使item的绘制顺序调整生效
39 | ViewGroup parent = (ViewGroup) v.getParent();
40 | if (parent != null) {
41 | parent.requestLayout();
42 | parent.postInvalidate();
43 | }
44 | }
45 | });
46 | onDataBinding(holder, position);
47 | }
48 |
49 |
50 | /**
51 | * 实现失去焦点时的动画
52 | */
53 | protected abstract void focusOut(View v, int position) ;
54 |
55 | /**
56 | * 实现获取焦点时的动画
57 | */
58 | protected abstract void focusIn(View v, int position) ;
59 |
60 |
61 |
62 | @Override
63 | public long getItemId(int position) {
64 | return position;
65 | }
66 |
67 | /**
68 | * 实现数据与View的绑定
69 | *
70 | * @param holder
71 | * @param position
72 | */
73 | protected abstract void onDataBinding(VH holder, int position);
74 |
75 |
76 |
77 |
78 |
79 | public interface OnItemClickListener {
80 | void onItemClick(View v, int pos);
81 | }
82 |
83 |
84 | public class ViewHolder extends RecyclerView.ViewHolder {
85 | Context mContext;
86 |
87 | public ViewHolder(Context context, View itemView) {
88 | super(itemView);
89 | this.mContext = context;
90 | itemView.setBackground(mContext.getResources().getDrawable(R.drawable.rv_item_bg));
91 | }
92 | }
93 |
94 | }
95 |
--------------------------------------------------------------------------------
/app/src/main/java/com/kevinho/view/tvrecyclerviewdemo/SimpleTVRecyclerViewAdapter.java:
--------------------------------------------------------------------------------
1 | package com.kevinho.view.tvrecyclerviewdemo;
2 |
3 | import android.animation.AnimatorSet;
4 | import android.animation.ObjectAnimator;
5 | import android.content.Context;
6 | import android.graphics.Color;
7 | import android.util.Log;
8 | import android.view.LayoutInflater;
9 | import android.view.View;
10 | import android.view.ViewGroup;
11 | import android.widget.FrameLayout;
12 | import android.widget.TextView;
13 |
14 | import com.kevinho.view.tvrecyclerview.TVRecyclerViewAdapter;
15 |
16 | import java.util.Random;
17 |
18 |
19 | public class SimpleTVRecyclerViewAdapter extends TVRecyclerViewAdapter {
20 | private static final String TAG = "SimpleAdapter";
21 | Context mContext;
22 |
23 | public static final String[] COLORS = {
24 | "#0793ea",
25 | "#07eabd",
26 | "#ea0756",
27 | "#e2ea07",
28 | "#07ea5a",
29 | "#ea8b07",
30 | "#b907ea",
31 | "#5f30ec",
32 | "#ec55f4",
33 | "#f14616"
34 | };
35 |
36 | public SimpleTVRecyclerViewAdapter(Context context) {
37 | mContext = context;
38 | setHasStableIds(true);
39 | setOnItemClickListener(new OnItemClickListener() {
40 | @Override
41 | public void onItemClick(View v, int pos) {
42 | Log.e(TAG, "onItemClick:" + pos);
43 | }
44 | });
45 | }
46 |
47 | @Override
48 | public TVRecyclerViewAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
49 |
50 | return new OneVH(mContext, LayoutInflater.from(mContext).inflate(R.layout.item_one, parent, false));
51 | }
52 |
53 |
54 | @Override
55 | public long getItemId(int position) {
56 | return position;
57 | }
58 |
59 | @Override
60 | protected void focusOut(View v,int pos) {
61 | ObjectAnimator scaleX = ObjectAnimator.ofFloat(v, "scaleX", 1.05f, 1.0f);
62 | ObjectAnimator scaleY = ObjectAnimator.ofFloat(v, "scaleY", 1.05f, 1.0f);
63 | AnimatorSet set = new AnimatorSet();
64 | set.play(scaleX).with(scaleY);
65 | set.start();
66 | }
67 |
68 | @Override
69 | protected void focusIn(View v,int pos) {
70 | ObjectAnimator scaleX = ObjectAnimator.ofFloat(v, "scaleX", 1.0f, 1.05f);
71 | ObjectAnimator scaleY = ObjectAnimator.ofFloat(v, "scaleY", 1.0f, 1.05f);
72 | AnimatorSet set = new AnimatorSet();
73 | set.play(scaleX).with(scaleY);
74 | set.start();
75 | }
76 |
77 | @Override
78 | protected void onDataBinding(TVRecyclerViewAdapter.ViewHolder holder, int position) {
79 | if (holder instanceof OneVH) {
80 | ((OneVH) holder).tv.setText("" + position);
81 | }
82 | }
83 |
84 | @Override
85 | public int getItemCount() {
86 | return 100;
87 | }
88 |
89 | class OneVH extends TVRecyclerViewAdapter.ViewHolder {
90 | TextView tv;
91 | FrameLayout fl;
92 |
93 | public OneVH(Context context, View itemView) {
94 | super(context, itemView);
95 | tv = (TextView) itemView.findViewById(R.id.tv1);
96 | fl = (FrameLayout) itemView.findViewById(R.id.fl);
97 | int i = new Random().nextInt(COLORS.length);
98 | fl.setBackgroundColor(Color.parseColor(COLORS[i]));
99 | }
100 | }
101 |
102 | }
103 |
--------------------------------------------------------------------------------
/tvrecyclerview/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 |
3 | //添加以下两个插件
4 | apply plugin: 'com.github.dcendents.android-maven'
5 | apply plugin: 'com.jfrog.bintray'
6 |
7 | version="0.1.3"
8 | android {
9 | compileSdkVersion 25
10 | buildToolsVersion "25.0.3"
11 |
12 | //资源前缀
13 | resourcePrefix "kevinhqf_"
14 |
15 |
16 | defaultConfig {
17 | minSdkVersion 19
18 | targetSdkVersion 25
19 | versionCode 1
20 | versionName "1.0"
21 |
22 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
23 |
24 | }
25 | buildTypes {
26 | release {
27 | minifyEnabled false
28 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
29 | }
30 | }
31 | //增加lint选项,不加的话下面上传到jCenter有可能会报错
32 | lintOptions {
33 | abortOnError false
34 | }
35 | }
36 | buildscript {
37 | repositories {
38 | jcenter()
39 | }
40 |
41 | }
42 | dependencies {
43 | compile fileTree(dir: 'libs', include: ['*.jar'])
44 | compile 'com.android.support:recyclerview-v7:26.0.0-alpha1'
45 | }
46 |
47 | //你的library的地址
48 | def siteUrl = 'https://github.com/kevinhqf/TVRecyclerView'
49 | def gitUrl = 'https://github.com/kevinhqf/TVRecyclerView.git'
50 | def issueUrl = 'https://github.com/kevinhqf/TVRecyclerView/issues'
51 |
52 | //这个蛮重要的,你上传到jCenter后一些文件存放的路径,如果不写或者写错了的话
53 | //可以不会产生pom文件,后面上传到jCenter后会报错,这个问题我搞了一下午!
54 | group = "kevinho.view.dev"
55 | install {
56 | repositories.mavenInstaller {
57 | // POM.xml文件内容
58 | pom {
59 | project {
60 | packaging 'aar'
61 | // 添加描述,不重要
62 | name 'tv recycler view'
63 | url siteUrl
64 | // 协议
65 | licenses {
66 | license {
67 | name 'The MIT License'
68 | url 'https://opensource.org/licenses/MIT'
69 | }
70 | }
71 | developers {
72 | developer {
73 | id 'kevinhqf' //your user ID
74 | name 'kevinhqf' //your name
75 | email 'kevin.ho.hqf@gmail.com' //your email
76 | }
77 | }
78 | scm {
79 | connection gitUrl
80 | developerConnection gitUrl
81 | url siteUrl
82 | }
83 | }
84 | }
85 | }
86 | }
87 | task sourcesJar(type: Jar) {
88 | from android.sourceSets.main.java.srcDirs
89 | classifier = 'sources'
90 | }
91 |
92 | task javadoc(type: Javadoc) {
93 |
94 | //增加编码,这行很重要,如果是windows系统,同时如果在代码中有中文的话,不加这行,上传会报错
95 | source = android.sourceSets.main.java.srcDirs
96 | classpath += project.files(android.getBootClasspath().join(File.pathSeparator))
97 | options.encoding "UTF-8"
98 | options.charSet 'UTF-8'
99 | options.author true
100 | options.version true
101 | failOnError false
102 | }
103 | task javadocJar(type: Jar, dependsOn: javadoc) {
104 | classifier = 'javadoc'
105 | from javadoc.destinationDir
106 | }
107 | artifacts {
108 | archives javadocJar
109 | archives sourcesJar
110 | }
111 | Properties properties = new Properties()
112 | properties.load(project.rootProject.file('local.properties').newDataInputStream())
113 | bintray {
114 | user = properties.getProperty("bintray.user")
115 | key = properties.getProperty("bintray.apikey")
116 | configurations = ['archives']
117 | pkg {
118 | //发布到Bintray的哪个仓库
119 | repo = "maven"
120 | //发布到Bintray上的名字
121 | name = "tvrecyclerview"
122 | //项目描述
123 | desc = "tv recyclerview"
124 | websiteUrl = siteUrl
125 | vcsUrl = gitUrl
126 | issueTrackerUrl = issueUrl
127 | licenses = ["Apache-2.0"]
128 | //标签
129 | labels = ['android']
130 | publish = true
131 | publicDownloadNumbers = true
132 | }
133 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # TVRecyclerView
2 |
3 | TVRecyclerView is an Android RecyclerView library for TV. It resolves the focus problem
4 | on the TV end(not for all layout manager).
5 |
6 | ### Usage
7 | 1. First you need to add gradle dependency in your project:
8 | ```gradle
9 | dependencies {
10 | ......
11 | compile 'kevinho.view.dev:tvrecyclerview:0.1.2'
12 | }
13 | ```
14 |
15 | 2. Add a tvrecyclerview tag in your layout XML file:
16 | ```xml
17 |
22 | ```
23 |
24 | 3. Then new a Adapter Class that extends TVRecyclerViewAdapter,and then you need
25 | to implement the methods below :
26 | ```java
27 | public class SimpleTVRecyclerViewAdapter extends TVRecyclerViewAdapter{
28 | .....
29 |
30 | @Override
31 | public long getItemId(int position) {
32 | return position;
33 | }
34 |
35 | /*
36 | implement to tell the view how to do
37 | when its state changing from onFocus to lose focus
38 | */
39 | @Override
40 | protected void focusOut(View v) {
41 | ObjectAnimator scaleX = ObjectAnimator.ofFloat(v, "scaleX", 1.05f, 1.0f);
42 | ObjectAnimator scaleY = ObjectAnimator.ofFloat(v, "scaleY", 1.05f, 1.0f);
43 | AnimatorSet set = new AnimatorSet();
44 | set.play(scaleX).with(scaleY);
45 | set.start();
46 | }
47 |
48 | /*
49 | implement to tell the view how to do
50 | when its state changing from unFocus to get focus
51 | */
52 | @Override
53 | protected void focusIn(View v) {
54 | ObjectAnimator scaleX = ObjectAnimator.ofFloat(v, "scaleX", 1.0f, 1.05f);
55 | ObjectAnimator scaleY = ObjectAnimator.ofFloat(v, "scaleY", 1.0f, 1.05f);
56 | AnimatorSet set = new AnimatorSet();
57 | set.play(scaleX).with(scaleY);
58 | set.start();
59 | }
60 |
61 | /**
62 | * to bind data to the item view
63 | */
64 | @Override
65 | protected void onDataBinding(TVRecyclerViewAdapter.ViewHolder holder, int position) {
66 | if (holder instanceof OneVH) {
67 | ((OneVH) holder).tv.setText("" + position);
68 | }
69 | }
70 |
71 | .....
72 | }
73 | ```
74 |
75 | 4. Finally use the TVRecyclerView just like the default recyclerview:
76 | ```java
77 | rv = (TVRecyclerView) findViewById(R.id.rv_list);
78 | GridLayoutManager manager = new GridLayoutManager(this, 3, GridLayoutManager.HORIZONTAL, false);
79 | manager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
80 | @Override
81 | public int getSpanSize(int position) {
82 | if (position % 5 == 0)
83 | return 2;
84 | return 1;
85 | }
86 | });
87 | // set the layout manager
88 | rv.setLayoutManager(manager);
89 | // set the adapter
90 | rv.setAdapter(new SimpleTVRecyclerViewAdapter(this));
91 | // add a decoration
92 | rv.addItemDecoration(new DefaultItemDecoration(5,5, 0, 0));
93 | ```
94 |
95 | You can download the code to see how the TVRecyclerView works and there is a
96 | Demo too.
97 |
98 | ### ScreenShot
99 | 
100 |
101 | ### License
102 | ```
103 | MIT License
104 |
105 | Copyright (c) [2017] [KevinHo]
106 |
107 | Permission is hereby granted, free of charge, to any person obtaining a copy
108 | of this software and associated documentation files (the "Software"), to deal
109 | in the Software without restriction, including without limitation the rights
110 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
111 | copies of the Software, and to permit persons to whom the Software is
112 | furnished to do so, subject to the following conditions:
113 |
114 | The above copyright notice and this permission notice shall be included in all
115 | copies or substantial portions of the Software.
116 |
117 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
118 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
119 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
120 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
121 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
122 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
123 | SOFTWARE.
124 | ```
125 |
--------------------------------------------------------------------------------
/tvrecyclerview/src/main/java/com/kevinho/view/tvrecyclerview/TVRecyclerView.java:
--------------------------------------------------------------------------------
1 | package com.kevinho.view.tvrecyclerview;
2 |
3 | import android.content.Context;
4 | import android.graphics.Point;
5 | import android.os.Build;
6 | import android.support.annotation.Nullable;
7 | import android.support.v7.widget.RecyclerView;
8 | import android.util.AttributeSet;
9 | import android.view.FocusFinder;
10 | import android.view.KeyEvent;
11 | import android.view.View;
12 |
13 |
14 |
15 | public class TVRecyclerView extends RecyclerView {
16 | private static final String TAG = "TVRecyclerView";
17 |
18 | public TVRecyclerView(Context context) {
19 | this(context, null);
20 | }
21 |
22 | public TVRecyclerView(Context context, @Nullable AttributeSet attrs) {
23 | this(context, attrs, 0);
24 | }
25 |
26 | public TVRecyclerView(Context context, @Nullable AttributeSet attrs, int defStyle) {
27 | super(context, attrs, defStyle);
28 | init();
29 | }
30 |
31 | private void init() {
32 | setDescendantFocusability(FOCUS_AFTER_DESCENDANTS);
33 | //setHasFixedSize(true);
34 | //setWillNotDraw(true);
35 | setChildrenDrawingOrderEnabled(true);
36 |
37 | setClipChildren(false);
38 | setClipToPadding(false);
39 |
40 | setItemAnimator(null);
41 | }
42 |
43 | private OnInterceptListener mOnInterceptListener;
44 |
45 | public void setOnInterceptListener(OnInterceptListener onInterceptListener) {
46 | mOnInterceptListener = onInterceptListener;
47 | }
48 |
49 | private boolean keyCodeOfDPAD(KeyEvent event) {
50 | return event.getKeyCode() == KeyEvent.KEYCODE_DPAD_RIGHT
51 | || event.getKeyCode() == KeyEvent.KEYCODE_DPAD_LEFT
52 | || event.getKeyCode() == KeyEvent.KEYCODE_DPAD_DOWN
53 | || event.getKeyCode() == KeyEvent.KEYCODE_DPAD_UP;
54 | }
55 |
56 | @Override
57 | public boolean dispatchKeyEvent(KeyEvent event) {
58 | if (mOnInterceptListener != null && mOnInterceptListener.onIntercept(event)) {
59 | return true;
60 | }
61 | boolean result = super.dispatchKeyEvent(event);
62 | View focusView = this.getFocusedChild();
63 | if (focusView == null) {
64 | return result;
65 | } else {
66 | // TODO: 2017-11-3 解决不同viewType的item滑动
67 | int dy = 0;
68 | int dx = 0;
69 | if (getChildCount() > 0) {
70 | View firstView = this.getChildAt(0);
71 | dy = firstView.getHeight();
72 | dx = firstView.getWidth();
73 | }
74 | if (event.getAction() == KeyEvent.ACTION_UP
75 | && keyCodeOfDPAD(event)) {
76 | return true;
77 | } else {
78 | switch (event.getKeyCode()) {
79 | case KeyEvent.KEYCODE_DPAD_RIGHT:
80 | return findNextFocusView(focusView, new Point(dx, 0), View.FOCUS_RIGHT);
81 | case KeyEvent.KEYCODE_DPAD_LEFT:
82 | return findNextFocusView(focusView, new Point(-dx, 0), View.FOCUS_LEFT);
83 | case KeyEvent.KEYCODE_DPAD_DOWN:
84 | return findNextFocusView(focusView, new Point(0, dy), View.FOCUS_DOWN);
85 | case KeyEvent.KEYCODE_DPAD_UP:
86 | return findNextFocusView(focusView, new Point(0, -dy), View.FOCUS_UP);
87 | }
88 | }
89 | }
90 |
91 |
92 | return result;
93 | }
94 |
95 | @Override
96 | public boolean isInTouchMode() {
97 | boolean result = super.isInTouchMode();
98 | // 解决4.4版本抢焦点的问题
99 | if (Build.VERSION.SDK_INT == 19) {
100 | return !(hasFocus() && !result);
101 | } else {
102 | return result;
103 | }
104 | }
105 | /**
106 | * 找到下一个焦点的itemView
107 | *
108 | * @param focusView
109 | * @param vector
110 | * @param direction
111 | * @return
112 | */
113 | private boolean findNextFocusView(View focusView, Point vector, int direction) {
114 | View nextFocus = FocusFinder.getInstance()
115 | .findNextFocus(this, focusView, direction);
116 | // Log.i(TAG, "right is null:" + (rightView == null));
117 | if (nextFocus != null) {
118 | nextFocus.requestFocus();
119 | return true;
120 | } else {
121 | this.smoothScrollBy(vector.x, vector.y);
122 | return true;
123 | }
124 | }
125 |
126 | /**
127 | * 修改item的绘制顺序,让获取焦点的item在最后进行绘制
128 | *
129 | * @param childCount
130 | * @param i
131 | * @return
132 | */
133 | @Override
134 | protected int getChildDrawingOrder(int childCount, int i) {
135 | View view = getFocusedChild();
136 |
137 | int position = indexOfChild(view);
138 | if (position < 0) {
139 | return i;
140 | } else {
141 | if (i == childCount - 1) {//这是最后一个需要刷新的item
142 | return position;
143 | }
144 | if (i == position) {
145 | return childCount - 1;
146 | }
147 | }
148 | return i;//正常次序的item
149 | }
150 |
151 | /**
152 | * 可以实现此接口来实现自己的KeyEvent逻辑
153 | */
154 | public interface OnInterceptListener {
155 | boolean onIntercept(KeyEvent event);
156 | }
157 |
158 | }
159 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------