├── .gitignore
├── .idea
├── compiler.xml
├── copyright
│ └── profiles_settings.xml
├── dictionaries
│ └── zhangjy.xml
├── gradle.xml
├── misc.xml
├── modules.xml
└── runConfigurations.xml
├── README.md
├── app
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── fb
│ │ └── jjyyzjy
│ │ └── buildlayoutdemo
│ │ └── ExampleInstrumentedTest.java
│ ├── main
│ ├── AndroidManifest.xml
│ ├── java
│ │ └── com
│ │ │ └── fb
│ │ │ └── jjyyzjy
│ │ │ └── buildlayoutdemo
│ │ │ ├── BuildLayoutAdapter.java
│ │ │ ├── MainActivity.java
│ │ │ ├── utils
│ │ │ ├── CastUtils.java
│ │ │ ├── DebugLog.java
│ │ │ ├── DisplayUtil.java
│ │ │ └── FocusScaleUtils.java
│ │ │ └── view
│ │ │ ├── bring
│ │ │ ├── BringToFrontHelper.java
│ │ │ ├── BringToFrontLinear.java
│ │ │ ├── BringToFrontLinearLayout.java
│ │ │ ├── BringToFrontRelative.java
│ │ │ └── BringToFrontRelativeLayout.java
│ │ │ └── buildview
│ │ │ ├── BaseBuildLayoutAdapter.java
│ │ │ ├── BuildAdapterDataObserver.java
│ │ │ ├── BuildItemPoll.java
│ │ │ ├── BuildLayout.java
│ │ │ ├── BuildLayoutUtils.java
│ │ │ ├── FocusSearchUtils.java
│ │ │ ├── MyBuildLayout.java
│ │ │ ├── OnDismissFocusListener2.java
│ │ │ ├── OnOutOfBoundListener.java
│ │ │ └── Parameter.java
│ └── res
│ │ ├── layout
│ │ └── activity_main.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-1024x575
│ │ ├── dimens.xml
│ │ └── strings.xml
│ │ ├── values-1024x600
│ │ ├── dimens.xml
│ │ └── strings.xml
│ │ ├── values-1024x720
│ │ ├── dimens.xml
│ │ └── strings.xml
│ │ ├── values-1152x648
│ │ ├── dimens.xml
│ │ └── strings.xml
│ │ ├── values-1196x720
│ │ ├── dimens.xml
│ │ └── strings.xml
│ │ ├── values-1196x768
│ │ ├── dimens.xml
│ │ └── strings.xml
│ │ ├── values-1200x720
│ │ ├── dimens.xml
│ │ └── strings.xml
│ │ ├── values-1203x676
│ │ ├── dimens.xml
│ │ └── strings.xml
│ │ ├── values-1216x684
│ │ ├── dimens.xml
│ │ └── strings.xml
│ │ ├── values-1220x690
│ │ ├── dimens.xml
│ │ └── strings.xml
│ │ ├── values-1228x691
│ │ ├── dimens.xml
│ │ └── strings.xml
│ │ ├── values-1241x698
│ │ ├── dimens.xml
│ │ └── strings.xml
│ │ ├── values-1267x712
│ │ ├── dimens.xml
│ │ └── strings.xml
│ │ ├── values-1278x718
│ │ ├── dimens.xml
│ │ └── strings.xml
│ │ ├── values-1280x656
│ │ ├── dimens.xml
│ │ └── strings.xml
│ │ ├── values-1280x672
│ │ ├── dimens.xml
│ │ └── strings.xml
│ │ ├── values-1280x719
│ │ ├── dimens.xml
│ │ └── strings.xml
│ │ ├── values-1280x720
│ │ ├── dimens.xml
│ │ └── strings.xml
│ │ ├── values-1280x736
│ │ ├── dimens.xml
│ │ └── strings.xml
│ │ ├── values-1280x800
│ │ ├── dimens.xml
│ │ └── strings.xml
│ │ ├── values-1366x768
│ │ ├── dimens.xml
│ │ └── strings.xml
│ │ ├── values-1794x1080
│ │ ├── dimens.xml
│ │ └── strings.xml
│ │ ├── values-1820x1030
│ │ ├── dimens.xml
│ │ └── strings.xml
│ │ ├── values-1832x1028
│ │ ├── dimens.xml
│ │ └── strings.xml
│ │ ├── values-1840x1060
│ │ ├── dimens.xml
│ │ └── strings.xml
│ │ ├── values-1916x1076
│ │ ├── dimens.xml
│ │ └── strings.xml
│ │ ├── values-1916x1080
│ │ ├── dimens.xml
│ │ └── strings.xml
│ │ ├── values-1920x1008
│ │ ├── dimens.xml
│ │ └── strings.xml
│ │ ├── values-1920x1080
│ │ ├── dimens.xml
│ │ └── strings.xml
│ │ ├── values-1920x1128
│ │ ├── dimens.xml
│ │ └── strings.xml
│ │ ├── values-2048x1460
│ │ ├── dimens.xml
│ │ └── strings.xml
│ │ ├── values-2560x1440
│ │ ├── dimens.xml
│ │ └── strings.xml
│ │ ├── values-2560x1600
│ │ ├── dimens.xml
│ │ └── strings.xml
│ │ ├── values-3840x2160
│ │ ├── dimens.xml
│ │ └── strings.xml
│ │ ├── values-791x480
│ │ ├── dimens.xml
│ │ └── strings.xml
│ │ ├── values-800x432
│ │ ├── dimens.xml
│ │ └── strings.xml
│ │ ├── values-800x444
│ │ ├── dimens.xml
│ │ └── strings.xml
│ │ ├── values-800x480
│ │ ├── dimens.xml
│ │ └── strings.xml
│ │ ├── values-854x480
│ │ ├── dimens.xml
│ │ └── strings.xml
│ │ ├── values-960x540
│ │ ├── dimens.xml
│ │ └── strings.xml
│ │ ├── values-960x640
│ │ ├── dimens.xml
│ │ └── strings.xml
│ │ └── values
│ │ ├── colors.xml
│ │ ├── ids.xml
│ │ ├── strings.xml
│ │ └── styles.xml
│ └── test
│ └── java
│ └── com
│ └── fb
│ └── jjyyzjy
│ └── buildlayoutdemo
│ └── ExampleUnitTest.java
├── build.gradle
├── build_layout_use_1.png
├── build_layout_use_2.png
├── build_use.gif
├── build_use.mp4
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── settings.gradle
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/workspace.xml
5 | /.idea/libraries
6 | .DS_Store
7 | /build
8 | /captures
9 | .externalNativeBuild
10 |
--------------------------------------------------------------------------------
/.idea/compiler.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/.idea/copyright/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/.idea/dictionaries/zhangjy.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/.idea/gradle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
17 |
18 |
--------------------------------------------------------------------------------
/.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 | Android > Lint > Correctness
39 |
40 |
41 | Android > Lint > Security
42 |
43 |
44 | Class metricsJava
45 |
46 |
47 | Data flow issuesJava
48 |
49 |
50 | Error handlingJava
51 |
52 |
53 | HTML
54 |
55 |
56 | Java
57 |
58 |
59 | Method metricsJava
60 |
61 |
62 | Modularization issuesJava
63 |
64 |
65 | Security issuesJava
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 | $USER_HOME$/.subversion
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 | 1.8
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 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.idea/runConfigurations.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # AndroidTvLayout
2 | ## TV动态布局 Android TV Layout BuildLayout DynamicLayout
3 | ###### 使用简单
4 | ###### item复用
5 | ###### 布局改变焦点不会乱
6 | ###### 支持控制焦点移动
7 | ###### 支持item缩放
8 | ###### 支持xml和动态设置布局大小item宽高间距等
9 |
10 | ```xml
11 |
24 | ```
25 | ```java
26 | int[][] data = {{0,0,1,1},{0,1,1,1},{0,2,1,1},{1,0,2,1},{1,1,2,1},{1,2,1,1},{2,2,1,1},{3,0,2,2},{3,2,2,1},{5,0,1,3}};
27 | MyBuildLayout buildLayout = (MyBuildLayout) findViewById(R.id.build_layout);
28 | BuildLayoutAdapter adapter = new BuildLayoutAdapter();
29 | buildLayout.setAdapter(adapter);
30 | adapter.setData(data);
31 | adapter.notifyDataSetChanged();
32 |
33 | buildLayout.mySetLayoutSize(6,3);
34 | buildLayout.mySetItemSize(250),151);
35 | buildLayout.mySetDividing(30);
36 | ```
37 | 
38 |
39 | 
40 |
41 | 
42 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 26
5 | buildToolsVersion "26.0.2"
6 | defaultConfig {
7 | applicationId "com.fb.jjyyzjy.buildlayoutdemo"
8 | minSdkVersion 15
9 | targetSdkVersion 26
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(dir: 'libs', include: ['*.jar'])
24 | androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
25 | exclude group: 'com.android.support', module: 'support-annotations'
26 | })
27 | compile 'com.android.support:appcompat-v7:26.+'
28 | compile 'com.android.support.constraint:constraint-layout:1.0.2'
29 | testCompile 'junit:junit:4.12'
30 | }
31 |
--------------------------------------------------------------------------------
/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 /Users/zhangjy/Library/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/src/androidTest/java/com/fb/jjyyzjy/buildlayoutdemo/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package com.fb.jjyyzjy.buildlayoutdemo;
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.fb.jjyyzjy.buildlayoutdemo", appContext.getPackageName());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/app/src/main/java/com/fb/jjyyzjy/buildlayoutdemo/BuildLayoutAdapter.java:
--------------------------------------------------------------------------------
1 | package com.fb.jjyyzjy.buildlayoutdemo;
2 |
3 | import android.graphics.Color;
4 | import android.view.View;
5 | import android.view.ViewGroup;
6 | import android.widget.ImageView;
7 |
8 | import com.fb.jjyyzjy.buildlayoutdemo.view.buildview.BaseBuildLayoutAdapter;
9 |
10 | /**
11 | * Created by zhangjy on 2018/4/24.
12 | */
13 |
14 | public class BuildLayoutAdapter extends BaseBuildLayoutAdapter {
15 |
16 | private int[][] data;
17 |
18 | public void setData(int[][] data){
19 | this.data = data;
20 | }
21 |
22 | @Override
23 | public int[] getLayout(int position) {
24 | return data[position];
25 | }
26 |
27 | @Override
28 | public int getCount() {
29 | return data == null ? 0 : data.length;
30 | }
31 |
32 | @Override
33 | public Object getItem(int position) {
34 | return data[position];
35 | }
36 |
37 | @Override
38 | public long getItemId(int position) {
39 | return position;
40 | }
41 |
42 | @Override
43 | public View getView(int position, View contentView, ViewGroup parent) {
44 | if (contentView == null){
45 | contentView = new ImageView(parent.getContext());
46 | contentView.setBackgroundColor(Color.BLUE);
47 | }
48 | return contentView;
49 | }
50 |
51 |
52 | }
53 |
--------------------------------------------------------------------------------
/app/src/main/java/com/fb/jjyyzjy/buildlayoutdemo/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.fb.jjyyzjy.buildlayoutdemo;
2 |
3 | import android.support.v7.app.AppCompatActivity;
4 | import android.os.Bundle;
5 | import android.view.View;
6 | import android.widget.TextView;
7 |
8 | import com.fb.jjyyzjy.buildlayoutdemo.utils.DisplayUtil;
9 | import com.fb.jjyyzjy.buildlayoutdemo.view.buildview.MyBuildLayout;
10 |
11 | public class MainActivity extends AppCompatActivity {
12 |
13 | @Override
14 | protected void onCreate(Bundle savedInstanceState) {
15 | super.onCreate(savedInstanceState);
16 | setContentView(R.layout.activity_main);
17 | DisplayUtil.init(this);
18 | initView();
19 | }
20 |
21 | private int[][] data = {{0,0,1,1},{0,1,1,1},{0,2,1,1},{1,0,2,1},{1,1,2,1},{1,2,1,1},{2,2,1,1},{3,0,2,2},{3,2,2,1},{5,0,1,3}};
22 | private int[][] data2 = {{0,0,3,3},{3,0,1,1},{3,1,1,1},{3,2,1,1},{4,0,1,2},{4,2,1,1},{5,0,1,1},{5,1,1,2},{0,3,6,1}};
23 | private boolean isData = true;
24 | private void initView() {
25 | final MyBuildLayout buildLayout = (MyBuildLayout) findViewById(R.id.build_layout);
26 | final BuildLayoutAdapter adapter = new BuildLayoutAdapter();
27 | buildLayout.setAdapter(adapter);
28 | adapter.setData(data);
29 | adapter.notifyDataSetChanged();
30 |
31 | TextView btn = (TextView) findViewById(R.id.btn);
32 | btn.setOnClickListener(new View.OnClickListener() {
33 | @Override
34 | public void onClick(View v) {
35 | if (isData = !isData){
36 | buildLayout.mySetLayoutSize(6,3);
37 | buildLayout.mySetItemSize(DisplayUtil.dim2px(250),DisplayUtil.dim2px(151));
38 | buildLayout.mySetDividing(DisplayUtil.dim2px(30));
39 | adapter.setData(data);
40 | }else {
41 | buildLayout.mySetLayoutSize(7,4);
42 | buildLayout.mySetItemSize(DisplayUtil.dim2px(200),DisplayUtil.dim2px(100));
43 | buildLayout.mySetDividing(DisplayUtil.dim2px(40));
44 | adapter.setData(data2);
45 | }
46 | adapter.notifyDataSetChanged();
47 | }
48 | });
49 | btn.requestFocus();
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/app/src/main/java/com/fb/jjyyzjy/buildlayoutdemo/utils/CastUtils.java:
--------------------------------------------------------------------------------
1 | package com.fb.jjyyzjy.buildlayoutdemo.utils;
2 |
3 | /**
4 | * 安全的类型转换
5 | * Created by ZJY on 2016/5/19.
6 | */
7 | public class CastUtils {
8 |
9 | public static int getIntForString(String str, int defaultNum){
10 | try{
11 | defaultNum = Integer.parseInt(str);
12 | }catch (Exception e){
13 | DebugLog.e("CastUtils_getIntForString Exception=="+e);
14 | }
15 | return defaultNum;
16 | }
17 |
18 | public static long getLongForString(String str, long defaultNum){
19 | try{
20 | defaultNum = Long.parseLong(str);
21 | }catch (Exception e){
22 | DebugLog.e("CastUtils_getLongForString Exception=="+e);
23 | }
24 | return defaultNum;
25 | }
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/app/src/main/java/com/fb/jjyyzjy/buildlayoutdemo/utils/DebugLog.java:
--------------------------------------------------------------------------------
1 | package com.fb.jjyyzjy.buildlayoutdemo.utils;
2 |
3 | import android.util.Log;
4 |
5 | public class DebugLog {
6 |
7 | private static String LOG_TAG = "DEBUG_LOG";
8 | private static String className;
9 | private static String methodName;
10 | private static int lineNumber;
11 | private static boolean isDebug = true;
12 |
13 | public static void initDebug(boolean isDebug) {
14 | DebugLog.isDebug = isDebug;
15 | }
16 |
17 | private static boolean isDebug() {
18 | return isDebug;
19 | }
20 |
21 | private static String createLog(String log) {
22 | return "[" +
23 | className +
24 | ":" +
25 | methodName +
26 | "+" +
27 | lineNumber +
28 | "]" +
29 | log;
30 | }
31 |
32 | private static void getMethodNames(StackTraceElement[] sElements) {
33 | className = sElements[1].getFileName();
34 | methodName = sElements[1].getMethodName();
35 | lineNumber = sElements[1].getLineNumber();
36 | }
37 |
38 | public static void e(String message) {
39 | if (isDebug()) {
40 | getMethodNames((new Throwable()).getStackTrace());
41 | Log.e(LOG_TAG, createLog(message));
42 | }
43 | }
44 |
45 | public static void i(String message) {
46 | if (isDebug()) {
47 | getMethodNames((new Throwable()).getStackTrace());
48 | Log.i(LOG_TAG, createLog(message));
49 | }
50 | }
51 |
52 | public static void d(String message) {
53 | if (isDebug()) {
54 | getMethodNames((new Throwable()).getStackTrace());
55 | Log.d(LOG_TAG, createLog(message));
56 | }
57 | }
58 |
59 | public static void v(String message) {
60 | if (isDebug()) {
61 | getMethodNames((new Throwable()).getStackTrace());
62 | Log.v(LOG_TAG, createLog(message));
63 | }
64 | }
65 |
66 | public static void w(String message) {
67 | if (isDebug()) {
68 | getMethodNames((new Throwable()).getStackTrace());
69 | Log.w(LOG_TAG, createLog(message));
70 | }
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/app/src/main/java/com/fb/jjyyzjy/buildlayoutdemo/utils/DisplayUtil.java:
--------------------------------------------------------------------------------
1 | package com.fb.jjyyzjy.buildlayoutdemo.utils;
2 |
3 | import android.content.Context;
4 | import android.util.DisplayMetrics;
5 |
6 | /**
7 | * Created by JJYYZJY on 2017/4/25.
8 | */
9 | public class DisplayUtil {
10 | private static float scale;
11 |
12 | private static float scaledDensity;
13 |
14 | private static float widthPixels;
15 |
16 | private static float heightPixels;
17 |
18 | public static final int CHINESE = 0;
19 |
20 | public static final int NUMBER_OR_CHARACTER = 1;
21 |
22 | public static void init(Context context){
23 | DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
24 | scale = displayMetrics.density;
25 | scaledDensity = displayMetrics.scaledDensity;
26 | widthPixels = displayMetrics.widthPixels;
27 | heightPixels = displayMetrics.heightPixels;
28 |
29 | }
30 |
31 | public static int dim2px(float dimValue){
32 | return (int) (dimValue*widthPixels/1920);
33 | }
34 |
35 | /**
36 | * dp转成px
37 | * @param dipValue
38 | * @return
39 | */
40 | public static int dip2px(float dipValue) {
41 | return (int) (dipValue * scale + 0.5f);
42 | }
43 |
44 | /**
45 | * px转成dp
46 | * @param pxValue
47 | * @return
48 | */
49 | public static int px2dip(float pxValue) {
50 | return (int) (pxValue / scale + 0.5f);
51 | }
52 |
53 | /**
54 | * sp转成px
55 | * @param spValue
56 | * @param type
57 | * @return
58 | */
59 | public static float sp2px(float spValue, int type) {
60 | switch (type) {
61 | case CHINESE:
62 | return spValue * scaledDensity;
63 | case NUMBER_OR_CHARACTER:
64 | return spValue * scaledDensity * 10.0f / 18.0f;
65 | default:
66 | return spValue * scaledDensity;
67 | }
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/app/src/main/java/com/fb/jjyyzjy/buildlayoutdemo/utils/FocusScaleUtils.java:
--------------------------------------------------------------------------------
1 | package com.fb.jjyyzjy.buildlayoutdemo.utils;
2 |
3 | import android.animation.Animator;
4 | import android.animation.AnimatorSet;
5 | import android.animation.ObjectAnimator;
6 | import android.view.View;
7 | import android.view.animation.AccelerateInterpolator;
8 | import android.view.animation.DecelerateInterpolator;
9 | import android.view.animation.Interpolator;
10 |
11 | import java.util.HashMap;
12 | import java.util.Map;
13 |
14 | /**
15 | * 焦点缩放工具类
16 | * Created by ZJY on 2016/6/7.
17 | * update on 2016/8/17 解决还原未执行完时放大失败问题
18 | */
19 | public class FocusScaleUtils {
20 | private View oldView;
21 | /**
22 | * 放大用时
23 | */
24 | private int durationLarge = 300;
25 | /**
26 | * 缩小用时
27 | */
28 | private int durationSmall = 500;
29 | private float scale = 1.1f;
30 | private AnimatorSet animatorSet;
31 | private Interpolator interpolatorLarge;
32 | private Interpolator interpolatorSmall;
33 | private Map animatorSetMap;
34 |
35 | public FocusScaleUtils() {
36 | this.interpolatorLarge = new AccelerateInterpolator(1.5f);
37 | this.interpolatorSmall = new DecelerateInterpolator(1.5f);
38 | init();
39 | }
40 |
41 | public FocusScaleUtils(int duration, float scale, Interpolator interpolator) {
42 | this(duration, duration, scale, interpolator, interpolator);
43 | }
44 |
45 | public FocusScaleUtils(int durationLarge, int durationSmall, float scale, Interpolator interpolatorLarge, Interpolator interpolatorSmall) {
46 | this.durationLarge = durationLarge;
47 | this.durationSmall = durationSmall;
48 | this.scale = scale;
49 | this.interpolatorLarge = interpolatorLarge;
50 | this.interpolatorSmall = interpolatorSmall;
51 | init();
52 | }
53 |
54 | private void init() {
55 | animatorSetMap = new HashMap<>();
56 | }
57 |
58 | /**
59 | * 放大指定view(view必须拥有焦点拥有焦点)
60 | * @param item
61 | */
62 | public void scaleToLarge(View item) {
63 | if (!item.isFocused()) {
64 | return;
65 | }
66 | scaleToLargeNotFocus(item);
67 | }
68 |
69 | /**
70 | * 放大指定view(不需要view拥有焦点)
71 | * @param item
72 | */
73 | public void scaleToLargeNotFocus(View item) {
74 | DebugLog.e("FocusScaleUtils__scaleToLargeNotFocus=="+item);
75 | DebugLog.e("FocusScaleUtils__animator_map.size=="+animatorSetMap.size());
76 |
77 | Animator animatorOld = animatorSetMap.get(item);
78 | if (animatorOld != null && animatorOld.isRunning()){
79 | animatorOld.cancel();
80 | }
81 |
82 | animatorSet = new AnimatorSet();
83 |
84 | ObjectAnimator largeX = ObjectAnimator.ofFloat(item, "ScaleX", 1f, scale);
85 | ObjectAnimator largeY = ObjectAnimator.ofFloat(item, "ScaleY", 1f,
86 | scale);
87 | animatorSet.setDuration(durationLarge);
88 | animatorSet.setInterpolator(interpolatorLarge);
89 | animatorSet.play(largeX).with(largeY);
90 | animatorSet.start();
91 |
92 | oldView = item;
93 | }
94 |
95 | /**
96 | * 还原指定view
97 | * @param item
98 | */
99 | public void scaleToNormal(final View item) {
100 | DebugLog.e("FocusScaleUtils__scaleToNormal=="+item);
101 | if (animatorSet == null || item == null) {
102 | return;
103 | }
104 |
105 | if (animatorSet.isRunning()) {
106 | animatorSet.cancel();
107 | }
108 |
109 | AnimatorSet animatorSetForNormal = new AnimatorSet();
110 |
111 | ObjectAnimator oa = ObjectAnimator.ofFloat(item, "ScaleX", 1f);
112 | ObjectAnimator oa2 = ObjectAnimator.ofFloat(item, "ScaleY", 1f);
113 | animatorSetForNormal.setDuration(durationSmall);
114 | animatorSetForNormal.setInterpolator(interpolatorSmall);
115 | animatorSetForNormal.play(oa).with(oa2);
116 | animatorSetForNormal.addListener(new Animator.AnimatorListener() {
117 | @Override
118 | public void onAnimationStart(Animator animation) {
119 | animatorSetMap.put(item,animation);
120 | }
121 |
122 | @Override
123 | public void onAnimationEnd(Animator animation) {
124 | animatorSetMap.remove(item);
125 | }
126 |
127 | @Override
128 | public void onAnimationCancel(Animator animation) {
129 | animatorSetMap.remove(item);
130 | }
131 |
132 | @Override
133 | public void onAnimationRepeat(Animator animation) {
134 |
135 | }
136 | });
137 | animatorSetForNormal.start();
138 | oldView = null;
139 | }
140 |
141 | /**
142 | * 还原上一次放大的view
143 | */
144 | public void scaleToNormal() {
145 | scaleToNormal(oldView);
146 | }
147 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/fb/jjyyzjy/buildlayoutdemo/view/bring/BringToFrontHelper.java:
--------------------------------------------------------------------------------
1 | package com.fb.jjyyzjy.buildlayoutdemo.view.bring;
2 |
3 | import android.view.View;
4 | import android.view.ViewGroup;
5 |
6 | /**
7 | * Created by JJYYZJY on 2017/9/6.
8 | */
9 | public class BringToFrontHelper {
10 |
11 | private int mFocusChildIndex;
12 |
13 | public void bringChildToFront(ViewGroup viewGroup, View childView){
14 | mFocusChildIndex = viewGroup.indexOfChild(childView);
15 | if(mFocusChildIndex != -1){
16 | viewGroup.postInvalidate();
17 | }
18 | }
19 |
20 | public int getChildDrawingOrder(int childCount, int i){
21 | if(mFocusChildIndex != -1){
22 | if(i == childCount-1){
23 | if(mFocusChildIndex > childCount-1){
24 | mFocusChildIndex = childCount-1;
25 | }
26 | return mFocusChildIndex;
27 | }
28 | if(i == mFocusChildIndex){
29 |
30 | return childCount -1;
31 | }
32 | }
33 | if(childCount <= i){
34 | i = childCount-1;
35 | }
36 | return i;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/app/src/main/java/com/fb/jjyyzjy/buildlayoutdemo/view/bring/BringToFrontLinear.java:
--------------------------------------------------------------------------------
1 | package com.fb.jjyyzjy.buildlayoutdemo.view.bring;
2 |
3 | import android.content.Context;
4 | import android.util.AttributeSet;
5 | import android.view.View;
6 | import android.widget.LinearLayout;
7 |
8 | /**
9 | * Created by JJYYZJY on 2017/9/7.
10 | */
11 | public class BringToFrontLinear extends LinearLayout {
12 |
13 | public BringToFrontLinear(Context context) {
14 | super(context);
15 | mInit();
16 | }
17 |
18 | public BringToFrontLinear(Context context, AttributeSet attrs) {
19 | super(context, attrs);
20 | mInit();
21 | }
22 |
23 | public BringToFrontLinear(Context context, AttributeSet attrs, int defStyleAttr) {
24 | super(context, attrs, defStyleAttr);
25 | mInit();
26 | }
27 |
28 | public BringToFrontLinear(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
29 | super(context, attrs, defStyleAttr, defStyleRes);
30 | mInit();
31 | }
32 |
33 | private BringToFrontHelper bringToFrontHelper;
34 |
35 | private void mInit() {
36 | setWillNotDraw(true);
37 | setChildrenDrawingOrderEnabled(true);
38 | bringToFrontHelper = new BringToFrontHelper();
39 | }
40 |
41 | @Override
42 | protected int getChildDrawingOrder(int childCount, int i) {
43 | return bringToFrontHelper.getChildDrawingOrder(childCount,i);
44 | }
45 |
46 | @Override
47 | public void bringChildToFront(View child) {
48 | bringToFrontHelper.bringChildToFront(this,child);
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/app/src/main/java/com/fb/jjyyzjy/buildlayoutdemo/view/bring/BringToFrontLinearLayout.java:
--------------------------------------------------------------------------------
1 | package com.fb.jjyyzjy.buildlayoutdemo.view.bring;
2 |
3 | import android.content.Context;
4 | import android.util.AttributeSet;
5 | import android.view.View;
6 |
7 | /**
8 | * 将持有焦点的view的父控件移到视图最上方
9 | * Created by JJYYZJY on 2017/9/7.
10 | */
11 | public class BringToFrontLinearLayout extends BringToFrontLinear {
12 | public BringToFrontLinearLayout(Context context) {
13 | super(context);
14 | }
15 |
16 | public BringToFrontLinearLayout(Context context, AttributeSet attrs) {
17 | super(context, attrs);
18 | }
19 |
20 | public BringToFrontLinearLayout(Context context, AttributeSet attrs, int defStyleAttr) {
21 | super(context, attrs, defStyleAttr);
22 | }
23 |
24 | public BringToFrontLinearLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
25 | super(context, attrs, defStyleAttr, defStyleRes);
26 | }
27 |
28 | @Override
29 | public void requestChildFocus(View child, View focused) {
30 | child.bringToFront();
31 | super.requestChildFocus(child, focused);
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/app/src/main/java/com/fb/jjyyzjy/buildlayoutdemo/view/bring/BringToFrontRelative.java:
--------------------------------------------------------------------------------
1 | package com.fb.jjyyzjy.buildlayoutdemo.view.bring;
2 |
3 | import android.content.Context;
4 | import android.util.AttributeSet;
5 | import android.view.View;
6 | import android.widget.RelativeLayout;
7 |
8 | /**
9 | * Created by JJYYZJY on 2017/9/7.
10 | */
11 | public class BringToFrontRelative extends RelativeLayout {
12 | public BringToFrontRelative(Context context) {
13 | super(context);
14 | mInit();
15 | }
16 |
17 | public BringToFrontRelative(Context context, AttributeSet attrs) {
18 | super(context, attrs);
19 | mInit();
20 | }
21 |
22 | public BringToFrontRelative(Context context, AttributeSet attrs, int defStyleAttr) {
23 | super(context, attrs, defStyleAttr);
24 | mInit();
25 | }
26 |
27 | public BringToFrontRelative(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
28 | super(context, attrs, defStyleAttr, defStyleRes);
29 | mInit();
30 | }
31 |
32 | private BringToFrontHelper bringToFrontHelper;
33 |
34 | private void mInit() {
35 | setWillNotDraw(true);
36 | setChildrenDrawingOrderEnabled(true);
37 | bringToFrontHelper = new BringToFrontHelper();
38 | }
39 |
40 |
41 | @Override
42 | protected int getChildDrawingOrder(int childCount, int i) {
43 | return bringToFrontHelper.getChildDrawingOrder(childCount,i);
44 | }
45 |
46 | @Override
47 | public void bringChildToFront(View child) {
48 | bringToFrontHelper.bringChildToFront(this,child);
49 | }
50 |
51 | }
52 |
--------------------------------------------------------------------------------
/app/src/main/java/com/fb/jjyyzjy/buildlayoutdemo/view/bring/BringToFrontRelativeLayout.java:
--------------------------------------------------------------------------------
1 | package com.fb.jjyyzjy.buildlayoutdemo.view.bring;
2 |
3 | import android.content.Context;
4 | import android.util.AttributeSet;
5 | import android.view.View;
6 |
7 | /**
8 | * 将持有焦点的view的父控件移到视图最上方
9 | * Created by JJYYZJY on 2017/5/5.
10 | */
11 | public class BringToFrontRelativeLayout extends BringToFrontRelative {
12 | public BringToFrontRelativeLayout(Context context) {
13 | super(context);
14 | }
15 |
16 | public BringToFrontRelativeLayout(Context context, AttributeSet attrs) {
17 | super(context, attrs);
18 | }
19 |
20 | public BringToFrontRelativeLayout(Context context, AttributeSet attrs, int defStyleAttr) {
21 | super(context, attrs, defStyleAttr);
22 | }
23 |
24 | public BringToFrontRelativeLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
25 | super(context, attrs, defStyleAttr, defStyleRes);
26 | }
27 |
28 | @Override
29 | public void requestChildFocus(View child, View focused) {
30 | child.bringToFront();
31 | super.requestChildFocus(child, focused);
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/app/src/main/java/com/fb/jjyyzjy/buildlayoutdemo/view/buildview/BaseBuildLayoutAdapter.java:
--------------------------------------------------------------------------------
1 | package com.fb.jjyyzjy.buildlayoutdemo.view.buildview;
2 |
3 | import android.view.View;
4 | import android.view.ViewGroup;
5 |
6 | /**
7 | * 动态布局——布局中item适配器
8 | * Created by ZJY on 2016/5/3.
9 | */
10 | public abstract class BaseBuildLayoutAdapter {
11 |
12 | private Parameter parameter;
13 |
14 | public abstract int[] getLayout(int position);
15 |
16 | public abstract int getCount();
17 |
18 | public abstract Object getItem(int position);
19 |
20 | public abstract long getItemId(int position);
21 |
22 | public int getItemViewType(int position){
23 | return 0;
24 | }
25 |
26 | public abstract View getView(int position, View contentView,
27 | ViewGroup parent);
28 |
29 | /**
30 | * Set some parameters
31 | * @param parameter
32 | */
33 | public void setParameter(Parameter parameter){
34 | this.parameter = parameter;
35 | }
36 |
37 | /**
38 | * Get some parameters
39 | */
40 | public Parameter getParameter(){
41 | return parameter;
42 | }
43 |
44 | private BuildAdapterDataObserver observer;
45 |
46 | public void registerAdapterDataObserver(BuildAdapterDataObserver observer) {
47 | this.observer = observer;
48 | }
49 |
50 | public void unregisterAdapterDataObserver(BuildAdapterDataObserver observer) {
51 | this.observer = null;
52 | }
53 |
54 | public final void notifyDataSetChanged() {
55 | observer.onChanged();
56 | }
57 |
58 | }
59 |
--------------------------------------------------------------------------------
/app/src/main/java/com/fb/jjyyzjy/buildlayoutdemo/view/buildview/BuildAdapterDataObserver.java:
--------------------------------------------------------------------------------
1 | package com.fb.jjyyzjy.buildlayoutdemo.view.buildview;
2 |
3 | /**
4 | * Created by JJYYZJY on 2017/9/19.
5 | */
6 | public abstract class BuildAdapterDataObserver {
7 |
8 | public void onChanged() {
9 |
10 | }
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/app/src/main/java/com/fb/jjyyzjy/buildlayoutdemo/view/buildview/BuildItemPoll.java:
--------------------------------------------------------------------------------
1 | package com.fb.jjyyzjy.buildlayoutdemo.view.buildview;
2 |
3 | import android.support.annotation.NonNull;
4 | import android.util.SparseArray;
5 | import android.util.SparseIntArray;
6 | import android.view.View;
7 |
8 | import java.util.ArrayList;
9 |
10 | /**
11 | * Created by JJYYZJY on 2017/9/18.
12 | */
13 | public class BuildItemPoll/* extends RecyclerView.RecycledViewPool */{
14 |
15 | private SparseArray> mScrap =
16 | new SparseArray>();
17 | private SparseIntArray mMaxScrap = new SparseIntArray();
18 | private static final int DEFAULT_MAX_SCRAP = 5;
19 |
20 | public void clear() {
21 | mScrap.clear();
22 | }
23 |
24 | public void setMaxRecycledViews(int viewType, int max) {
25 | mMaxScrap.put(viewType, max);
26 | final ArrayList scrapHeap = mScrap.get(viewType);
27 | if (scrapHeap != null) {
28 | while (scrapHeap.size() > max) {
29 | scrapHeap.remove(scrapHeap.size() - 1);
30 | }
31 | }
32 | }
33 |
34 | public View getBuildItemView(int viewType) {
35 | final ArrayList scrapHeap = mScrap.get(viewType);
36 | if (scrapHeap != null && !scrapHeap.isEmpty()) {
37 | final int index = scrapHeap.size() - 1;
38 | final View scrap = scrapHeap.get(index);
39 | scrapHeap.remove(index);
40 | return scrap;
41 | }
42 | return null;
43 | }
44 |
45 | public void putBuildItemView(int viewType, View scrap) {
46 | getScrapHeapForType(viewType).add(scrap);
47 | }
48 |
49 | private ArrayList getScrapHeapForType(int viewType) {
50 | ArrayList scrap = mScrap.get(viewType);
51 | if (scrap == null) {
52 | scrap = new ArrayList<>();
53 | mScrap.put(viewType, scrap);
54 | }
55 | return scrap;
56 | }
57 |
58 | int size() {
59 | int count = 0;
60 | for (int i = 0; i < mScrap.size(); i ++) {
61 | ArrayList items = mScrap.valueAt(i);
62 | if (items != null) {
63 | count += items.size();
64 | }
65 | }
66 | return count;
67 | }
68 |
69 | public void putAllItemView(@NonNull BuildItemPoll poll){
70 |
71 | for (int i = 0; i < poll.mScrap.size(); i ++) {
72 | final int key = poll.mScrap.keyAt(i);
73 | mScrap.append(key,poll.mScrap.get(key));
74 | }
75 |
76 | poll.clear();
77 |
78 | }
79 |
80 | }
81 |
--------------------------------------------------------------------------------
/app/src/main/java/com/fb/jjyyzjy/buildlayoutdemo/view/buildview/BuildLayout.java:
--------------------------------------------------------------------------------
1 | package com.fb.jjyyzjy.buildlayoutdemo.view.buildview;
2 |
3 | import android.content.Context;
4 | import android.content.res.TypedArray;
5 | import android.util.AttributeSet;
6 | import android.view.View;
7 | import android.view.ViewGroup;
8 | import android.widget.RelativeLayout;
9 |
10 | import com.fb.jjyyzjy.buildlayoutdemo.R;
11 | import com.fb.jjyyzjy.buildlayoutdemo.utils.DebugLog;
12 | import com.fb.jjyyzjy.buildlayoutdemo.view.bring.BringToFrontRelative;
13 |
14 | import java.util.ArrayList;
15 | import java.util.List;
16 |
17 | /**
18 | * Created by JJYYZJY on 2017/9/18.
19 | */
20 | public class BuildLayout extends BringToFrontRelative {
21 | protected static final String TAG = "MyBuildLayout";
22 | protected static final boolean DEBUG_CAN = false;
23 | private List childViews;
24 | protected View[][] cViewTree = null;
25 | private View defaultGetFocusView;//默认获取焦点的View
26 | private View defaultGetFocusViewLB;//默认获取焦点的View
27 | private View defaultGetFocusViewRT;//默认获取焦点的View
28 | private View defaultGetFocusViewRB;//默认获取焦点的View
29 | private BaseBuildLayoutAdapter buildLayoutAdapter;
30 | private boolean isDealWithFocus;//是否处理焦点,使其左右不能离开布局
31 | /**
32 | * 单元格宽
33 | */
34 | protected int itemWidth = (int) getResources().getDimension(R.dimen.px270);
35 | /**
36 | * 单元格高
37 | */
38 | protected int itemHeight = (int) getResources().getDimension(R.dimen.px180);
39 | /**
40 | * 列数
41 | */
42 | private int hSize;
43 | /**
44 | * 行数
45 | */
46 | private int vSize;
47 | /**
48 | * 单元格间隔
49 | */
50 | protected int dividing;
51 |
52 | private int widthP;
53 | private int heightP;
54 |
55 | public BuildLayout(Context context) {
56 | this(context,null);
57 | }
58 |
59 | public BuildLayout(Context context, AttributeSet attrs) {
60 | this(context, attrs,0);
61 | }
62 |
63 | public BuildLayout(Context context, AttributeSet attrs, int defStyleAttr) {
64 | super(context, attrs, defStyleAttr);
65 | if (attrs != null) {
66 | TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.MyBuildLayout);
67 | this.hSize = typedArray.getInteger(R.styleable.MyBuildLayout_myHSize, 0);
68 | this.vSize = typedArray.getInteger(R.styleable.MyBuildLayout_myVSize, 0);
69 | this.itemWidth = (int) typedArray.getDimension(R.styleable.MyBuildLayout_myItemWidth, this.itemWidth);
70 | this.itemHeight = (int) typedArray.getDimension(R.styleable.MyBuildLayout_myItemHeight, this.itemHeight);
71 | this.dividing = (int) typedArray.getDimension(R.styleable.MyBuildLayout_myDividing, 0);
72 | typedArray.recycle();
73 | }
74 | init();
75 | }
76 |
77 | private void init() {
78 | childViews = new ArrayList<>();
79 | }
80 |
81 | @Override
82 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
83 | // super.onMeasure(widthMeasureSpec, heightMeasureSpec);
84 | for (int i = 0; i < childViews.size(); i++) {
85 | measureChild(childViews.get(i), widthMeasureSpec, heightMeasureSpec);
86 | }
87 | if (hSize == 0 || vSize == 0) {
88 | hSize = 5;
89 | vSize = 3;
90 | }
91 | if (itemWidth == 0 || itemHeight == 0) {
92 | itemWidth = (int) getResources().getDimension(R.dimen.px270);
93 | itemHeight = (int) getResources().getDimension(R.dimen.px180);
94 | }
95 |
96 | widthP = hSize * itemWidth + (hSize - 1) * dividing;
97 | heightP = vSize * itemHeight + (vSize - 1) * dividing;
98 | setMeasuredDimension(widthP, heightP);
99 | }
100 |
101 | @Override
102 | protected void onLayout(boolean changed, int l, int t, int r, int b) {
103 | // super.onLayout(changed, l, t, r, b);
104 | if (changed) {
105 | mySetChildLayout();
106 | }else {
107 | int cCount = childViews.size();
108 | int cWidth = 0;
109 | int cHeight = 0;
110 | for (int i = 0; i < cCount; i++) {
111 | View childView = childViews.get(i);
112 | cWidth = childView.getMeasuredWidth();
113 | cHeight = childView.getMeasuredHeight();
114 | int cl = 0, ct = 0, cr = 0, cb = 0;
115 | cl = childView.getLeft();
116 | ct = childView.getTop();
117 | cr = cl + cWidth;
118 | cb = cHeight + ct;
119 | childView.layout(cl, ct, cr, cb);
120 | }
121 | }
122 | }
123 |
124 | private void mySetChildLayout() {
125 | // MyLog.v(TAG, "onLayout==getChildCount=="+getChildCount());
126 | // MyLog.v(TAG, "onLayout==childViews.size()=="+childViews.size());
127 | if (DEBUG_CAN) DebugLog.i("vSize = " + vSize + ",hSize = " + hSize);
128 | cViewTree = new View[vSize][hSize];
129 | for (int i = 0; i < childViews.size(); i++) {
130 |
131 | int[] childLayout = buildLayoutAdapter.getLayout(i);
132 | if (childLayout.length < 4) {
133 | continue;
134 | }
135 |
136 | int v_r = childLayout[0] * itemWidth + childLayout[0] * dividing;
137 | int v_t = childLayout[1] * itemHeight + childLayout[1] * dividing;
138 | int v_w = childLayout[2] * itemWidth + (childLayout[2] - 1) * dividing;
139 | int v_h = childLayout[3] * itemHeight + (childLayout[3] - 1) * dividing;
140 |
141 | if (v_r == 0 && v_t == 0) {
142 | defaultGetFocusView = childViews.get(i);
143 | }
144 |
145 | if (v_r == 0 && (v_t + v_h) == heightP) {
146 | defaultGetFocusViewLB = childViews.get(i);
147 | }
148 |
149 | if ((v_r + v_w) == widthP && v_t == 0) {
150 | defaultGetFocusViewRT = childViews.get(i);
151 | }
152 |
153 | if ((v_r + v_w) == widthP && (v_t + v_h) == heightP) {
154 | defaultGetFocusViewRB = childViews.get(i);
155 | }
156 |
157 | childViews.get(i).layout(v_r,
158 | v_t,
159 | v_r + v_w,
160 | v_t + v_h);
161 |
162 | /*
163 | * 修改
164 | * 将child填充进其其所包含的所有坐标点,使查找更方便快速
165 | * @data 2017/4/19
166 | * @author zjy
167 | */
168 | int atArrayH = childLayout[1];
169 | int atArrayV = childLayout[0];
170 | int childW = childLayout[2];
171 | int childH = childLayout[3];
172 | if (DEBUG_CAN)
173 | DebugLog.i("add child to array : atArrayH=" + atArrayH + ", atArrayV=" + atArrayV + ", childW=" + childW + ", childH=" + childH);
174 | if (atArrayH < cViewTree.length && atArrayV < cViewTree[atArrayH].length) {
175 | while (childH > 0) {
176 | int childWCopy = childW;
177 | childH--;
178 | while (childWCopy > 0) {
179 | --childWCopy;
180 | if ((atArrayH + childH) < cViewTree.length && (atArrayV + childWCopy) < cViewTree[atArrayH + childH].length) {
181 | cViewTree[atArrayH + childH][atArrayV + childWCopy] = childViews.get(i);
182 | if (DEBUG_CAN)
183 | DebugLog.i("add child to array : array[0]=" + (atArrayH + childH) + ", array[1]=" + (atArrayV + childWCopy));
184 | } else {
185 | /*if (DEBUG_CAN) */
186 | DebugLog.w("err ArrayIndexOutOfBounds add child to array : array[0]=" + (atArrayH + childH) + ", array[1]=" + (atArrayV + childWCopy));
187 | }
188 | }
189 | }
190 | }
191 |
192 | childViews.get(i).setTag(childLayout);
193 | // MyLog.v("v_r", v_r+"");
194 | // MyLog.v("v_t", v_t+"");
195 | // MyLog.v("v_w", v_w+"");
196 | // MyLog.v("v_h", v_h+"");
197 | }
198 | if (isDealWithFocus)
199 | bindFocusSearchForBound();
200 | }
201 |
202 | private void initAdapter() {
203 | initItem();
204 | }
205 |
206 | BuildItemPoll mItemPoll = new BuildItemPoll();
207 | private void initItem() {
208 | mItemPoll.putAllItemView(poll);
209 | View focusViewFlag = findFocus();
210 | final int childCount = buildLayoutAdapter.getCount();
211 | View cacheItem;
212 | View newItem;
213 | int itemType;
214 | for (int i = 0; i < childCount; i++) {
215 | int[] childLayout = buildLayoutAdapter.getLayout(i);
216 | if (childLayout.length < 4) {
217 | continue;
218 | }
219 | itemType = buildLayoutAdapter.getItemViewType(i);
220 | cacheItem = getCacheViewForType(itemType);
221 |
222 | int v_w = childLayout[2] * itemWidth + (childLayout[2] - 1) * dividing;
223 | int v_h = childLayout[3] * itemHeight + (childLayout[3] - 1) * dividing;
224 | if (cacheItem != null) {
225 | RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) cacheItem.getLayoutParams();
226 | lp.width = v_w;
227 | lp.height = v_h;
228 | cacheItem.setLayoutParams(lp);
229 | int wMeasure = View.MeasureSpec.makeMeasureSpec(v_w, View.MeasureSpec.EXACTLY);
230 | int hMeasure = View.MeasureSpec.makeMeasureSpec(v_h, View.MeasureSpec.EXACTLY);
231 | cacheItem.setTag(R.id.key_tag_build_item_w, v_w);
232 | cacheItem.setTag(R.id.key_tag_build_item_h, v_h);
233 | cacheItem.setRight(cacheItem.getLeft() + v_w);
234 | cacheItem.setBottom(cacheItem.getTop() + v_h);
235 | cacheItem.measure(wMeasure, hMeasure);
236 | if (cacheItem instanceof ViewGroup) {
237 | ViewGroup viewGroup = (ViewGroup) cacheItem;
238 | View viewChild;
239 | int widthChild;
240 | int heightChild;
241 | for (int j = 0; j < viewGroup.getChildCount(); j++) {
242 | viewChild = viewGroup.getChildAt(j);
243 | widthChild = viewChild.getMeasuredWidth();
244 | heightChild = viewChild.getMeasuredHeight();
245 | viewChild.setRight(viewChild.getLeft() + widthChild);
246 | viewChild.setBottom(viewChild.getTop() + heightChild);
247 | }
248 | }
249 | }
250 | newItem = buildLayoutAdapter.getView(i, cacheItem, this);
251 | DebugLog.i(TAG + " cacheItem : " + cacheItem + ",newItem : " + newItem);
252 | if (cacheItem == null || (newItem != null && newItem != cacheItem)) {
253 | if (DEBUG_CAN) DebugLog.i("initItem newItem != cacheItem");
254 | RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(v_w, v_h);
255 | newItem.setLayoutParams(lp);
256 | if (newItem.getParent() != null) {
257 | ((ViewGroup) newItem.getParent()).removeView(newItem);
258 | }
259 | // addView(newItem);
260 | }
261 | if (newItem != null) {
262 | if (DEBUG_CAN) DebugLog.i("newItem != null");
263 | poll.putBuildItemView(itemType,newItem);
264 | if (childViews.contains(newItem)){
265 | int index = childViews.indexOf(newItem);
266 | if (index != i){
267 | childViews.remove(index);
268 | childViews.add(i,newItem);
269 | }
270 | }else {
271 | if (i < childViews.size()){
272 | removeView(childViews.remove(i));
273 | childViews.add(i,newItem);
274 | }else {
275 | childViews.add(newItem);
276 | }
277 | addView(newItem);
278 | }
279 | }
280 |
281 | }
282 | if (DEBUG_CAN) {
283 | DebugLog.i(TAG + " mItemPoll.size() : " + mItemPoll.size() + "mItemPoll : " + mItemPoll.toString());
284 | if (itemPoll != null) {
285 | DebugLog.i(TAG + " itemPoll.size() : " + itemPoll.size() + "itemPoll : " + itemPoll.toString());
286 | }
287 | DebugLog.i(TAG + " childViews.size : " + childViews.size() + "childViews : " + childViews.toString());
288 | DebugLog.i(TAG + " getChildCount : " + getChildCount());
289 | for (int i = 0; i < getChildCount(); i++) {
290 | DebugLog.i(TAG + "getChild : " + i + " " + getChildAt(i));
291 | }
292 | }
293 |
294 | for (int i = childViews.size() - 1; i >= childCount; i--) {
295 | childViews.remove(i);
296 | }
297 | if (DEBUG_CAN)
298 | DebugLog.i(TAG + " childViews.size2 : " + childViews.size() + "childViews2 : " + childViews.toString());
299 | if (DEBUG_CAN) DebugLog.i(TAG + "getChildCount2 : " + getChildCount());
300 | View viewC;
301 | for (int n = 0; n < getChildCount(); n++) {
302 | viewC = getChildAt(n);
303 | if (!childViews.contains(viewC)) {
304 | removeView(viewC);
305 | n--;
306 | }
307 | }
308 | if (DEBUG_CAN)
309 | DebugLog.i(TAG + " childViews.size() : " + childViews.size() + "childViews : " + childViews.toString());
310 | DebugLog.i(TAG + " getChildCount : " + getChildCount());
311 |
312 | mySetChildLayout();
313 | bindEvent();
314 | //解决数据更新由于控件复用导致带有焦点的item位置变化而焦点框位置未更新
315 | if (focusViewFlag != null) {
316 | if (childViews != null && childViews.size() > 0) {
317 | if (focusViewFlag != childViews.get(0)) {
318 | childViews.get(0).requestFocus();
319 | } else {
320 | if (childViews.size() > 1) {
321 | childViews.get(1).requestFocus();
322 | }
323 | }
324 | if (childViews.contains(focusViewFlag)) {
325 | focusViewFlag.requestFocus();
326 | }
327 | }
328 | }
329 | mItemPoll.clear();
330 | }
331 |
332 | BuildItemPoll poll = new BuildItemPoll();
333 | private View getCacheViewForType(int itemType) {
334 | View cacheItem = mItemPoll.getBuildItemView(itemType);
335 | if (cacheItem == null && itemPoll != null){
336 | cacheItem = itemPoll.getBuildItemView(itemType);
337 | }
338 | return cacheItem;
339 | }
340 |
341 | private void bindEvent() {
342 | View child;
343 | for (int i = 0; i < getChildCount(); i++) {
344 | child = getChildAt(i);
345 | if (child != null) {
346 | child.setOnFocusChangeListener(new View.OnFocusChangeListener() {
347 | @Override
348 | public void onFocusChange(final View child, boolean focus) {
349 | if (onChildSelectListener != null) {
350 | onChildSelectListener.onChildSelect(child, focus);
351 | }
352 | if (onChildFocusChangeListener != null) {
353 | onChildFocusChangeListener.onChildFocus(child, focus, false, 0F);
354 | }
355 | }
356 | });
357 | if (onChildClickListener != null) {
358 | child.setOnClickListener(new View.OnClickListener() {
359 | @Override
360 | public void onClick(View child) {
361 | onChildClickListener.onChildClick(child);
362 |
363 | }
364 | });
365 | }
366 | }
367 | }
368 | }
369 |
370 | private void bindFocusSearchForBound() {
371 | View view;
372 | for (int i = 0; i < childViews.size(); i++) {
373 | view = childViews.get(i);
374 | FocusSearchUtils.unBindFocus(view);
375 | }
376 | if (cViewTree == null) {
377 | return;
378 | }
379 | if (cViewTree.length > 0) {
380 | for (int i = 0; i < cViewTree.length; i++) {
381 | if (cViewTree[i].length > 0) {
382 | FocusSearchUtils.bindFocusSearch(cViewTree[i][0], cViewTree[i][cViewTree[i].length - 1]);
383 | }
384 | }
385 | }
386 | }
387 |
388 |
389 |
390 | /**
391 | * 设置单元格宽高
392 | *
393 | * @param itemWidth
394 | * @param itemHeight
395 | */
396 | public void mySetItemSize(int itemWidth, int itemHeight) {
397 | this.itemWidth = itemWidth;
398 | this.itemHeight = itemHeight;
399 | setItemLayout();
400 | invalidate();
401 | }
402 |
403 | private void setItemLayout() {
404 | View child;
405 | for (int i = 0; i < childViews.size(); i++) {
406 | child = childViews.get(i);
407 | if (child == null) {
408 | continue;
409 | }
410 | int[] childLayout = buildLayoutAdapter.getLayout(i);
411 | if (childLayout.length < 4) {
412 | continue;
413 | }
414 | int v_w = childLayout[2] * itemWidth + (childLayout[2] - 1) * dividing;
415 | int v_h = childLayout[3] * itemHeight + (childLayout[3] - 1) * dividing;
416 | RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) child.getLayoutParams();
417 | if (lp == null) {
418 | lp = new RelativeLayout.LayoutParams(v_w, v_h);
419 | } else {
420 | lp.width = v_w;
421 | lp.height = v_h;
422 | }
423 | child.setLayoutParams(lp);
424 | }
425 | }
426 |
427 | /**
428 | * 设置控件尺寸
429 | *
430 | * @param hSize 列数
431 | * @param vSize 行数
432 | */
433 | public void mySetLayoutSize(int hSize, int vSize) {
434 | if (DEBUG_CAN) DebugLog.i("mySetLayoutSize [hSize=" + hSize + ",vSize=" + vSize + "]");
435 | this.hSize = hSize;
436 | this.vSize = vSize;
437 | invalidate();
438 | }
439 |
440 | /**
441 | * 设置间隔
442 | */
443 | public void mySetDividing(int dividing) {
444 | this.dividing = dividing;
445 | invalidate();
446 | }
447 |
448 | /**
449 | * 处理焦点左右移动
450 | *
451 | * @param isDealWithFocus
452 | */
453 | public void setIsDealWithFocus(boolean isDealWithFocus) {
454 | this.isDealWithFocus = isDealWithFocus;
455 | if (isDealWithFocus) {
456 | bindFocusSearchForBound();
457 | }
458 | }
459 |
460 | public boolean getIsDealWithFocus() {
461 | return isDealWithFocus;
462 | }
463 |
464 | /**
465 | * 获得默认获取焦点的View
466 | *
467 | * @return
468 | */
469 | public View myGetDefaultFocusView() {
470 | return defaultGetFocusView;
471 | }
472 |
473 | /**
474 | * 获得默认获取焦点的View
475 | *
476 | * @return
477 | */
478 | public View myGetDefaultFocusViewLB() {
479 | return defaultGetFocusViewLB;
480 | }
481 |
482 | /**
483 | * 获得默认获取焦点的View
484 | *
485 | * @return
486 | */
487 | public View myGetDefaultFocusViewRT() {
488 | return defaultGetFocusViewRT;
489 | }
490 |
491 | /**
492 | * 获得默认获取焦点的View
493 | *
494 | * @return
495 | */
496 | public View myGetDefaultFocusViewRB() {
497 | return defaultGetFocusViewRB;
498 | }
499 |
500 | private final BuildAdapterDataObserver observer = new BuildAdapterDataObserver() {
501 | @Override
502 | public void onChanged() {
503 | super.onChanged();
504 | initAdapter();
505 | }
506 | };
507 |
508 | /**
509 | * 设置布局适配器
510 | *
511 | * @param buildLayoutAdapter
512 | */
513 | public void setAdapter(BaseBuildLayoutAdapter buildLayoutAdapter) {
514 | if (DEBUG_CAN) DebugLog.i("setAdapter buildLayoutAdapter : " + buildLayoutAdapter);
515 | if (this.buildLayoutAdapter != null){
516 | this.buildLayoutAdapter.unregisterAdapterDataObserver(observer);
517 | }
518 | if (buildLayoutAdapter != null) {
519 | this.buildLayoutAdapter = buildLayoutAdapter;
520 | buildLayoutAdapter.registerAdapterDataObserver(observer);
521 | initAdapter();
522 | }
523 | }
524 |
525 | public BaseBuildLayoutAdapter getAdapter(){
526 | return buildLayoutAdapter;
527 | }
528 |
529 | private static BuildItemPoll itemPoll;
530 | public void setBuildItemPoll(BuildItemPoll poll){
531 | itemPoll = poll;
532 | }
533 |
534 | public BuildItemPoll getItemPoll(){
535 | return itemPoll;
536 | }
537 |
538 | public void detach(){
539 | if (itemPoll != null){
540 | itemPoll.putAllItemView(poll);
541 | childViews.clear();
542 | removeAllViews();
543 | }
544 | }
545 |
546 | private OnChildSelectListener onChildSelectListener;
547 | private OnChildClickListener onChildClickListener;
548 | private OnChildFocusChangeListener onChildFocusChangeListener;
549 |
550 | public void setOnChildSelectListener(OnChildSelectListener myListener) {
551 | this.onChildSelectListener = myListener;
552 | }
553 |
554 | public void setOnChildClickListener(OnChildClickListener myListener) {
555 | this.onChildClickListener = myListener;
556 | }
557 |
558 | public void setOnChildFocusChangeListener(OnChildFocusChangeListener myListener) {
559 | this.onChildFocusChangeListener = myListener;
560 | }
561 |
562 | public interface OnChildSelectListener {
563 | public void onChildSelect(View child, boolean isSelect);
564 | }
565 |
566 | public interface OnChildClickListener {
567 | public void onChildClick(View child);
568 | }
569 |
570 | public interface OnChildFocusChangeListener {
571 | public void onChildFocus(View child, boolean isFocus, boolean scalable, float scale);
572 | }
573 | }
574 |
--------------------------------------------------------------------------------
/app/src/main/java/com/fb/jjyyzjy/buildlayoutdemo/view/buildview/BuildLayoutUtils.java:
--------------------------------------------------------------------------------
1 | package com.fb.jjyyzjy.buildlayoutdemo.view.buildview;
2 |
3 | import com.fb.jjyyzjy.buildlayoutdemo.utils.CastUtils;
4 |
5 | /**
6 | * 自定义动态布局,辅助工具类
7 | * Created by ZJY on 2016/6/18.
8 | */
9 | public class BuildLayoutUtils {
10 |
11 | /**
12 | * 根据服务器返回数据转换成对应宽高尺寸
13 | * @param sSize
14 | * @param mW
15 | * @param mH
16 | * @return
17 | */
18 | public static int[] getBuildLayoutSize(String sSize, int mW, int mH){
19 | int[] size = new int[2];
20 | if (sSize != null){
21 | String[] sizeLayout = sSize.split("\\*");
22 | if (sizeLayout.length >= 2){
23 | size[0] = CastUtils.getIntForString(sizeLayout[0],mW);
24 | size[1] = CastUtils.getIntForString(sizeLayout[1],mH);
25 | }else {
26 | size[0] = mW;
27 | size[1] = mH;
28 | }
29 | }else {
30 | size[0] = mW;
31 | size[1] = mH;
32 | }
33 | return size;
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/app/src/main/java/com/fb/jjyyzjy/buildlayoutdemo/view/buildview/FocusSearchUtils.java:
--------------------------------------------------------------------------------
1 | package com.fb.jjyyzjy.buildlayoutdemo.view.buildview;
2 |
3 | import android.view.KeyEvent;
4 | import android.view.View;
5 |
6 | import com.fb.jjyyzjy.buildlayoutdemo.R;
7 | import com.fb.jjyyzjy.buildlayoutdemo.utils.DebugLog;
8 |
9 |
10 | /**
11 | * Created by JJYYZJY on 2017/5/3.
12 | */
13 | public class FocusSearchUtils {
14 |
15 | private static final boolean DEBUG = true;
16 |
17 | public static void bindFocusSearch(View viewLeft, View viewRight){
18 | if (DEBUG) DebugLog.i("bindFocusSearch viewLeft : "+viewLeft+", viewRight : "+viewRight);
19 | if (viewLeft == null || viewRight == null){
20 | return;
21 | }
22 | viewLeft.setTag(R.id.key_tag_focus_has_next_left,viewRight);
23 | viewRight.setTag(R.id.key_tag_focus_has_next_right,viewLeft);
24 | }
25 |
26 | public static void bindFocusSearch(View[] viewLeft, View[] viewRight){
27 | if (DEBUG) DebugLog.i("bindFocusSearch viewLeft[] : "+viewLeft+", viewRight[] : "+viewRight);
28 | if (viewLeft == null || viewRight == null){
29 | return;
30 | }
31 | int count = viewLeft.length > viewRight.length ? viewLeft.length : viewRight.length;
32 | for (int i = 0 ; i < count ; i++){
33 | bindFocusSearch(viewLeft[i >= viewLeft.length ? viewLeft.length-1 : i]
34 | ,viewRight[i >= viewRight.length ? viewRight.length-1 : i]);
35 | }
36 | }
37 |
38 | public static void unBindFocus(View viewLeft, View viewRight){
39 | if (viewLeft == null || viewRight == null){
40 | return;
41 | }
42 | viewLeft.setTag(R.id.key_tag_focus_has_next_left,null);
43 | viewRight.setTag(R.id.key_tag_focus_has_next_right,null);
44 | }
45 |
46 | public static void unBindFocus(View view){
47 | if (view == null){
48 | return;
49 | }
50 | view.setTag(R.id.key_tag_focus_has_next_left,null);
51 | view.setTag(R.id.key_tag_focus_has_next_right,null);
52 | }
53 |
54 | public static boolean requestFocusSearch(View focus, int direction){
55 | if (DEBUG) DebugLog.i("requestFocusSearch direction : "+direction+",focus : "+focus);
56 | if (focus == null){
57 | return false;
58 | }
59 | if (direction == View.FOCUS_LEFT){
60 | final View tag = (View) focus.getTag(R.id.key_tag_focus_has_next_left);
61 | if (tag != null){
62 | final View focusNext = tag.focusSearch(View.FOCUS_UP);
63 | if (DEBUG) DebugLog.i("FOCUS_LEFT focusNext : "+focusNext + "\n tag : "+tag);
64 | if (focusNext != null && focusNext != tag){
65 | boolean is = focusNext.requestFocus();
66 | DebugLog.w("FOCUS_LEFT isRequest : " + is);
67 | }
68 | return true;
69 | }
70 | }else if (direction == View.FOCUS_RIGHT){
71 | final View tag = (View) focus.getTag(R.id.key_tag_focus_has_next_right);
72 | if (tag != null){
73 | final View focusNext = tag.focusSearch(View.FOCUS_DOWN);
74 | if (DEBUG) DebugLog.i("FOCUS_RIGHT focusNext : "+focusNext + "\n tag : "+tag);
75 | if (focusNext != null && focusNext != tag) {
76 | boolean is = focusNext.requestFocus();
77 | DebugLog.w("FOCUS_RIGHT isRequest : " + is);
78 | }
79 | return true;
80 | }
81 | }
82 | return false;
83 | }
84 |
85 | public static boolean dispatchKeyEvent(View mRootView, KeyEvent event){
86 | if (DEBUG) DebugLog.i("dispatchKeyEvent event : " + event);
87 | if (event.getAction() == KeyEvent.ACTION_DOWN){
88 | if (event.getKeyCode() == KeyEvent.KEYCODE_DPAD_LEFT){
89 | final View focus = mRootView != null ? mRootView.findFocus() : null;
90 | if (focus != null){
91 | if (requestFocusSearch(focus, View.FOCUS_LEFT)){
92 | return true;
93 | }
94 | }
95 | }else if (event.getKeyCode() == KeyEvent.KEYCODE_DPAD_RIGHT){
96 | final View focus = mRootView != null ? mRootView.findFocus() : null;
97 | if (focus != null){
98 | if (requestFocusSearch(focus, View.FOCUS_RIGHT)){
99 | return true;
100 | }
101 | }
102 | }
103 | }
104 | return false;
105 | }
106 |
107 |
108 | }
109 |
--------------------------------------------------------------------------------
/app/src/main/java/com/fb/jjyyzjy/buildlayoutdemo/view/buildview/MyBuildLayout.java:
--------------------------------------------------------------------------------
1 | package com.fb.jjyyzjy.buildlayoutdemo.view.buildview;
2 |
3 | import android.content.Context;
4 | import android.util.AttributeSet;
5 | import android.view.KeyEvent;
6 | import android.view.View;
7 | import android.view.WindowManager;
8 |
9 | import com.fb.jjyyzjy.buildlayoutdemo.utils.DebugLog;
10 |
11 | /**
12 | * 动态表格布局
13 | * @author JJYYZJY
14 | */
15 | public class MyBuildLayout extends BuildLayout {
16 |
17 | public MyBuildLayout(Context context) {
18 | super(context);
19 | init();
20 | }
21 |
22 | public MyBuildLayout(Context context, AttributeSet attrs) {
23 | super(context, attrs);
24 | init();
25 | }
26 |
27 | public MyBuildLayout(Context context, AttributeSet attrs, int defStyle) {
28 | super(context, attrs, defStyle);
29 | init();
30 | }
31 |
32 | private void init() {
33 | WindowManager windowManager = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
34 | windowWidth = windowManager.getDefaultDisplay().getWidth();
35 | }
36 |
37 | /**
38 | * 焦点出界监听
39 | */
40 | private OnDismissFocusListener2 dismissListener;
41 | private OnOutOfBoundListener outOfBoundListener;
42 | private int windowWidth;
43 |
44 | @Override
45 | public boolean dispatchKeyEvent(KeyEvent event) {
46 | if (event.getAction() == KeyEvent.ACTION_DOWN) {
47 | if (DEBUG_CAN) DebugLog.i("dispatchKeyEvent ACTION_DOWN");
48 | View focus = findFocus();
49 | switch (event.getKeyCode()) {
50 | case KeyEvent.KEYCODE_DPAD_DOWN:
51 | if (focus.getBottom() == getHeight()) {
52 | if (dismissListener != null) {
53 | if (dismissListener.onDismissForBot(this)) {
54 | return true;
55 | }
56 | }
57 | } else {
58 | if (focusSearchWithTag(focus.getTag(), FOCUS_DOWN)) {
59 | return true;
60 | }
61 | }
62 | break;
63 | case KeyEvent.KEYCODE_DPAD_UP:
64 | if (focus.getTop() == 0) {
65 | if (dismissListener != null) {
66 | if (dismissListener.onDismissForTop(this)) {
67 | return true;
68 | }
69 | }
70 | } else {
71 | if (focusSearchWithTag(focus.getTag(), FOCUS_UP)) {
72 | return true;
73 | }
74 | }
75 | break;
76 | case KeyEvent.KEYCODE_DPAD_LEFT:
77 | if (focus.getLeft() == 0) {
78 | if (dismissListener != null) {
79 | if (dismissListener.onDismissForLeft(this)) {
80 | return true;
81 | }
82 | }
83 | } else {
84 | if (outOfBoundListener != null) {
85 | int[] location = new int[2];
86 | focus.getLocationInWindow(location);
87 | // MyLog.v("focus.getLeft()",""+focus.getLeft());
88 | // MyLog.v("location[0]",""+location[0]);
89 | // MyLog.v("itemWidth",""+itemWidth);
90 | // MyLog.v("dividing",""+dividing);
91 | if (focus.getLeft() > location[0] && location[0] < itemWidth + dividing) {
92 | if (DEBUG_CAN) DebugLog.i("outOfBoundListener ok");
93 | outOfBoundListener.onOutForLeft(focus);
94 | }
95 | }
96 |
97 | if (focusSearchWithTag(focus.getTag(), FOCUS_LEFT)) {
98 | return true;
99 | }
100 |
101 | }
102 | break;
103 | case KeyEvent.KEYCODE_DPAD_RIGHT:
104 | if (focus.getRight() == getWidth()) {
105 | if (dismissListener != null) {
106 | if (dismissListener.onDismissForRight(this)) {
107 | return true;
108 | }
109 | }
110 | } else {
111 | if (outOfBoundListener != null) {
112 |
113 | int[] location = new int[2];
114 | focus.getLocationInWindow(location);
115 |
116 | // MyLog.v("location[0] + itemWidth + dividing + itemWidth",""+ (location[0] + itemWidth + dividing + itemWidth));
117 |
118 | if (location[0] + itemWidth + dividing + itemWidth > windowWidth) {
119 | if (DEBUG_CAN) DebugLog.i("outOfBoundListener ok");
120 | outOfBoundListener.onOutForRight(focus);
121 | }
122 | }
123 |
124 | if (focusSearchWithTag(focus.getTag(), FOCUS_RIGHT)) {
125 | return true;
126 | }
127 |
128 | }
129 | break;
130 | }
131 | }
132 | return super.dispatchKeyEvent(event);
133 | }
134 |
135 | private boolean focusSearchWithTag(Object tag, int direction) {
136 | if (DEBUG_CAN) DebugLog.i(TAG + " focusSearchWithTag");
137 | if (tag instanceof int[]) {
138 | int[] layout = (int[]) tag;
139 | if (DEBUG_CAN)
140 | DebugLog.i(TAG + " focusSearchWithTag tag(layout) : [" + layout[0] + "," + layout[1] + "," + layout[2] + "," + layout[3] + "] direction : " + direction);
141 | switch (direction) {
142 | case FOCUS_UP:
143 | if (layout[2] >= 1) {
144 | View nextFocus = findViewWithFuzzyLayout(layout[0], layout[1] - 1, layout[3], FOCUS_UP);
145 | if (nextFocus != null) {
146 | return nextFocus.requestFocus();
147 | }
148 | }
149 | break;
150 | case FOCUS_DOWN:
151 | if (layout[2] >= 1) {
152 | View nextFocus = findViewWithFuzzyLayout(layout[0], layout[1] + layout[3], layout[2], FOCUS_DOWN);
153 | if (nextFocus != null) {
154 | return nextFocus.requestFocus();
155 | }
156 | }
157 | break;
158 | case FOCUS_LEFT:
159 | if (layout[3] >= 1) {
160 | View nextFocus = findViewWithFuzzyLayout(layout[0] - 1, layout[1], layout[3], FOCUS_LEFT);
161 | if (nextFocus != null) {
162 | return nextFocus.requestFocus();
163 | }
164 | }
165 | break;
166 | case FOCUS_RIGHT:
167 | if (layout[3] >= 1) {
168 | View nextFocus = findViewWithFuzzyLayout(layout[0] + layout[2], layout[1], layout[3], FOCUS_RIGHT);
169 | if (nextFocus != null) {
170 | return nextFocus.requestFocus();
171 | }
172 | }
173 | break;
174 | }
175 | }
176 | if (DEBUG_CAN) DebugLog.i(TAG + " focusSearchWithTag false");
177 | return false;
178 | }
179 |
180 | private View findViewWithFuzzyLayout(int x, int y, int range, int direction) {
181 | if (DEBUG_CAN)
182 | DebugLog.i(TAG + " findViewWithFuzzyLayout [x=" + x + ",y=" + y + ",range=" + range + ",direction=" + direction + "]");
183 | if (cViewTree == null || x < 0 || y < 0 || y >= cViewTree.length || x >= cViewTree[y].length) {
184 | if (DEBUG_CAN) DebugLog.w(TAG + " findViewWithFuzzyLayout parameter err");
185 | return null;
186 | }
187 | View nextView = null;
188 | switch (direction) {
189 | case FOCUS_UP:
190 | while (nextView == null && y >= 0) {
191 | int flag = 0;
192 | while (nextView == null && range > flag) {
193 | nextView = cViewTree[y][x + flag];
194 | if (DEBUG_CAN) {
195 | if (nextView != null)
196 | DebugLog.i("cViewTree[" + y + "][" + (x + flag) + "]");
197 | }
198 | flag++;
199 | }
200 | y--;
201 | }
202 | break;
203 | case FOCUS_DOWN:
204 | while (nextView == null && y >= 0 && y < cViewTree.length) {
205 | int flag = 0;
206 | while (nextView == null && range > flag) {
207 | nextView = cViewTree[y][x + flag];
208 | if (DEBUG_CAN) {
209 | if (nextView != null)
210 | DebugLog.i("cViewTree[" + y + "][" + (x + flag) + "]");
211 | }
212 | flag++;
213 | }
214 | y++;
215 | }
216 | break;
217 | case FOCUS_LEFT:
218 | while (nextView == null && x >= 0) {
219 | int flag = 0;
220 | while (nextView == null && range > flag) {
221 | nextView = cViewTree[y + flag][x];
222 | if (DEBUG_CAN) {
223 | if (nextView != null)
224 | DebugLog.i("cViewTree[" + (y + flag) + "][" + x + "]");
225 | }
226 | flag++;
227 | }
228 | x--;
229 | }
230 | break;
231 | case FOCUS_RIGHT:
232 | while (nextView == null && x >= 0 && x < cViewTree[y].length) {
233 | int flag = 0;
234 | while (nextView == null && range > flag) {
235 | nextView = cViewTree[y + flag][x];
236 | if (DEBUG_CAN) {
237 | if (nextView != null)
238 | DebugLog.i("cViewTree[" + (y + flag) + "][" + x + "]");
239 | }
240 | flag++;
241 | }
242 | x++;
243 | }
244 | break;
245 | }
246 | if (DEBUG_CAN) DebugLog.i(TAG + " findViewWithFuzzyLayout nextView : " + nextView);
247 | return nextView;
248 | }
249 |
250 |
251 | public View[] getLeftChildTree() {
252 | if (cViewTree != null) {
253 | View[] views = new View[cViewTree.length];
254 | for (int i = 0; i < cViewTree.length; i++) {
255 | if (cViewTree[i].length > 0) {
256 | views[i] = cViewTree[i][0];
257 | }
258 | }
259 | return views;
260 | }
261 | return null;
262 | }
263 |
264 | public View[] getRightChildTree() {
265 | DebugLog.i("getRightChildTree cViewTree : " + cViewTree.toString() + ",cViewTree.length : " + cViewTree.length);
266 | if (cViewTree != null) {
267 | View[] views = new View[cViewTree.length];
268 | for (int i = 0; i < cViewTree.length; i++) {
269 | if (cViewTree[i].length > 0) {
270 | views[i] = cViewTree[i][cViewTree[i].length - 1];
271 | DebugLog.i("views[" + i + "] : " + views[i]);
272 | }
273 | }
274 | return views;
275 | }
276 | return null;
277 | }
278 |
279 | public void setOnDismissFocusListener(OnDismissFocusListener2 dismissListener) {
280 | this.dismissListener = dismissListener;
281 | }
282 |
283 | public void setOnOutOfBoundListener(OnOutOfBoundListener outOfBoundListener) {
284 | this.outOfBoundListener = outOfBoundListener;
285 | }
286 |
287 | }
288 |
--------------------------------------------------------------------------------
/app/src/main/java/com/fb/jjyyzjy/buildlayoutdemo/view/buildview/OnDismissFocusListener2.java:
--------------------------------------------------------------------------------
1 | package com.fb.jjyyzjy.buildlayoutdemo.view.buildview;
2 |
3 | import android.view.View;
4 |
5 | /**
6 | * 失去焦点2_带返回_true为截断事件
7 | * Created by ZJY on 2016/4/26.
8 | */
9 | public interface OnDismissFocusListener2 {
10 | public boolean onDismissForTop(View v);
11 | public boolean onDismissForBot(View v);
12 | public boolean onDismissForLeft(View v);
13 | public boolean onDismissForRight(View v);
14 | }
15 |
--------------------------------------------------------------------------------
/app/src/main/java/com/fb/jjyyzjy/buildlayoutdemo/view/buildview/OnOutOfBoundListener.java:
--------------------------------------------------------------------------------
1 | package com.fb.jjyyzjy.buildlayoutdemo.view.buildview;
2 |
3 | import android.view.View;
4 |
5 | /**
6 | * 宽度超多视图窗口的view焦点超过视图监听
7 | * Created by ZJY on 2016/5/12.
8 | */
9 | public interface OnOutOfBoundListener {
10 | void onOutForRight(View v);
11 | void onOutForLeft(View v);
12 | }
13 |
--------------------------------------------------------------------------------
/app/src/main/java/com/fb/jjyyzjy/buildlayoutdemo/view/buildview/Parameter.java:
--------------------------------------------------------------------------------
1 | package com.fb.jjyyzjy.buildlayoutdemo.view.buildview;
2 |
3 | /**
4 | * Created by JJYYZJY on 2017/6/6.
5 | */
6 | public class Parameter {
7 |
8 | private int pageIndex;
9 | private int itemPosition;
10 |
11 | public int getPageIndex() {
12 | return pageIndex;
13 | }
14 |
15 | public void setPageIndex(int pageIndex) {
16 | this.pageIndex = pageIndex;
17 | }
18 |
19 | public int getItemPosition() {
20 | return itemPosition;
21 | }
22 |
23 | public void setItemPosition(int itemPosition) {
24 | this.itemPosition = itemPosition;
25 | }
26 |
27 | @Override
28 | public String toString() {
29 | return "Parameter{" +
30 | "pageIndex=" + pageIndex +
31 | ", itemPosition=" + itemPosition +
32 | '}';
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
16 |
17 |
30 |
31 |
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JJYYZJY/AndroidTvLayout/d33c76b6cc38c65bcc44607514a5321d449b6944/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JJYYZJY/AndroidTvLayout/d33c76b6cc38c65bcc44607514a5321d449b6944/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JJYYZJY/AndroidTvLayout/d33c76b6cc38c65bcc44607514a5321d449b6944/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JJYYZJY/AndroidTvLayout/d33c76b6cc38c65bcc44607514a5321d449b6944/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JJYYZJY/AndroidTvLayout/d33c76b6cc38c65bcc44607514a5321d449b6944/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JJYYZJY/AndroidTvLayout/d33c76b6cc38c65bcc44607514a5321d449b6944/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JJYYZJY/AndroidTvLayout/d33c76b6cc38c65bcc44607514a5321d449b6944/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JJYYZJY/AndroidTvLayout/d33c76b6cc38c65bcc44607514a5321d449b6944/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JJYYZJY/AndroidTvLayout/d33c76b6cc38c65bcc44607514a5321d449b6944/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JJYYZJY/AndroidTvLayout/d33c76b6cc38c65bcc44607514a5321d449b6944/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/values-1024x575/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | values-nodpi-1024x575
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/values-1024x600/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | values-nodpi-1024x600
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/values-1024x720/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | values-nodpi-1024x720
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/values-1152x648/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | values-nodpi-1152x648
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/values-1196x720/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | values-nodpi-1196x720
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/values-1196x768/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | values-nodpi-1196x768
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/values-1200x720/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | values-nodpi-1200x720
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/values-1203x676/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | values-nodpi-1203x676
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/values-1216x684/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | values-nodpi-1216x684
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/values-1220x690/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | values-nodpi-1220x690
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/values-1228x691/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | values-nodpi-1228x691
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/values-1241x698/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | values-nodpi-1241x698
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/values-1267x712/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | values-nodpi-1267x712
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/values-1278x718/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | values-nodpi-1278x718
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/values-1280x656/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | values-nodpi-1280x656
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/values-1280x672/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -18.0px
4 | 1533.0px
5 | 1600.0px
6 | 1280.0px
7 | 720.0px
8 | -10.0px
9 | -15.0px
10 | -333.0px
11 | 0.0px
12 | 1.0px
13 | 2.0px
14 | 2.0px
15 | 3.0px
16 | 4.0px
17 | 4.0px
18 | 5.0px
19 | 6.0px
20 | 6.0px
21 | 7.0px
22 | 8.0px
23 | 8.0px
24 | 9.0px
25 | 10.0px
26 | 10.0px
27 | 11.0px
28 | 12.0px
29 | 12.0px
30 | 13.0px
31 | 14.0px
32 | 14.0px
33 | 15.0px
34 | 16.0px
35 | 16.0px
36 | 17.0px
37 | 18.0px
38 | 18.0px
39 | 19.0px
40 | 20.0px
41 | 20.0px
42 | 21.0px
43 | 22.0px
44 | 22.0px
45 | 23.0px
46 | 24.0px
47 | 24.0px
48 | 25.0px
49 | 26.0px
50 | 26.0px
51 | 27.0px
52 | 28.0px
53 | 28.0px
54 | 29.0px
55 | 30.0px
56 | 30.0px
57 | 31.0px
58 | 32.0px
59 | 32.0px
60 | 33.0px
61 | 34.0px
62 | 34.0px
63 | 35.0px
64 | 36.0px
65 | 36.0px
66 | 37.0px
67 | -37.0px
68 | 38.0px
69 | 38.0px
70 | 39.0px
71 | 40.0px
72 | 40.0px
73 | 41.0px
74 | 42.0px
75 | 42.0px
76 | 43.0px
77 | 44.0px
78 | 44.0px
79 | 45.0px
80 | 46.0px
81 | 46.0px
82 | 47.0px
83 | 48.0px
84 | 48.0px
85 | 49.0px
86 | 50.0px
87 | 50.0px
88 | 51.0px
89 | 52.0px
90 | 52.0px
91 | 53.0px
92 | 54.0px
93 | 54.0px
94 | 55.0px
95 | 56.0px
96 | 56.0px
97 | 57.0px
98 | 58.0px
99 | 58.0px
100 | 59.0px
101 | 60.0px
102 | 60.0px
103 | 61.0px
104 | 62.0px
105 | 62.0px
106 | 63.0px
107 | 64.0px
108 | 64.0px
109 | 65.0px
110 | 66.0px
111 | 66.0px
112 | 67.0px
113 | 68.0px
114 | 68.0px
115 | 69.0px
116 | 70.0px
117 | 70.0px
118 | 71.0px
119 | 72.0px
120 | 72.0px
121 | 73.0px
122 | 74.0px
123 | 74.0px
124 | 75.0px
125 | 76.0px
126 | 76.0px
127 | 77.0px
128 | 78.0px
129 | 78.0px
130 | 79.0px
131 | 80.0px
132 | 80.0px
133 | 81.0px
134 | 82.0px
135 | 82.0px
136 | 83.0px
137 | 84.0px
138 | 84.0px
139 | 85.0px
140 | 86.0px
141 | 86.0px
142 | 87.0px
143 | 88.0px
144 | 88.0px
145 | 89.0px
146 | 90.0px
147 | 90.0px
148 | 91.0px
149 | 92.0px
150 | 92.0px
151 | 93.0px
152 | 94.0px
153 | 94.0px
154 | 95.0px
155 | 96.0px
156 | 96.0px
157 | 97.0px
158 | 98.0px
159 | 98.0px
160 | 99.0px
161 | 100.0px
162 | 100.0px
163 | 101.0px
164 | 102.0px
165 | 102.0px
166 | 103.0px
167 | 104.0px
168 | 104.0px
169 | 105.0px
170 | 106.0px
171 | 106.0px
172 | 107.0px
173 | 108.0px
174 | 108.0px
175 | 109.0px
176 | 110.0px
177 | 110.0px
178 | 111.0px
179 | 112.0px
180 | 112.0px
181 | 113.0px
182 | 114.0px
183 | 114.0px
184 | 115.0px
185 | 116.0px
186 | 116.0px
187 | 117.0px
188 | 118.0px
189 | 118.0px
190 | 119.0px
191 | 120.0px
192 | 120.0px
193 | 121.0px
194 | 122.0px
195 | 122.0px
196 | 123.0px
197 | 124.0px
198 | 124.0px
199 | 125.0px
200 | 126.0px
201 | 126.0px
202 | 127.0px
203 | 128.0px
204 | 128.0px
205 | 129.0px
206 | 130.0px
207 | 130.0px
208 | 131.0px
209 | 132.0px
210 | 132.0px
211 | 133.0px
212 | 134.0px
213 | 134.0px
214 | 135.0px
215 | 136.0px
216 | 136.0px
217 | 137.0px
218 | 138.0px
219 | 138.0px
220 | 139.0px
221 | 140.0px
222 | 140.0px
223 | 141.0px
224 | 142.0px
225 | 142.0px
226 | 143.0px
227 | 144.0px
228 | 144.0px
229 | 145.0px
230 | 146.0px
231 | 146.0px
232 | 147.0px
233 | 148.0px
234 | 148.0px
235 | 149.0px
236 | 150.0px
237 | 150.0px
238 | 151.0px
239 | 152.0px
240 | 152.0px
241 | 153.0px
242 | 154.0px
243 | 154.0px
244 | 155.0px
245 | 156.0px
246 | 156.0px
247 | 157.0px
248 | 158.0px
249 | 158.0px
250 | 159.0px
251 | 160.0px
252 | 160.0px
253 | 161.0px
254 | 162.0px
255 | 162.0px
256 | 163.0px
257 | 164.0px
258 | 164.0px
259 | 165.0px
260 | 166.0px
261 | 166.0px
262 | 167.0px
263 | 168.0px
264 | 168.0px
265 | 169.0px
266 | 170.0px
267 | 170.0px
268 | 171.0px
269 | 172.0px
270 | 172.0px
271 | 173.0px
272 | 174.0px
273 | 174.0px
274 | 175.0px
275 | 176.0px
276 | 176.0px
277 | 177.0px
278 | 178.0px
279 | 178.0px
280 | 179.0px
281 | 180.0px
282 | 180.0px
283 | 181.0px
284 | 182.0px
285 | 182.0px
286 | 183.0px
287 | 184.0px
288 | 184.0px
289 | 185.0px
290 | 186.0px
291 | 186.0px
292 | 187.0px
293 | 188.0px
294 | 188.0px
295 | 189.0px
296 | 190.0px
297 | 190.0px
298 | 191.0px
299 | 192.0px
300 | 192.0px
301 | 193.0px
302 | 194.0px
303 | 194.0px
304 | 195.0px
305 | 196.0px
306 | 196.0px
307 | 197.0px
308 | 198.0px
309 | 198.0px
310 | 199.0px
311 | 200.0px
312 | 200.0px
313 | 201.0px
314 | 202.0px
315 | 202.0px
316 | 203.0px
317 | 204.0px
318 | 204.0px
319 | 205.0px
320 | 206.0px
321 | 206.0px
322 | 207.0px
323 | 208.0px
324 | 208.0px
325 | 209.0px
326 | 210.0px
327 | 210.0px
328 | 211.0px
329 | 212.0px
330 | 212.0px
331 | 213.0px
332 | 214.0px
333 | 214.0px
334 | 215.0px
335 | 216.0px
336 | 216.0px
337 | 217.0px
338 | 218.0px
339 | 218.0px
340 | 219.0px
341 | 220.0px
342 | 220.0px
343 | 221.0px
344 | 222.0px
345 | 222.0px
346 | 223.0px
347 | 224.0px
348 | 224.0px
349 | 225.0px
350 | 226.0px
351 | 226.0px
352 | 227.0px
353 | 228.0px
354 | 228.0px
355 | 229.0px
356 | 230.0px
357 | 230.0px
358 | 231.0px
359 | 232.0px
360 | 232.0px
361 | 233.0px
362 | 234.0px
363 | 234.0px
364 | 235.0px
365 | 236.0px
366 | 236.0px
367 | 237.0px
368 | 238.0px
369 | 238.0px
370 | 239.0px
371 | 240.0px
372 | 240.0px
373 | 241.0px
374 | 242.0px
375 | 242.0px
376 | 243.0px
377 | 244.0px
378 | 244.0px
379 | 245.0px
380 | 246.0px
381 | 246.0px
382 | 247.0px
383 | 248.0px
384 | 248.0px
385 | 249.0px
386 | 250.0px
387 | 250.0px
388 | 251.0px
389 | 252.0px
390 | 252.0px
391 | 253.0px
392 | 254.0px
393 | 254.0px
394 | 255.0px
395 | 256.0px
396 | 256.0px
397 | 257.0px
398 | 258.0px
399 | 258.0px
400 | 259.0px
401 | 260.0px
402 | 260.0px
403 | 261.0px
404 | 262.0px
405 | 262.0px
406 | 263.0px
407 | 264.0px
408 | 264.0px
409 | 265.0px
410 | 266.0px
411 | 266.0px
412 | 267.0px
413 | 268.0px
414 | 268.0px
415 | 269.0px
416 | 270.0px
417 | 270.0px
418 | 271.0px
419 | 272.0px
420 | 272.0px
421 | 273.0px
422 | 274.0px
423 | 274.0px
424 | 275.0px
425 | 276.0px
426 | 276.0px
427 | 277.0px
428 | 278.0px
429 | 278.0px
430 | 279.0px
431 | 280.0px
432 | 280.0px
433 | 281.0px
434 | 282.0px
435 | 282.0px
436 | 283.0px
437 | 284.0px
438 | 284.0px
439 | 285.0px
440 | 286.0px
441 | 286.0px
442 | 287.0px
443 | 288.0px
444 | 288.0px
445 | 289.0px
446 | 290.0px
447 | 290.0px
448 | 291.0px
449 | 292.0px
450 | 292.0px
451 | 293.0px
452 | 294.0px
453 | 294.0px
454 | 295.0px
455 | 296.0px
456 | 296.0px
457 | 297.0px
458 | 298.0px
459 | 298.0px
460 | 299.0px
461 | 300.0px
462 | 300.0px
463 | 301.0px
464 | 302.0px
465 | 302.0px
466 | 303.0px
467 | 304.0px
468 | 304.0px
469 | 305.0px
470 | 306.0px
471 | 306.0px
472 | 307.0px
473 | 308.0px
474 | 308.0px
475 | 309.0px
476 | 310.0px
477 | 310.0px
478 | 311.0px
479 | 312.0px
480 | 312.0px
481 | 313.0px
482 | 314.0px
483 | 314.0px
484 | 315.0px
485 | 316.0px
486 | 316.0px
487 | 317.0px
488 | 318.0px
489 | 318.0px
490 | 319.0px
491 | 320.0px
492 | 320.0px
493 | 321.0px
494 | 322.0px
495 | 322.0px
496 | 323.0px
497 | 324.0px
498 | 324.0px
499 | 325.0px
500 | 326.0px
501 | 326.0px
502 | 327.0px
503 | 328.0px
504 | 328.0px
505 | 329.0px
506 | 330.0px
507 | 330.0px
508 | 331.0px
509 | 332.0px
510 | 332.0px
511 | 333.0px
512 | 334.0px
513 | 334.0px
514 | 335.0px
515 | 336.0px
516 | 336.0px
517 | 337.0px
518 | 338.0px
519 | 338.0px
520 | 339.0px
521 | 340.0px
522 | 340.0px
523 | 341.0px
524 | 342.0px
525 | 342.0px
526 | 343.0px
527 | 344.0px
528 | 344.0px
529 | 345.0px
530 | 346.0px
531 | 346.0px
532 | 347.0px
533 | 348.0px
534 | 348.0px
535 | 349.0px
536 | 350.0px
537 | 350.0px
538 | 351.0px
539 | 352.0px
540 | 352.0px
541 | 353.0px
542 | 354.0px
543 | 354.0px
544 | 355.0px
545 | 356.0px
546 | 356.0px
547 | 357.0px
548 | 358.0px
549 | 358.0px
550 | 359.0px
551 | 360.0px
552 | 360.0px
553 | 361.0px
554 | 362.0px
555 | 362.0px
556 | 363.0px
557 | 364.0px
558 | 364.0px
559 | 365.0px
560 | 366.0px
561 | 366.0px
562 | 367.0px
563 | 368.0px
564 | 368.0px
565 | 369.0px
566 | 370.0px
567 | 370.0px
568 | 371.0px
569 | 372.0px
570 | 372.0px
571 | 373.0px
572 | 374.0px
573 | 374.0px
574 | 375.0px
575 | 376.0px
576 | 376.0px
577 | 377.0px
578 | 378.0px
579 | 378.0px
580 | 379.0px
581 | 380.0px
582 | 380.0px
583 | 381.0px
584 | 382.0px
585 | 382.0px
586 | 383.0px
587 | 384.0px
588 | 384.0px
589 | 385.0px
590 | 386.0px
591 | 386.0px
592 | 387.0px
593 | 388.0px
594 | 388.0px
595 | 389.0px
596 | 390.0px
597 | 390.0px
598 | 391.0px
599 | 392.0px
600 | 392.0px
601 | 393.0px
602 | 394.0px
603 | 394.0px
604 | 395.0px
605 | 396.0px
606 | 396.0px
607 | 397.0px
608 | 398.0px
609 | 398.0px
610 | 399.0px
611 | 400.0px
612 | 400.0px
613 | 401.0px
614 | 402.0px
615 | 402.0px
616 | 403.0px
617 | 404.0px
618 | 404.0px
619 | 405.0px
620 | 406.0px
621 | 406.0px
622 | 407.0px
623 | 408.0px
624 | 408.0px
625 | 409.0px
626 | 410.0px
627 | 410.0px
628 | 411.0px
629 | 412.0px
630 | 412.0px
631 | 413.0px
632 | 414.0px
633 | 414.0px
634 | 415.0px
635 | 416.0px
636 | 416.0px
637 | 417.0px
638 | 418.0px
639 | 418.0px
640 | 419.0px
641 | 420.0px
642 | 420.0px
643 | 421.0px
644 | 422.0px
645 | 422.0px
646 | 423.0px
647 | 424.0px
648 | 424.0px
649 | 425.0px
650 | 426.0px
651 | 426.0px
652 | 427.0px
653 | 428.0px
654 | 428.0px
655 | 429.0px
656 | 430.0px
657 | 430.0px
658 | 431.0px
659 | 432.0px
660 | 432.0px
661 | 433.0px
662 | 434.0px
663 | 434.0px
664 | 435.0px
665 | 436.0px
666 | 436.0px
667 | 437.0px
668 | 438.0px
669 | 438.0px
670 | 439.0px
671 | 440.0px
672 | 440.0px
673 | 441.0px
674 | 442.0px
675 | 442.0px
676 | 443.0px
677 | 444.0px
678 | 444.0px
679 | 445.0px
680 | 446.0px
681 | 446.0px
682 | 447.0px
683 | 448.0px
684 | 448.0px
685 | 449.0px
686 | 450.0px
687 | 450.0px
688 | 451.0px
689 | 452.0px
690 | 452.0px
691 | 453.0px
692 | 454.0px
693 | 454.0px
694 | 455.0px
695 | 456.0px
696 | 456.0px
697 | 457.0px
698 | 458.0px
699 | 458.0px
700 | 459.0px
701 | 460.0px
702 | 460.0px
703 | 461.0px
704 | 462.0px
705 | 462.0px
706 | 463.0px
707 | 464.0px
708 | 464.0px
709 | 465.0px
710 | 466.0px
711 | 466.0px
712 | 467.0px
713 | 468.0px
714 | 468.0px
715 | 469.0px
716 | 470.0px
717 | 470.0px
718 | 471.0px
719 | 472.0px
720 | 472.0px
721 | 473.0px
722 | 474.0px
723 | 474.0px
724 | 475.0px
725 | 476.0px
726 | 476.0px
727 | 477.0px
728 | 478.0px
729 | 478.0px
730 | 479.0px
731 | 480.0px
732 | 480.0px
733 | 481.0px
734 | 482.0px
735 | 482.0px
736 | 483.0px
737 | 484.0px
738 | 484.0px
739 | 485.0px
740 | 486.0px
741 | 486.0px
742 | 487.0px
743 | 488.0px
744 | 488.0px
745 | 489.0px
746 | 490.0px
747 | 490.0px
748 | 491.0px
749 | 492.0px
750 | 492.0px
751 | 493.0px
752 | 494.0px
753 | 494.0px
754 | 495.0px
755 | 496.0px
756 | 496.0px
757 | 497.0px
758 | 498.0px
759 | 498.0px
760 | 499.0px
761 | 500.0px
762 | 500.0px
763 | 501.0px
764 | 502.0px
765 | 502.0px
766 | 503.0px
767 | 504.0px
768 | 504.0px
769 | 505.0px
770 | 506.0px
771 | 506.0px
772 | 507.0px
773 | 508.0px
774 | 508.0px
775 | 509.0px
776 | 510.0px
777 | 510.0px
778 | 511.0px
779 | 512.0px
780 | 512.0px
781 | 513.0px
782 | 514.0px
783 | 514.0px
784 | 515.0px
785 | 516.0px
786 | 516.0px
787 | 517.0px
788 | 518.0px
789 | 518.0px
790 | 519.0px
791 | 520.0px
792 | 520.0px
793 | 521.0px
794 | 522.0px
795 | 522.0px
796 | 523.0px
797 | 524.0px
798 | 524.0px
799 | 525.0px
800 | 526.0px
801 | 526.0px
802 | 527.0px
803 | 528.0px
804 | 528.0px
805 | 529.0px
806 | 530.0px
807 | 530.0px
808 | 531.0px
809 | 532.0px
810 | 532.0px
811 | 533.0px
812 | 534.0px
813 | 534.0px
814 | 535.0px
815 | 536.0px
816 | 536.0px
817 | 537.0px
818 | 538.0px
819 | 538.0px
820 | 539.0px
821 | 540.0px
822 | 540.0px
823 | 541.0px
824 | 542.0px
825 | 542.0px
826 | 543.0px
827 | 544.0px
828 | 544.0px
829 | 545.0px
830 | 546.0px
831 | 546.0px
832 | 547.0px
833 | 548.0px
834 | 548.0px
835 | 549.0px
836 | 550.0px
837 | 550.0px
838 | 551.0px
839 | 552.0px
840 | 552.0px
841 | 553.0px
842 | 554.0px
843 | 554.0px
844 | 555.0px
845 | 556.0px
846 | 556.0px
847 | 557.0px
848 | 558.0px
849 | 558.0px
850 | 559.0px
851 | 560.0px
852 | 560.0px
853 | 561.0px
854 | 562.0px
855 | 562.0px
856 | 563.0px
857 | 564.0px
858 | 564.0px
859 | 565.0px
860 | 566.0px
861 | 566.0px
862 | 567.0px
863 | 568.0px
864 | 568.0px
865 | 569.0px
866 | 570.0px
867 | 570.0px
868 | 571.0px
869 | 572.0px
870 | 572.0px
871 | 573.0px
872 | 574.0px
873 | 574.0px
874 | 575.0px
875 | 576.0px
876 | 576.0px
877 | 577.0px
878 | 578.0px
879 | 578.0px
880 | 579.0px
881 | 580.0px
882 | 580.0px
883 | 581.0px
884 | 582.0px
885 | 582.0px
886 | 583.0px
887 | 584.0px
888 | 584.0px
889 | 585.0px
890 | 586.0px
891 | 586.0px
892 | 587.0px
893 | 588.0px
894 | 588.0px
895 | 589.0px
896 | 590.0px
897 | 590.0px
898 | 591.0px
899 | 592.0px
900 | 592.0px
901 | 593.0px
902 | 594.0px
903 | 594.0px
904 | 595.0px
905 | 596.0px
906 | 596.0px
907 | 597.0px
908 | 598.0px
909 | 598.0px
910 | 599.0px
911 | 600.0px
912 | 600.0px
913 | 601.0px
914 | 602.0px
915 | 602.0px
916 | 603.0px
917 | 604.0px
918 | 604.0px
919 | 605.0px
920 | 606.0px
921 | 606.0px
922 | 607.0px
923 | 608.0px
924 | 608.0px
925 | 609.0px
926 | 610.0px
927 | 610.0px
928 | 611.0px
929 | 612.0px
930 | 612.0px
931 | 613.0px
932 | 614.0px
933 | 614.0px
934 | 615.0px
935 | 616.0px
936 | 616.0px
937 | 617.0px
938 | 618.0px
939 | 618.0px
940 | 619.0px
941 | 620.0px
942 | 620.0px
943 | 621.0px
944 | 622.0px
945 | 622.0px
946 | 623.0px
947 | 624.0px
948 | 624.0px
949 | 625.0px
950 | 626.0px
951 | 626.0px
952 | 627.0px
953 | 628.0px
954 | 628.0px
955 | 629.0px
956 | 630.0px
957 | 630.0px
958 | 631.0px
959 | 632.0px
960 | 632.0px
961 | 633.0px
962 | 634.0px
963 | 634.0px
964 | 635.0px
965 | 636.0px
966 | 636.0px
967 | 637.0px
968 | 638.0px
969 | 638.0px
970 | 639.0px
971 | 640.0px
972 | 640.0px
973 | 641.0px
974 | 642.0px
975 | 642.0px
976 | 643.0px
977 | 644.0px
978 | 644.0px
979 | 645.0px
980 | 646.0px
981 | 646.0px
982 | 647.0px
983 | 648.0px
984 | 648.0px
985 | 649.0px
986 | 650.0px
987 | 650.0px
988 | 651.0px
989 | 652.0px
990 | 652.0px
991 | 653.0px
992 | 654.0px
993 | 654.0px
994 | 655.0px
995 | 656.0px
996 | 656.0px
997 | 657.0px
998 | 658.0px
999 | 658.0px
1000 | 659.0px
1001 | 660.0px
1002 | 660.0px
1003 | 661.0px
1004 | 662.0px
1005 | 662.0px
1006 | 663.0px
1007 | 664.0px
1008 | 664.0px
1009 | 665.0px
1010 | 666.0px
1011 | 666.0px
1012 | 667.0px
1013 | 668.0px
1014 | 668.0px
1015 | 669.0px
1016 | 670.0px
1017 | 670.0px
1018 | 671.0px
1019 | 672.0px
1020 | 672.0px
1021 | 673.0px
1022 | 674.0px
1023 | 674.0px
1024 | 675.0px
1025 | 676.0px
1026 | 676.0px
1027 | 677.0px
1028 | 678.0px
1029 | 678.0px
1030 | 679.0px
1031 | 680.0px
1032 | 680.0px
1033 | 681.0px
1034 | 682.0px
1035 | 682.0px
1036 | 683.0px
1037 | 684.0px
1038 | 684.0px
1039 | 685.0px
1040 | 686.0px
1041 | 686.0px
1042 | 687.0px
1043 | 688.0px
1044 | 688.0px
1045 | 689.0px
1046 | 690.0px
1047 | 690.0px
1048 | 691.0px
1049 | 692.0px
1050 | 692.0px
1051 | 693.0px
1052 | 694.0px
1053 | 694.0px
1054 | 695.0px
1055 | 696.0px
1056 | 696.0px
1057 | 697.0px
1058 | 698.0px
1059 | 698.0px
1060 | 699.0px
1061 | 700.0px
1062 | 700.0px
1063 | 701.0px
1064 | 702.0px
1065 | 702.0px
1066 | 703.0px
1067 | 704.0px
1068 | 704.0px
1069 | 705.0px
1070 | 706.0px
1071 | 706.0px
1072 | 707.0px
1073 | 708.0px
1074 | 708.0px
1075 | 709.0px
1076 | 710.0px
1077 | 710.0px
1078 | 711.0px
1079 | 712.0px
1080 | 712.0px
1081 | 713.0px
1082 | 714.0px
1083 | 714.0px
1084 | 715.0px
1085 | 716.0px
1086 | 716.0px
1087 | 717.0px
1088 | 718.0px
1089 | 718.0px
1090 | 719.0px
1091 | 720.0px
1092 | 720.0px
1093 | 721.0px
1094 | 722.0px
1095 | 722.0px
1096 | 723.0px
1097 | 724.0px
1098 | 724.0px
1099 | 725.0px
1100 | 726.0px
1101 | 726.0px
1102 | 727.0px
1103 | 728.0px
1104 | 728.0px
1105 | 729.0px
1106 | 730.0px
1107 | 730.0px
1108 | 731.0px
1109 | 732.0px
1110 | 732.0px
1111 | 733.0px
1112 | 734.0px
1113 | 734.0px
1114 | 735.0px
1115 | 736.0px
1116 | 736.0px
1117 | 737.0px
1118 | 738.0px
1119 | 738.0px
1120 | 739.0px
1121 | 740.0px
1122 | 740.0px
1123 | 741.0px
1124 | 742.0px
1125 | 742.0px
1126 | 743.0px
1127 | 744.0px
1128 | 744.0px
1129 | 745.0px
1130 | 746.0px
1131 | 746.0px
1132 | 747.0px
1133 | 748.0px
1134 | 748.0px
1135 | 749.0px
1136 | 750.0px
1137 | 750.0px
1138 | 751.0px
1139 | 752.0px
1140 | 752.0px
1141 | 753.0px
1142 | 754.0px
1143 | 754.0px
1144 | 755.0px
1145 | 756.0px
1146 | 756.0px
1147 | 757.0px
1148 | 758.0px
1149 | 758.0px
1150 | 759.0px
1151 | 760.0px
1152 | 760.0px
1153 | 761.0px
1154 | 762.0px
1155 | 762.0px
1156 | 763.0px
1157 | 764.0px
1158 | 764.0px
1159 | 765.0px
1160 | 766.0px
1161 | 766.0px
1162 | 767.0px
1163 | 768.0px
1164 | 768.0px
1165 | 769.0px
1166 | 770.0px
1167 | 770.0px
1168 | 771.0px
1169 | 772.0px
1170 | 772.0px
1171 | 773.0px
1172 | 774.0px
1173 | 774.0px
1174 | 775.0px
1175 | 776.0px
1176 | 776.0px
1177 | 777.0px
1178 | 778.0px
1179 | 778.0px
1180 | 779.0px
1181 | 780.0px
1182 | 780.0px
1183 | 781.0px
1184 | 782.0px
1185 | 782.0px
1186 | 783.0px
1187 | 784.0px
1188 | 784.0px
1189 | 785.0px
1190 | 786.0px
1191 | 786.0px
1192 | 787.0px
1193 | 788.0px
1194 | 788.0px
1195 | 789.0px
1196 | 790.0px
1197 | 790.0px
1198 | 791.0px
1199 | 792.0px
1200 | 792.0px
1201 | 793.0px
1202 | 794.0px
1203 | 794.0px
1204 | 795.0px
1205 | 796.0px
1206 | 796.0px
1207 | 797.0px
1208 | 798.0px
1209 | 798.0px
1210 | 799.0px
1211 | 800.0px
1212 | 800.0px
1213 | 801.0px
1214 | 802.0px
1215 | 802.0px
1216 | 803.0px
1217 | 804.0px
1218 | 804.0px
1219 | 805.0px
1220 | 806.0px
1221 | 806.0px
1222 | 807.0px
1223 | 808.0px
1224 | 808.0px
1225 | 809.0px
1226 | 810.0px
1227 | 810.0px
1228 | 811.0px
1229 | 812.0px
1230 | 812.0px
1231 | 813.0px
1232 | 814.0px
1233 | 814.0px
1234 | 815.0px
1235 | 816.0px
1236 | 816.0px
1237 | 817.0px
1238 | 818.0px
1239 | 818.0px
1240 | 819.0px
1241 | 820.0px
1242 | 820.0px
1243 | 821.0px
1244 | 822.0px
1245 | 822.0px
1246 | 823.0px
1247 | 824.0px
1248 | 824.0px
1249 | 825.0px
1250 | 826.0px
1251 | 826.0px
1252 | 827.0px
1253 | 828.0px
1254 | 828.0px
1255 | 829.0px
1256 | 830.0px
1257 | 830.0px
1258 | 831.0px
1259 | 832.0px
1260 | 832.0px
1261 | 833.0px
1262 | 834.0px
1263 | 834.0px
1264 | 835.0px
1265 | 836.0px
1266 | 836.0px
1267 | 837.0px
1268 | 838.0px
1269 | 838.0px
1270 | 839.0px
1271 | 840.0px
1272 | 840.0px
1273 | 841.0px
1274 | 842.0px
1275 | 842.0px
1276 | 843.0px
1277 | 844.0px
1278 | 844.0px
1279 | 845.0px
1280 | 846.0px
1281 | 846.0px
1282 | 847.0px
1283 | 848.0px
1284 | 848.0px
1285 | 849.0px
1286 | 850.0px
1287 | 850.0px
1288 | 851.0px
1289 | 852.0px
1290 | 852.0px
1291 | 853.0px
1292 | 854.0px
1293 | 854.0px
1294 | 855.0px
1295 | 856.0px
1296 | 856.0px
1297 | 857.0px
1298 | 858.0px
1299 | 858.0px
1300 | 859.0px
1301 | 860.0px
1302 | 860.0px
1303 | 861.0px
1304 | 862.0px
1305 | 862.0px
1306 | 863.0px
1307 | 864.0px
1308 | 864.0px
1309 | 865.0px
1310 | 866.0px
1311 | 866.0px
1312 | 867.0px
1313 | 868.0px
1314 | 868.0px
1315 | 869.0px
1316 | 870.0px
1317 | 870.0px
1318 | 871.0px
1319 | 872.0px
1320 | 872.0px
1321 | 873.0px
1322 | 874.0px
1323 | 874.0px
1324 | 875.0px
1325 | 876.0px
1326 | 876.0px
1327 | 877.0px
1328 | 878.0px
1329 | 878.0px
1330 | 879.0px
1331 | 880.0px
1332 | 880.0px
1333 | 881.0px
1334 | 882.0px
1335 | 882.0px
1336 | 883.0px
1337 | 884.0px
1338 | 884.0px
1339 | 885.0px
1340 | 886.0px
1341 | 886.0px
1342 | 887.0px
1343 | 888.0px
1344 | 888.0px
1345 | 889.0px
1346 | 890.0px
1347 | 890.0px
1348 | 891.0px
1349 | 892.0px
1350 | 892.0px
1351 | 893.0px
1352 | 894.0px
1353 | 894.0px
1354 | 895.0px
1355 | 896.0px
1356 | 896.0px
1357 | 897.0px
1358 | 898.0px
1359 | 898.0px
1360 | 899.0px
1361 | 900.0px
1362 | 900.0px
1363 | 901.0px
1364 | 902.0px
1365 | 902.0px
1366 | 903.0px
1367 | 904.0px
1368 | 904.0px
1369 | 905.0px
1370 | 906.0px
1371 | 906.0px
1372 | 907.0px
1373 | 908.0px
1374 | 908.0px
1375 | 909.0px
1376 | 910.0px
1377 | 910.0px
1378 | 911.0px
1379 | 912.0px
1380 | 912.0px
1381 | 913.0px
1382 | 914.0px
1383 | 914.0px
1384 | 915.0px
1385 | 916.0px
1386 | 916.0px
1387 | 917.0px
1388 | 918.0px
1389 | 918.0px
1390 | 919.0px
1391 | 920.0px
1392 | 920.0px
1393 | 921.0px
1394 | 922.0px
1395 | 922.0px
1396 | 923.0px
1397 | 924.0px
1398 | 924.0px
1399 | 925.0px
1400 | 926.0px
1401 | 926.0px
1402 | 927.0px
1403 | 928.0px
1404 | 928.0px
1405 | 929.0px
1406 | 930.0px
1407 | 930.0px
1408 | 931.0px
1409 | 932.0px
1410 | 932.0px
1411 | 933.0px
1412 | 934.0px
1413 | 934.0px
1414 | 935.0px
1415 | 936.0px
1416 | 936.0px
1417 | 937.0px
1418 | 938.0px
1419 | 938.0px
1420 | 939.0px
1421 | 940.0px
1422 | 940.0px
1423 | 941.0px
1424 | 942.0px
1425 | 942.0px
1426 | 943.0px
1427 | 944.0px
1428 | 944.0px
1429 | 945.0px
1430 | 946.0px
1431 | 946.0px
1432 | 947.0px
1433 | 948.0px
1434 | 948.0px
1435 | 949.0px
1436 | 950.0px
1437 | 950.0px
1438 | 951.0px
1439 | 952.0px
1440 | 952.0px
1441 | 953.0px
1442 | 954.0px
1443 | 954.0px
1444 | 955.0px
1445 | 956.0px
1446 | 956.0px
1447 | 957.0px
1448 | 958.0px
1449 | 958.0px
1450 | 959.0px
1451 | 960.0px
1452 | 960.0px
1453 | 961.0px
1454 | 962.0px
1455 | 962.0px
1456 | 963.0px
1457 | 964.0px
1458 | 964.0px
1459 | 965.0px
1460 | 966.0px
1461 | 966.0px
1462 | 967.0px
1463 | 968.0px
1464 | 968.0px
1465 | 969.0px
1466 | 970.0px
1467 | 970.0px
1468 | 971.0px
1469 | 972.0px
1470 | 972.0px
1471 | 973.0px
1472 | 974.0px
1473 | 974.0px
1474 | 975.0px
1475 | 976.0px
1476 | 976.0px
1477 | 977.0px
1478 | 978.0px
1479 | 978.0px
1480 | 979.0px
1481 | 980.0px
1482 | 980.0px
1483 | 981.0px
1484 | 982.0px
1485 | 982.0px
1486 | 983.0px
1487 | 984.0px
1488 | 984.0px
1489 | 985.0px
1490 | 986.0px
1491 | 986.0px
1492 | 987.0px
1493 | 988.0px
1494 | 988.0px
1495 | 989.0px
1496 | 990.0px
1497 | 990.0px
1498 | 991.0px
1499 | 992.0px
1500 | 992.0px
1501 | 993.0px
1502 | 994.0px
1503 | 994.0px
1504 | 995.0px
1505 | 996.0px
1506 | 996.0px
1507 | 997.0px
1508 | 998.0px
1509 | 998.0px
1510 | 999.0px
1511 | 1000.0px
1512 | 1000.0px
1513 | 1001.0px
1514 | 1002.0px
1515 | 1002.0px
1516 | 1003.0px
1517 | 1004.0px
1518 | 1004.0px
1519 | 1005.0px
1520 | 1006.0px
1521 | 1006.0px
1522 | 1007.0px
1523 | 1008.0px
1524 | 1008.0px
1525 | 1009.0px
1526 | 1010.0px
1527 | 1010.0px
1528 | 1011.0px
1529 | 1012.0px
1530 | 1012.0px
1531 | 1013.0px
1532 | 1014.0px
1533 | 1014.0px
1534 | 1015.0px
1535 | 1016.0px
1536 | 1016.0px
1537 | 1017.0px
1538 | 1018.0px
1539 | 1018.0px
1540 | 1019.0px
1541 | 1020.0px
1542 | 1020.0px
1543 | 1021.0px
1544 | 1022.0px
1545 | 1022.0px
1546 | 1023.0px
1547 | 1024.0px
1548 | 1024.0px
1549 | 1025.0px
1550 | 1026.0px
1551 | 1026.0px
1552 | 1027.0px
1553 | 1028.0px
1554 | 1028.0px
1555 | 1029.0px
1556 | 1030.0px
1557 | 1030.0px
1558 | 1031.0px
1559 | 1032.0px
1560 | 1032.0px
1561 | 1033.0px
1562 | 1034.0px
1563 | 1034.0px
1564 | 1035.0px
1565 | 1036.0px
1566 | 1036.0px
1567 | 1037.0px
1568 | 1038.0px
1569 | 1038.0px
1570 | 1039.0px
1571 | 1040.0px
1572 | 1040.0px
1573 | 1041.0px
1574 | 1042.0px
1575 | 1042.0px
1576 | 1043.0px
1577 | 1044.0px
1578 | 1044.0px
1579 | 1045.0px
1580 | 1046.0px
1581 | 1046.0px
1582 | 1047.0px
1583 | 1048.0px
1584 | 1048.0px
1585 | 1049.0px
1586 | 1050.0px
1587 | 1050.0px
1588 | 1051.0px
1589 | 1052.0px
1590 | 1052.0px
1591 | 1053.0px
1592 | 1054.0px
1593 | 1054.0px
1594 | 1055.0px
1595 | 1056.0px
1596 | 1056.0px
1597 | 1057.0px
1598 | 1058.0px
1599 | 1058.0px
1600 | 1059.0px
1601 | 1060.0px
1602 | 1060.0px
1603 | 1061.0px
1604 | 1062.0px
1605 | 1062.0px
1606 | 1063.0px
1607 | 1064.0px
1608 | 1064.0px
1609 | 1065.0px
1610 | 1066.0px
1611 | 1066.0px
1612 | 1067.0px
1613 | 1068.0px
1614 | 1068.0px
1615 | 1069.0px
1616 | 1070.0px
1617 | 1070.0px
1618 | 1071.0px
1619 | 1072.0px
1620 | 1072.0px
1621 | 1073.0px
1622 | 1074.0px
1623 | 1074.0px
1624 | 1075.0px
1625 | 1076.0px
1626 | 1076.0px
1627 | 1077.0px
1628 | 1078.0px
1629 | 1078.0px
1630 | 1079.0px
1631 | 1080.0px
1632 | 1080.0px
1633 | 1081.0px
1634 | 1082.0px
1635 | 1082.0px
1636 | 1083.0px
1637 | 1084.0px
1638 | 1084.0px
1639 | 1085.0px
1640 | 1086.0px
1641 | 1086.0px
1642 | 1087.0px
1643 | 1088.0px
1644 | 1088.0px
1645 | 1089.0px
1646 | 1090.0px
1647 | 1090.0px
1648 | 1091.0px
1649 | 1092.0px
1650 | 1092.0px
1651 | 1093.0px
1652 | 1094.0px
1653 | 1094.0px
1654 | 1095.0px
1655 | 1096.0px
1656 | 1096.0px
1657 | 1097.0px
1658 | 1098.0px
1659 | 1098.0px
1660 | 1099.0px
1661 | 1100.0px
1662 | 1100.0px
1663 | 1101.0px
1664 | 1102.0px
1665 | 1102.0px
1666 | 1103.0px
1667 | 1104.0px
1668 | 1104.0px
1669 | 1105.0px
1670 | 1106.0px
1671 | 1106.0px
1672 | 1107.0px
1673 | 1108.0px
1674 | 1108.0px
1675 | 1109.0px
1676 | 1110.0px
1677 | 1110.0px
1678 | 1111.0px
1679 | 1112.0px
1680 | 1112.0px
1681 | 1113.0px
1682 | 1114.0px
1683 | 1114.0px
1684 | 1115.0px
1685 | 1116.0px
1686 | 1116.0px
1687 | 1117.0px
1688 | 1118.0px
1689 | 1118.0px
1690 | 1119.0px
1691 | 1120.0px
1692 | 1120.0px
1693 | 1121.0px
1694 | 1122.0px
1695 | 1122.0px
1696 | 1123.0px
1697 | 1124.0px
1698 | 1124.0px
1699 | 1125.0px
1700 | 1126.0px
1701 | 1126.0px
1702 | 1127.0px
1703 | 1128.0px
1704 | 1128.0px
1705 | 1129.0px
1706 | 1130.0px
1707 | 1130.0px
1708 | 1131.0px
1709 | 1132.0px
1710 | 1132.0px
1711 | 1133.0px
1712 | 1134.0px
1713 | 1134.0px
1714 | 1135.0px
1715 | 1136.0px
1716 | 1136.0px
1717 | 1137.0px
1718 | 1138.0px
1719 | 1138.0px
1720 | 1139.0px
1721 | 1140.0px
1722 | 1140.0px
1723 | 1141.0px
1724 | 1142.0px
1725 | 1142.0px
1726 | 1143.0px
1727 | 1144.0px
1728 | 1144.0px
1729 | 1145.0px
1730 | 1146.0px
1731 | 1146.0px
1732 | 1147.0px
1733 | 1148.0px
1734 | 1148.0px
1735 | 1149.0px
1736 | 1150.0px
1737 | 1150.0px
1738 | 1151.0px
1739 | 1152.0px
1740 | 1152.0px
1741 | 1153.0px
1742 | 1154.0px
1743 | 1154.0px
1744 | 1155.0px
1745 | 1156.0px
1746 | 1156.0px
1747 | 1157.0px
1748 | 1158.0px
1749 | 1158.0px
1750 | 1159.0px
1751 | 1160.0px
1752 | 1160.0px
1753 | 1161.0px
1754 | 1162.0px
1755 | 1162.0px
1756 | 1163.0px
1757 | 1164.0px
1758 | 1164.0px
1759 | 1165.0px
1760 | 1166.0px
1761 | 1166.0px
1762 | 1167.0px
1763 | 1168.0px
1764 | 1168.0px
1765 | 1169.0px
1766 | 1170.0px
1767 | 1170.0px
1768 | 1171.0px
1769 | 1172.0px
1770 | 1172.0px
1771 | 1173.0px
1772 | 1174.0px
1773 | 1174.0px
1774 | 1175.0px
1775 | 1176.0px
1776 | 1176.0px
1777 | 1177.0px
1778 | 1178.0px
1779 | 1178.0px
1780 | 1179.0px
1781 | 1180.0px
1782 | 1180.0px
1783 | 1181.0px
1784 | 1182.0px
1785 | 1182.0px
1786 | 1183.0px
1787 | 1184.0px
1788 | 1184.0px
1789 | 1185.0px
1790 | 1186.0px
1791 | 1186.0px
1792 | 1187.0px
1793 | 1188.0px
1794 | 1188.0px
1795 | 1189.0px
1796 | 1190.0px
1797 | 1190.0px
1798 | 1191.0px
1799 | 1192.0px
1800 | 1192.0px
1801 | 1193.0px
1802 | 1194.0px
1803 | 1194.0px
1804 | 1195.0px
1805 | 1196.0px
1806 | 1196.0px
1807 | 1197.0px
1808 | 1198.0px
1809 | 1198.0px
1810 | 1199.0px
1811 | 1200.0px
1812 | 1200.0px
1813 | 1201.0px
1814 | 1202.0px
1815 | 1202.0px
1816 | 1203.0px
1817 | 1204.0px
1818 | 1204.0px
1819 | 1205.0px
1820 | 1206.0px
1821 | 1206.0px
1822 | 1207.0px
1823 | 1208.0px
1824 | 1208.0px
1825 | 1209.0px
1826 | 1210.0px
1827 | 1210.0px
1828 | 1211.0px
1829 | 1212.0px
1830 | 1212.0px
1831 | 1213.0px
1832 | 1214.0px
1833 | 1214.0px
1834 | 1215.0px
1835 | 1216.0px
1836 | 1216.0px
1837 | 1217.0px
1838 | 1218.0px
1839 | 1218.0px
1840 | 1219.0px
1841 | 1220.0px
1842 | 1220.0px
1843 | 1221.0px
1844 | 1222.0px
1845 | 1222.0px
1846 | 1223.0px
1847 | 1224.0px
1848 | 1224.0px
1849 | 1225.0px
1850 | 1226.0px
1851 | 1226.0px
1852 | 1227.0px
1853 | 1228.0px
1854 | 1228.0px
1855 | 1229.0px
1856 | 1230.0px
1857 | 1230.0px
1858 | 1231.0px
1859 | 1232.0px
1860 | 1232.0px
1861 | 1233.0px
1862 | 1234.0px
1863 | 1234.0px
1864 | 1235.0px
1865 | 1236.0px
1866 | 1236.0px
1867 | 1237.0px
1868 | 1238.0px
1869 | 1238.0px
1870 | 1239.0px
1871 | 1240.0px
1872 | 1240.0px
1873 | 1241.0px
1874 | 1242.0px
1875 | 1242.0px
1876 | 1243.0px
1877 | 1244.0px
1878 | 1244.0px
1879 | 1245.0px
1880 | 1246.0px
1881 | 1246.0px
1882 | 1247.0px
1883 | 1248.0px
1884 | 1248.0px
1885 | 1249.0px
1886 | 1250.0px
1887 | 1250.0px
1888 | 1251.0px
1889 | 1252.0px
1890 | 1252.0px
1891 | 1253.0px
1892 | 1254.0px
1893 | 1254.0px
1894 | 1255.0px
1895 | 1256.0px
1896 | 1256.0px
1897 | 1257.0px
1898 | 1258.0px
1899 | 1258.0px
1900 | 1259.0px
1901 | 1260.0px
1902 | 1260.0px
1903 | 1261.0px
1904 | 1262.0px
1905 | 1262.0px
1906 | 1263.0px
1907 | 1264.0px
1908 | 1264.0px
1909 | 1265.0px
1910 | 1266.0px
1911 | 1266.0px
1912 | 1267.0px
1913 | 1268.0px
1914 | 1268.0px
1915 | 1269.0px
1916 | 1270.0px
1917 | 1270.0px
1918 | 1271.0px
1919 | 1272.0px
1920 | 1272.0px
1921 | 1273.0px
1922 | 1274.0px
1923 | 1274.0px
1924 | 1275.0px
1925 | 1276.0px
1926 | 1276.0px
1927 | 1277.0px
1928 | 1278.0px
1929 | 1278.0px
1930 | 1279.0px
1931 | 1280.0px
1932 |
1933 |
--------------------------------------------------------------------------------
/app/src/main/res/values-1280x672/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | values-nodpi-1280x672
4 | 0
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/values-1280x719/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | values-nodpi-1280x719
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/values-1280x720/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | values-nodpi-1280x720
4 | 0
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/values-1280x736/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | values-nodpi-1280x736
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/values-1280x800/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | values-nodpi-1280x800
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/values-1366x768/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | values-nodpi-1366x768
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/values-1794x1080/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | values-nodpi-1794x1080
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/values-1820x1030/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | values-nodpi-1820x1030
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/values-1832x1028/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | values-nodpi-1832x1028
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/values-1840x1060/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | values-nodpi-1840x1060
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/values-1916x1076/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | values-nodpi-1916x1076
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/values-1916x1080/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | values-nodpi-1916x1080
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/values-1920x1008/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | values-nodpi-1920x1080
4 | 1
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/values-1920x1080/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | values-nodpi-1920x1080
4 | 1
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/values-1920x1128/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | values-nodpi-1920x1128
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/values-2048x1460/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | values-nodpi-2048x1460
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/values-2560x1440/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | values-nodpi-2560x1440
4 | 1
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/values-2560x1600/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | values-nodpi-2560x1600
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/values-3840x2160/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | values-nodpi-3840x2160
4 | 3
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/values-791x480/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | values-nodpi-791x480
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/values-800x432/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | values-nodpi-800x432
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/values-800x444/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | values-nodpi-800x444
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/values-800x480/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | values-nodpi-800x480
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/values-854x480/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | values-nodpi-854x480
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/values-960x540/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | values-nodpi-960x540
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/values-960x640/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | values-nodpi-960x640
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/ids.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | BuildLayoutDemo
3 | 动态布局demo
4 | change
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/test/java/com/fb/jjyyzjy/buildlayoutdemo/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.fb.jjyyzjy.buildlayoutdemo;
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 | }
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | repositories {
5 | jcenter()
6 | }
7 | dependencies {
8 | classpath 'com.android.tools.build:gradle:2.3.3'
9 |
10 | // NOTE: Do not place your application dependencies here; they belong
11 | // in the individual module build.gradle files
12 | }
13 | }
14 |
15 | allprojects {
16 | repositories {
17 | jcenter()
18 | }
19 | }
20 |
21 | task clean(type: Delete) {
22 | delete rootProject.buildDir
23 | }
24 |
--------------------------------------------------------------------------------
/build_layout_use_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JJYYZJY/AndroidTvLayout/d33c76b6cc38c65bcc44607514a5321d449b6944/build_layout_use_1.png
--------------------------------------------------------------------------------
/build_layout_use_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JJYYZJY/AndroidTvLayout/d33c76b6cc38c65bcc44607514a5321d449b6944/build_layout_use_2.png
--------------------------------------------------------------------------------
/build_use.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JJYYZJY/AndroidTvLayout/d33c76b6cc38c65bcc44607514a5321d449b6944/build_use.gif
--------------------------------------------------------------------------------
/build_use.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JJYYZJY/AndroidTvLayout/d33c76b6cc38c65bcc44607514a5321d449b6944/build_use.mp4
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JJYYZJY/AndroidTvLayout/d33c76b6cc38c65bcc44607514a5321d449b6944/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Tue Apr 24 16:27:18 CST 2018
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 |
--------------------------------------------------------------------------------
/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'
2 |
--------------------------------------------------------------------------------