├── .gitignore
├── .idea
├── codeStyles
│ └── Project.xml
├── gradle.xml
├── misc.xml
├── runConfigurations.xml
└── vcs.xml
├── README.md
├── app
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── zhl
│ │ └── secondaryscreen
│ │ └── ExampleInstrumentedTest.java
│ ├── main
│ ├── AndroidManifest.xml
│ ├── assets
│ │ └── biking_is_cool.json
│ ├── java
│ │ └── com
│ │ │ └── zhl
│ │ │ └── secondaryscreen
│ │ │ ├── activity
│ │ │ ├── MainActivity.java
│ │ │ └── SecondFloorActivity.java
│ │ │ ├── adapter
│ │ │ └── MyPaperAdapter.java
│ │ │ ├── fragment
│ │ │ ├── MainFragment.java
│ │ │ ├── OtherFragment.java
│ │ │ ├── ProgressbarFragment.java
│ │ │ ├── RecyclerViewRefreshFragment.java
│ │ │ ├── ScrollViewRefreshFragment.java
│ │ │ └── TagImageFragment.java
│ │ │ └── view
│ │ │ ├── CustomRefreshHeader.java
│ │ │ ├── ImageProgressBar.java
│ │ │ ├── OnSecondFloorScrollistener.java
│ │ │ ├── OnStateListener.java
│ │ │ ├── SecondFloorView.java
│ │ │ ├── SecondaryScreenView.java
│ │ │ └── TagImageView.java
│ └── res
│ │ ├── drawable-v24
│ │ └── ic_launcher_foreground.xml
│ │ ├── drawable
│ │ ├── drawable_refresh_tv.xml
│ │ └── ic_launcher_background.xml
│ │ ├── layout
│ │ ├── activity_custom_progress_bar.xml
│ │ ├── activity_custom_refresh_header.xml
│ │ ├── activity_custom_view_test.xml
│ │ ├── activity_main.xml
│ │ ├── activity_pull_secondview.xml
│ │ ├── custom_refresh_header.xml
│ │ ├── fg_second_floor.xml
│ │ └── item_cardview.xml
│ │ ├── mipmap-anydpi-v26
│ │ ├── ic_launcher.xml
│ │ └── ic_launcher_round.xml
│ │ ├── mipmap-hdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-mdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xxhdpi
│ │ ├── arrow_down.png
│ │ ├── bg2.jpg
│ │ ├── ic_launcher.png
│ │ ├── ic_launcher_round.png
│ │ ├── img_1.jpg
│ │ ├── img_3.jpg
│ │ ├── progressbar_bg.jpg
│ │ ├── second_floor_main.png
│ │ ├── secondary_screen.jpg
│ │ ├── top_right_search_black.png
│ │ ├── v1.jpg
│ │ ├── v2.jpg
│ │ └── v3.jpg
│ │ ├── mipmap-xxxhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ └── values
│ │ ├── attrs.xml
│ │ ├── colors.xml
│ │ ├── strings.xml
│ │ └── styles.xml
│ └── test
│ └── java
│ └── com
│ └── zhl
│ └── secondaryscreen
│ └── ExampleUnitTest.java
├── build.gradle
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── image
├── show.gif
├── show_video.jpg
└── show_video.mp4
├── settings.gradle
├── show.gif
├── show2.jpg
├── show3.gif
└── video_show_secondfloorview.gif
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/caches
5 | /.idea/libraries
6 | /.idea/modules.xml
7 | /.idea/workspace.xml
8 | /.idea/navEditor.xml
9 | /.idea/assetWizardSettings.xml
10 | .DS_Store
11 | /build
12 | /captures
13 | .externalNativeBuild
14 |
--------------------------------------------------------------------------------
/.idea/codeStyles/Project.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 |
--------------------------------------------------------------------------------
/.idea/gradle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
14 |
15 |
--------------------------------------------------------------------------------
/.idea/misc.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 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # SecondaryScreen
2 |
3 | - 因为只有一个自定义ViewGroup就不上传maven了,直接拷入工程去用就O了。用法参考demo
4 |
5 | - 下拉刷新 继续刷新进入二楼
6 |
7 |
8 |
9 |
10 |
11 | - 还有一个imageViewProgressbar
12 |
13 |
14 |
15 | - TagImageView
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 28
5 | defaultConfig {
6 | applicationId "com.zhl.secondaryscreen"
7 | minSdkVersion 19
8 | targetSdkVersion 28
9 | versionCode 1
10 | versionName "1.0"
11 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
12 | }
13 | buildTypes {
14 | release {
15 | minifyEnabled false
16 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
17 | }
18 | }
19 | dataBinding {
20 | enabled = true
21 | }
22 | }
23 |
24 | dependencies {
25 | implementation fileTree(include: ['*.jar'], dir: 'libs')
26 | implementation 'com.android.support:appcompat-v7:28.0.0'
27 | implementation 'com.android.support.constraint:constraint-layout:1.1.3'
28 | testImplementation 'junit:junit:4.12'
29 | implementation 'com.scwang.smartrefresh:SmartRefreshLayout:1.0.5.1'
30 | implementation 'com.github.hackware1993:magicindicator:1.5.0'
31 | implementation 'com.airbnb.android:lottie:2.7.0'
32 | implementation 'com.airbnb.android:lottie:2.7.0'
33 | implementation 'com.android.support:recyclerview-v7:28.0.0'
34 | implementation 'com.android.support:cardview-v7:28.0.0'
35 | implementation('com.zhy:base-rvadapter:3.0.3') {
36 | exclude(group: 'com.android.support', module: 'recyclerview-v7')
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/app/src/androidTest/java/com/zhl/secondaryscreen/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package com.zhl.secondaryscreen;
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 | * Instrumented test, which will execute on an Android device.
14 | *
15 | * @see Testing documentation
16 | */
17 | @RunWith(AndroidJUnit4.class)
18 | public class ExampleInstrumentedTest {
19 | @Test
20 | public void useAppContext() {
21 | // Context of the app under test.
22 | Context appContext = InstrumentationRegistry.getTargetContext();
23 |
24 | assertEquals("com.zhl.secondaryscreen", appContext.getPackageName());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/app/src/main/java/com/zhl/secondaryscreen/activity/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.zhl.secondaryscreen.activity;
2 |
3 | import android.content.Context;
4 | import android.graphics.Color;
5 | import android.os.Bundle;
6 | import android.support.v4.view.ViewPager;
7 | import android.support.v7.app.AppCompatActivity;
8 | import android.view.View;
9 | import android.widget.ImageView;
10 |
11 | import com.zhl.secondaryscreen.R;
12 | import com.zhl.secondaryscreen.adapter.MyPaperAdapter;
13 | import com.zhl.secondaryscreen.view.SecondaryScreenView;
14 |
15 | import net.lucode.hackware.magicindicator.MagicIndicator;
16 | import net.lucode.hackware.magicindicator.ViewPagerHelper;
17 | import net.lucode.hackware.magicindicator.buildins.commonnavigator.CommonNavigator;
18 | import net.lucode.hackware.magicindicator.buildins.commonnavigator.abs.CommonNavigatorAdapter;
19 | import net.lucode.hackware.magicindicator.buildins.commonnavigator.abs.IPagerIndicator;
20 | import net.lucode.hackware.magicindicator.buildins.commonnavigator.abs.IPagerTitleView;
21 | import net.lucode.hackware.magicindicator.buildins.commonnavigator.indicators.LinePagerIndicator;
22 | import net.lucode.hackware.magicindicator.buildins.commonnavigator.titles.ColorTransitionPagerTitleView;
23 |
24 | import java.util.ArrayList;
25 |
26 | public class MainActivity extends AppCompatActivity {
27 | private MagicIndicator magicIndicator;
28 | private ViewPager mViewPager;
29 | private ArrayList mTitleDataList = new ArrayList<>();
30 | SecondaryScreenView secondaryScreenView;
31 | @Override
32 | protected void onCreate(Bundle savedInstanceState) {
33 | super.onCreate(savedInstanceState);
34 | setContentView(R.layout.activity_main);
35 | mTitleDataList.add("主页");
36 | mTitleDataList.add("发现");
37 | mTitleDataList.add("推荐");
38 | mTitleDataList.add("日报");
39 | mTitleDataList.add("ImageProgressBar");
40 | mTitleDataList.add("ImageTag");
41 | magicIndicator = (MagicIndicator) findViewById(R.id.magic_indicator);
42 | secondaryScreenView = findViewById(R.id.secondaryScreenView);
43 | mViewPager = findViewById(R.id.viewpager);
44 | mViewPager.setAdapter(new MyPaperAdapter(getSupportFragmentManager(),mTitleDataList));
45 | CommonNavigator commonNavigator = new CommonNavigator(this);
46 | commonNavigator.setAdapter(new CommonNavigatorAdapter() {
47 |
48 | @Override
49 | public int getCount() {
50 | return mTitleDataList == null ? 0 : mTitleDataList.size();
51 | }
52 |
53 | @Override
54 | public IPagerTitleView getTitleView(Context context, final int index) {
55 | ColorTransitionPagerTitleView colorTransitionPagerTitleView = new ColorTransitionPagerTitleView(context);
56 | colorTransitionPagerTitleView.setNormalColor(Color.GRAY);
57 | colorTransitionPagerTitleView.setSelectedColor(Color.BLACK);
58 | colorTransitionPagerTitleView.setText(mTitleDataList.get(index));
59 | colorTransitionPagerTitleView.setOnClickListener(new View.OnClickListener() {
60 | @Override
61 | public void onClick(View view) {
62 | mViewPager.setCurrentItem(index);
63 | }
64 | });
65 | return colorTransitionPagerTitleView;
66 | }
67 |
68 | @Override
69 | public IPagerIndicator getIndicator(Context context) {
70 | LinePagerIndicator indicator = new LinePagerIndicator(context);
71 | indicator.setMode(LinePagerIndicator.MODE_WRAP_CONTENT);
72 | return indicator;
73 | }
74 | });
75 | magicIndicator.setNavigator(commonNavigator);
76 | ViewPagerHelper.bind(magicIndicator, mViewPager);
77 | ImageView btnSearch = findViewById(R.id.top_search);
78 | btnSearch.setOnClickListener(new View.OnClickListener() {
79 | @Override
80 | public void onClick(View v) {
81 | secondaryScreenView.translateToSecondaryView();
82 | }
83 | });
84 | }
85 |
86 | @Override
87 | public void onBackPressed() {
88 | if(!secondaryScreenView.isStillMainView()){
89 | secondaryScreenView.translateToMainView();
90 | }else{
91 | super.onBackPressed();
92 | }
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/app/src/main/java/com/zhl/secondaryscreen/activity/SecondFloorActivity.java:
--------------------------------------------------------------------------------
1 | package com.zhl.secondaryscreen.activity;
2 |
3 | import android.content.Context;
4 | import android.graphics.Color;
5 | import android.os.Bundle;
6 | import android.support.v4.app.Fragment;
7 | import android.support.v4.app.FragmentStatePagerAdapter;
8 | import android.support.v4.view.ViewPager;
9 | import android.support.v7.app.AppCompatActivity;
10 | import android.view.View;
11 |
12 | import com.zhl.secondaryscreen.R;
13 | import com.zhl.secondaryscreen.fragment.RecyclerViewRefreshFragment;
14 | import com.zhl.secondaryscreen.fragment.ScrollViewRefreshFragment;
15 |
16 | import net.lucode.hackware.magicindicator.MagicIndicator;
17 | import net.lucode.hackware.magicindicator.ViewPagerHelper;
18 | import net.lucode.hackware.magicindicator.buildins.commonnavigator.CommonNavigator;
19 | import net.lucode.hackware.magicindicator.buildins.commonnavigator.abs.CommonNavigatorAdapter;
20 | import net.lucode.hackware.magicindicator.buildins.commonnavigator.abs.IPagerIndicator;
21 | import net.lucode.hackware.magicindicator.buildins.commonnavigator.abs.IPagerTitleView;
22 | import net.lucode.hackware.magicindicator.buildins.commonnavigator.indicators.LinePagerIndicator;
23 | import net.lucode.hackware.magicindicator.buildins.commonnavigator.titles.ColorTransitionPagerTitleView;
24 |
25 | import java.util.ArrayList;
26 |
27 | public class SecondFloorActivity extends AppCompatActivity {
28 | private MagicIndicator magicIndicator;
29 | private ViewPager mViewPager;
30 | private ArrayList mTitleDataList = new ArrayList<>();
31 | @Override
32 | protected void onCreate(Bundle savedInstanceState) {
33 | super.onCreate(savedInstanceState);
34 | setContentView(R.layout.activity_pull_secondview);
35 | mTitleDataList.add("RecyclerView");
36 | mTitleDataList.add("ScrollView");
37 | magicIndicator = (MagicIndicator) findViewById(R.id.magic_indicator);
38 | mViewPager = findViewById(R.id.viewpager);
39 | mViewPager.setAdapter(new FragmentStatePagerAdapter(getSupportFragmentManager()) {
40 | @Override
41 | public Fragment getItem(int i) {
42 | Fragment fg = null;
43 | switch (i){
44 | case 0:
45 | fg = new RecyclerViewRefreshFragment();
46 | break;
47 | case 1:
48 | fg = new ScrollViewRefreshFragment();
49 | break;
50 | }
51 | return fg;
52 | }
53 |
54 | @Override
55 | public int getCount() {
56 | return mTitleDataList.size();
57 | }
58 | });
59 | CommonNavigator commonNavigator = new CommonNavigator(this);
60 | commonNavigator.setAdapter(new CommonNavigatorAdapter() {
61 |
62 | @Override
63 | public int getCount() {
64 | return mTitleDataList == null ? 0 : mTitleDataList.size();
65 | }
66 |
67 | @Override
68 | public IPagerTitleView getTitleView(Context context, final int index) {
69 | ColorTransitionPagerTitleView colorTransitionPagerTitleView = new ColorTransitionPagerTitleView(context);
70 | colorTransitionPagerTitleView.setNormalColor(Color.GRAY);
71 | colorTransitionPagerTitleView.setSelectedColor(Color.BLACK);
72 | colorTransitionPagerTitleView.setText(mTitleDataList.get(index));
73 | colorTransitionPagerTitleView.setOnClickListener(new View.OnClickListener() {
74 | @Override
75 | public void onClick(View view) {
76 | mViewPager.setCurrentItem(index);
77 | }
78 | });
79 | return colorTransitionPagerTitleView;
80 | }
81 |
82 | @Override
83 | public IPagerIndicator getIndicator(Context context) {
84 | LinePagerIndicator indicator = new LinePagerIndicator(context);
85 | indicator.setMode(LinePagerIndicator.MODE_WRAP_CONTENT);
86 | return indicator;
87 | }
88 | });
89 | magicIndicator.setNavigator(commonNavigator);
90 | ViewPagerHelper.bind(magicIndicator, mViewPager);
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/app/src/main/java/com/zhl/secondaryscreen/adapter/MyPaperAdapter.java:
--------------------------------------------------------------------------------
1 | package com.zhl.secondaryscreen.adapter;
2 |
3 | import android.support.v4.app.Fragment;
4 | import android.support.v4.app.FragmentManager;
5 | import android.support.v4.app.FragmentPagerAdapter;
6 |
7 | import com.zhl.secondaryscreen.R;
8 | import com.zhl.secondaryscreen.fragment.MainFragment;
9 | import com.zhl.secondaryscreen.fragment.OtherFragment;
10 | import com.zhl.secondaryscreen.fragment.ProgressbarFragment;
11 | import com.zhl.secondaryscreen.fragment.TagImageFragment;
12 |
13 | import java.util.ArrayList;
14 |
15 | /**
16 | * 描述:
17 | * Created by zhaohl on 2019-1-21.
18 | */
19 | public class MyPaperAdapter extends FragmentPagerAdapter {
20 | private ArrayList mDatas ;
21 |
22 | public MyPaperAdapter(FragmentManager fm) {
23 | this(fm,null);
24 | }
25 |
26 | public MyPaperAdapter(FragmentManager fm, ArrayList mDatas){
27 | super(fm);
28 | this.mDatas = mDatas;
29 | }
30 |
31 | @Override
32 | public Fragment getItem(int position) {
33 | Fragment fragment = null;
34 | switch (position){
35 | case 0:
36 | fragment = new MainFragment();
37 | break;
38 | case 1:
39 | fragment = OtherFragment.newInstance(mDatas.get(position), R.mipmap.v1);
40 | break;
41 | case 2:
42 | fragment = OtherFragment.newInstance(mDatas.get(position),R.mipmap.v2);
43 | break;
44 | case 3:
45 | fragment = OtherFragment.newInstance(mDatas.get(position),R.mipmap.v3);
46 | break;
47 | case 4:
48 | fragment = ProgressbarFragment.newInstance();
49 | break;
50 | case 5:
51 | fragment = TagImageFragment.newInstance();
52 | break;
53 | }
54 | return fragment;
55 | }
56 |
57 | @Override
58 | public int getCount() {
59 | return mDatas==null?0:mDatas.size();
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/app/src/main/java/com/zhl/secondaryscreen/fragment/MainFragment.java:
--------------------------------------------------------------------------------
1 | package com.zhl.secondaryscreen.fragment;
2 |
3 | import android.content.Intent;
4 | import android.os.Bundle;
5 | import android.support.annotation.NonNull;
6 | import android.support.annotation.Nullable;
7 | import android.support.v4.app.Fragment;
8 | import android.support.v7.widget.LinearLayoutManager;
9 | import android.support.v7.widget.RecyclerView;
10 | import android.view.LayoutInflater;
11 | import android.view.View;
12 | import android.view.ViewGroup;
13 |
14 | import com.scwang.smartrefresh.layout.SmartRefreshLayout;
15 | import com.scwang.smartrefresh.layout.api.RefreshLayout;
16 | import com.scwang.smartrefresh.layout.listener.OnRefreshListener;
17 | import com.zhl.secondaryscreen.R;
18 | import com.zhl.secondaryscreen.activity.SecondFloorActivity;
19 | import com.zhy.adapter.recyclerview.CommonAdapter;
20 | import com.zhy.adapter.recyclerview.MultiItemTypeAdapter;
21 | import com.zhy.adapter.recyclerview.base.ViewHolder;
22 |
23 | import java.util.ArrayList;
24 | import java.util.List;
25 |
26 | /**
27 | * 描述:
28 | * Created by zhaohl on 2019-1-21.
29 | */
30 | public class MainFragment extends Fragment {
31 | private RecyclerView mRecyclerView;
32 | private List datas = new ArrayList<>();
33 | private SmartRefreshLayout refreshView ;
34 | private CommonAdapter mAdapter;
35 | @Override
36 | public void onCreate(@Nullable Bundle savedInstanceState) {
37 | super.onCreate(savedInstanceState);
38 | }
39 |
40 | @Nullable
41 | @Override
42 | public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
43 | View view = inflater.inflate(R.layout.activity_custom_refresh_header,null);
44 | refreshView = view.findViewById(R.id.refresh_layout);
45 | mRecyclerView = view.findViewById(R.id.recyclerview);
46 | mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
47 | for (int i = 0; i < 30; i++) {
48 | datas.add("custom_refresh_header" + i);
49 | }
50 | mRecyclerView.setAdapter(mAdapter = new CommonAdapter(getContext(), R.layout.item_cardview, datas) {
51 | @Override
52 | protected void convert(ViewHolder holder, String s, int position) {
53 | holder.setText(R.id.item_tx, s);
54 | }
55 |
56 | });
57 | refreshView.setOnRefreshListener(new OnRefreshListener() {
58 | @Override
59 | public void onRefresh(RefreshLayout refreshLayout) {
60 | refreshView.postDelayed(new Runnable() {
61 | @Override
62 | public void run() {
63 | refreshView.finishRefresh();
64 | }
65 | },2000);
66 | }
67 | });
68 | mAdapter.setOnItemClickListener(new MultiItemTypeAdapter.OnItemClickListener() {
69 | @Override
70 | public void onItemClick(View view, RecyclerView.ViewHolder holder, int position) {
71 | Intent intent = new Intent(getContext(), SecondFloorActivity.class);
72 | startActivity(intent);
73 | }
74 |
75 | @Override
76 | public boolean onItemLongClick(View view, RecyclerView.ViewHolder holder, int position) {
77 | return false;
78 | }
79 | });
80 | return view;
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/app/src/main/java/com/zhl/secondaryscreen/fragment/OtherFragment.java:
--------------------------------------------------------------------------------
1 | package com.zhl.secondaryscreen.fragment;
2 |
3 | import android.os.Bundle;
4 | import android.support.annotation.NonNull;
5 | import android.support.annotation.Nullable;
6 | import android.support.v4.app.Fragment;
7 | import android.view.LayoutInflater;
8 | import android.view.View;
9 | import android.view.ViewGroup;
10 | import android.widget.ImageView;
11 |
12 | /**
13 | * 描述:
14 | * Created by zhaohl on 2019-1-21.
15 | */
16 | public class OtherFragment extends Fragment {
17 | private String title;
18 | private int imgResID;
19 | public static OtherFragment newInstance(String title, int ImgResid){
20 | OtherFragment fg = new OtherFragment();
21 | fg.title = title;
22 | fg.imgResID = ImgResid;
23 | return fg;
24 | }
25 | @Override
26 | public void onCreate(@Nullable Bundle savedInstanceState) {
27 | super.onCreate(savedInstanceState);
28 | }
29 |
30 | @Nullable
31 | @Override
32 | public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
33 | // TextView textView = new TextView(getContext());
34 | // textView.setText(title);
35 | // textView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
36 | // textView.setGravity(Gravity.CENTER);
37 | ImageView imageView = new ImageView(getContext());
38 | imageView.setBackgroundResource(imgResID);
39 | imageView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
40 | return imageView;
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/app/src/main/java/com/zhl/secondaryscreen/fragment/ProgressbarFragment.java:
--------------------------------------------------------------------------------
1 | package com.zhl.secondaryscreen.fragment;
2 |
3 | import android.os.Bundle;
4 | import android.os.Handler;
5 | import android.os.Message;
6 | import android.support.annotation.NonNull;
7 | import android.support.annotation.Nullable;
8 | import android.support.v4.app.Fragment;
9 | import android.view.LayoutInflater;
10 | import android.view.View;
11 | import android.view.ViewGroup;
12 |
13 | import com.zhl.secondaryscreen.R;
14 | import com.zhl.secondaryscreen.view.ImageProgressBar;
15 |
16 | /**
17 | * 描述:
18 | * Created by zhaohl on 2019-6-26.
19 | */
20 | public class ProgressbarFragment extends Fragment {
21 | private static final int UPDATE_PROGRESS=0;
22 | boolean stop;
23 | ImageProgressBar progressBar,progressBar2;
24 | Handler handler = new Handler(){
25 | public void handleMessage(Message msg) {
26 | switch (msg.what) {
27 | case UPDATE_PROGRESS:
28 | progressBar.setProgress(msg.arg1);
29 | progressBar2.setProgress(msg.arg1);
30 | break;
31 | default:
32 | break;
33 | }
34 | };
35 | };
36 |
37 | public static ProgressbarFragment newInstance(){
38 | ProgressbarFragment fg = new ProgressbarFragment();
39 | return fg;
40 | }
41 | @Override
42 | public void onCreate(@Nullable Bundle savedInstanceState) {
43 | super.onCreate(savedInstanceState);
44 | }
45 |
46 | @Nullable
47 | @Override
48 | public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
49 | View view = inflater.inflate(R.layout.activity_custom_progress_bar,null);
50 | progressBar = view.findViewById(R.id.progressBar);
51 | progressBar2 = view.findViewById(R.id.progressBar2);
52 | return view;
53 | }
54 |
55 | @Override
56 | public void onActivityCreated(@Nullable Bundle savedInstanceState) {
57 | super.onActivityCreated(savedInstanceState);
58 | new Thread(new Runnable() {
59 | @Override
60 | public void run() {
61 | int progress = 0;
62 | while(!stop){
63 | if(progress>=100){
64 | break;
65 | }
66 | Message msg = handler.obtainMessage();
67 | try {
68 | Thread.sleep(50);
69 | } catch (InterruptedException e) {
70 | e.printStackTrace();
71 | }
72 | progress+=1;
73 | msg.what= UPDATE_PROGRESS;
74 | msg.arg1 = progress;
75 | msg.sendToTarget();
76 | }
77 | progress = 0;
78 | }
79 | }).start();
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/app/src/main/java/com/zhl/secondaryscreen/fragment/RecyclerViewRefreshFragment.java:
--------------------------------------------------------------------------------
1 | package com.zhl.secondaryscreen.fragment;
2 |
3 | import android.os.Bundle;
4 | import android.support.annotation.NonNull;
5 | import android.support.annotation.Nullable;
6 | import android.support.v4.app.Fragment;
7 | import android.support.v7.widget.LinearLayoutManager;
8 | import android.support.v7.widget.RecyclerView;
9 | import android.util.Log;
10 | import android.view.LayoutInflater;
11 | import android.view.View;
12 | import android.view.ViewGroup;
13 | import android.widget.TextView;
14 |
15 | import com.scwang.smartrefresh.layout.SmartRefreshLayout;
16 | import com.scwang.smartrefresh.layout.api.RefreshLayout;
17 | import com.scwang.smartrefresh.layout.listener.OnRefreshListener;
18 | import com.zhl.secondaryscreen.R;
19 | import com.zhl.secondaryscreen.view.OnSecondFloorScrollistener;
20 | import com.zhl.secondaryscreen.view.OnStateListener;
21 | import com.zhl.secondaryscreen.view.SecondFloorView;
22 | import com.zhy.adapter.recyclerview.CommonAdapter;
23 | import com.zhy.adapter.recyclerview.base.ViewHolder;
24 |
25 | import java.util.ArrayList;
26 | import java.util.List;
27 |
28 | /**
29 | * 描述:
30 | * Created by zhaohl on 2020-4-3.
31 | */
32 | public class RecyclerViewRefreshFragment extends Fragment {
33 | private RecyclerView mRecyclerView;
34 | private List datas = new ArrayList<>();
35 | private SmartRefreshLayout refreshView ;
36 | private CommonAdapter mAdapter;
37 | SecondFloorView secondFloorView;
38 | TextView tvHeader;
39 | @Override
40 | public void onCreate(@Nullable Bundle savedInstanceState) {
41 | super.onCreate(savedInstanceState);
42 | }
43 |
44 | @Nullable
45 | @Override
46 | public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
47 | View view = inflater.inflate(R.layout.activity_custom_refresh_header,null);
48 | refreshView = view.findViewById(R.id.refresh_layout);
49 | refreshView.setEnableRefresh(false);
50 | mRecyclerView = view.findViewById(R.id.recyclerview);
51 | mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
52 | for (int i = 0; i < 30; i++) {
53 | datas.add("recyclerview in secondfloorview" + i);
54 | }
55 | mRecyclerView.setAdapter(mAdapter = new CommonAdapter(getContext(), R.layout.item_cardview, datas) {
56 |
57 | @Override
58 | protected void convert(ViewHolder holder, String s, int position) {
59 | holder.setText(R.id.item_tx, s);
60 | }
61 | });
62 | refreshView.setOnRefreshListener(new OnRefreshListener() {
63 | @Override
64 | public void onRefresh(RefreshLayout refreshLayout) {
65 | refreshView.postDelayed(new Runnable() {
66 | @Override
67 | public void run() {
68 | refreshView.finishRefresh();
69 | }
70 | },2000);
71 | }
72 | });
73 | secondFloorView = view.findViewById(R.id.second_floor_view);
74 | tvHeader = view.findViewById(R.id.tv_pull_header);
75 | secondFloorView.setOnSecondFloorScrollistener(new OnSecondFloorScrollistener() {
76 | @Override
77 | public void onScroll(int scrollY) {
78 | // Log.d("mytag","scrolly==="+scrollY);
79 | }
80 |
81 | @Override
82 | public void onSwipeToSecondFloor() {
83 |
84 | }
85 |
86 | @Override
87 | public void onSwipeToMain() {
88 |
89 | }
90 |
91 | @Override
92 | public void onRefresh() {
93 | Log.d("mytag","开始刷新");
94 | secondFloorView.postDelayed(new Runnable() {
95 | @Override
96 | public void run() {
97 | secondFloorView.finishRefresh();
98 | }
99 | },2000);
100 | }
101 | });
102 | secondFloorView.setOnStateListener(new OnStateListener() {
103 | @Override
104 | public void onStateChanged(String state) {
105 | // Log.d("mytag","onStateChanged=="+state);
106 | }
107 |
108 | @Override
109 | public void onStateRefreshing() {
110 | Log.d("mytag","onStateRefreshing");
111 | tvHeader.setText("正在刷新...");
112 | }
113 |
114 | @Override
115 | public void onStatePullToRefresh() {
116 | Log.d("mytag","onStatePullToRefresh");
117 | tvHeader.setText("下拉赢好礼 ↓");
118 | }
119 |
120 | @Override
121 | public void onStateReleaseToRefresh() {
122 | Log.d("mytag","onStateReleaseToRefresh");
123 | tvHeader.setText("松开开始刷新 ↑");
124 | }
125 |
126 | @Override
127 | public void onStateReleaseToSecond() {
128 | Log.d("mytag","onStateReleaseToSecond");
129 | tvHeader.setText("松开进入二楼");
130 | }
131 |
132 | @Override
133 | public void onStateReleaseToMain() {
134 | Log.d("mytag","onStateReleaseToMain");
135 | tvHeader.setText("松开回到主页");
136 | }
137 |
138 | @Override
139 | public void onStateMain() {
140 | Log.d("mytag","onStateMain");
141 | tvHeader.setText("下拉赢好礼 ↓");
142 | tvHeader.setVisibility(View.VISIBLE);
143 | }
144 |
145 | @Override
146 | public void onStateSecond() {
147 | Log.d("mytag","onStateSecond");
148 | tvHeader.setVisibility(View.GONE);
149 | }
150 | });
151 | return view;
152 | }
153 | }
154 |
--------------------------------------------------------------------------------
/app/src/main/java/com/zhl/secondaryscreen/fragment/ScrollViewRefreshFragment.java:
--------------------------------------------------------------------------------
1 | package com.zhl.secondaryscreen.fragment;
2 |
3 | import android.os.Bundle;
4 | import android.support.annotation.NonNull;
5 | import android.support.annotation.Nullable;
6 | import android.support.v4.app.Fragment;
7 | import android.util.Log;
8 | import android.view.LayoutInflater;
9 | import android.view.View;
10 | import android.view.ViewGroup;
11 | import android.widget.TextView;
12 |
13 | import com.zhl.secondaryscreen.R;
14 | import com.zhl.secondaryscreen.view.OnSecondFloorScrollistener;
15 | import com.zhl.secondaryscreen.view.OnStateListener;
16 | import com.zhl.secondaryscreen.view.SecondFloorView;
17 |
18 | /**
19 | * 描述:
20 | * Created by zhaohl on 2020-4-3.
21 | */
22 | public class ScrollViewRefreshFragment extends Fragment {
23 | SecondFloorView secondFloorView;
24 | TextView refreshView;
25 |
26 | @Override
27 | public void onCreate(@Nullable Bundle savedInstanceState) {
28 | super.onCreate(savedInstanceState);
29 | }
30 |
31 | @Nullable
32 | @Override
33 | public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
34 | View view = inflater.inflate(R.layout.fg_second_floor,null);
35 | initView(view);
36 | return view;
37 | }
38 |
39 | private void initView(View view) {
40 | secondFloorView = view.findViewById(R.id.second_floor_view);
41 | refreshView = view.findViewById(R.id.tv_pull_header);
42 | secondFloorView.setOnSecondFloorScrollistener(new OnSecondFloorScrollistener() {
43 | @Override
44 | public void onScroll(int scrollY) {
45 | // Log.d("mytag","scrolly==="+scrollY);
46 | }
47 |
48 | @Override
49 | public void onSwipeToSecondFloor() {
50 |
51 | }
52 |
53 | @Override
54 | public void onSwipeToMain() {
55 |
56 | }
57 |
58 | @Override
59 | public void onRefresh() {
60 | Log.d("mytag","开始刷新");
61 | secondFloorView.postDelayed(new Runnable() {
62 | @Override
63 | public void run() {
64 | secondFloorView.finishRefresh();
65 | }
66 | },2000);
67 | }
68 | });
69 | secondFloorView.setOnStateListener(new OnStateListener() {
70 | @Override
71 | public void onStateChanged(String state) {
72 | // Log.d("mytag","onStateChanged=="+state);
73 | }
74 |
75 | @Override
76 | public void onStateRefreshing() {
77 | Log.d("mytag","onStateRefreshing");
78 | refreshView.setText("正在刷新...");
79 | }
80 |
81 | @Override
82 | public void onStatePullToRefresh() {
83 | Log.d("mytag","onStatePullToRefresh");
84 | refreshView.setText("下拉赢好礼 ↓");
85 | }
86 |
87 | @Override
88 | public void onStateReleaseToRefresh() {
89 | Log.d("mytag","onStateReleaseToRefresh");
90 | refreshView.setText("松开开始刷新 ↑");
91 | }
92 |
93 | @Override
94 | public void onStateReleaseToSecond() {
95 | Log.d("mytag","onStateReleaseToSecond");
96 | refreshView.setText("松开进入二楼");
97 | }
98 |
99 | @Override
100 | public void onStateReleaseToMain() {
101 | Log.d("mytag","onStateReleaseToMain");
102 | refreshView.setText("松开回到主页");
103 | }
104 |
105 | @Override
106 | public void onStateMain() {
107 | Log.d("mytag","onStateMain");
108 | refreshView.setText("下拉赢好礼 ↓");
109 | refreshView.setVisibility(View.VISIBLE);
110 | }
111 |
112 | @Override
113 | public void onStateSecond() {
114 | Log.d("mytag","onStateSecond");
115 | refreshView.setVisibility(View.GONE);
116 | }
117 | });
118 | }
119 | }
120 |
--------------------------------------------------------------------------------
/app/src/main/java/com/zhl/secondaryscreen/fragment/TagImageFragment.java:
--------------------------------------------------------------------------------
1 | package com.zhl.secondaryscreen.fragment;
2 |
3 | import android.os.Bundle;
4 | import android.support.annotation.NonNull;
5 | import android.support.annotation.Nullable;
6 | import android.support.v4.app.Fragment;
7 | import android.view.LayoutInflater;
8 | import android.view.View;
9 | import android.view.ViewGroup;
10 |
11 | import com.zhl.secondaryscreen.R;
12 | import com.zhl.secondaryscreen.view.TagImageView;
13 |
14 | /**
15 | * 描述:
16 | * Created by zhaohl on 2019-6-26.
17 | */
18 | public class TagImageFragment extends Fragment {
19 | TagImageView imageView;
20 |
21 | public static TagImageFragment newInstance(){
22 | return new TagImageFragment();
23 | }
24 |
25 | @Override
26 | public void onCreate(@Nullable Bundle savedInstanceState) {
27 | super.onCreate(savedInstanceState);
28 | }
29 |
30 | @Nullable
31 | @Override
32 | public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
33 | View view = inflater.inflate(R.layout.activity_custom_view_test, null);
34 | imageView = view.findViewById(R.id.tag_img);
35 | // imageView.setTagSize(50);
36 | // imageView.setTagLocation(TagImageView.Location.ON_TOP_lEFT);
37 | // imageView.showTag(false);
38 | // imageView.setTagBackgroud(Color.parseColor("#FF3396FF"));
39 | // imageView.setTagTextColor(Color.parseColor("#FFFF336D"));
40 | return view;
41 | }
42 |
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/app/src/main/java/com/zhl/secondaryscreen/view/CustomRefreshHeader.java:
--------------------------------------------------------------------------------
1 | package com.zhl.secondaryscreen.view;
2 |
3 | import android.content.Context;
4 | import android.support.annotation.NonNull;
5 | import android.support.annotation.Nullable;
6 | import android.util.AttributeSet;
7 | import android.util.Log;
8 | import android.view.LayoutInflater;
9 | import android.view.View;
10 | import android.widget.ImageView;
11 | import android.widget.LinearLayout;
12 | import android.widget.TextView;
13 |
14 | import com.airbnb.lottie.LottieAnimationView;
15 | import com.scwang.smartrefresh.layout.api.RefreshHeader;
16 | import com.scwang.smartrefresh.layout.api.RefreshKernel;
17 | import com.scwang.smartrefresh.layout.api.RefreshLayout;
18 | import com.scwang.smartrefresh.layout.constant.RefreshState;
19 | import com.scwang.smartrefresh.layout.constant.SpinnerStyle;
20 | import com.zhl.secondaryscreen.R;
21 |
22 | /**
23 | * 描述:
24 | * Created by zhaohl on 2019-1-16.
25 | */
26 | public class CustomRefreshHeader extends LinearLayout implements RefreshHeader {
27 | private LottieAnimationView lottieAnimationView;
28 | private ImageView arrow;
29 | private TextView tipView;
30 |
31 | public CustomRefreshHeader(Context context) {
32 | this(context, null);
33 | }
34 |
35 | public CustomRefreshHeader(Context context, @Nullable AttributeSet attrs) {
36 | this(context, attrs, -1);
37 | }
38 |
39 | public CustomRefreshHeader(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
40 | super(context, attrs, defStyleAttr);
41 | View view = LayoutInflater.from(context).inflate(R.layout.custom_refresh_header, null);
42 | lottieAnimationView = view.findViewById(R.id.lottie_anim);
43 | arrow = view.findViewById(R.id.arrow);
44 | tipView = view.findViewById(R.id.tip_view);
45 | addView(view);
46 | }
47 |
48 | @NonNull
49 | @Override
50 | public View getView() {
51 | return this;
52 | }
53 |
54 | @NonNull
55 | @Override
56 | public SpinnerStyle getSpinnerStyle() {
57 | return SpinnerStyle.Translate;
58 | }
59 |
60 | @Override
61 | public void setPrimaryColors(int... colors) {
62 |
63 | }
64 |
65 | @Override
66 | public void onInitialized(@NonNull RefreshKernel kernel, int height, int extendHeight) {
67 |
68 | }
69 |
70 | @Override
71 | public void onPulling(float percent, int offset, int height, int extendHeight) {
72 | Log.d("mytag","----onPulling...");
73 | }
74 |
75 | @Override
76 | public void onReleasing(float percent, int offset, int height, int extendHeight) {
77 | Log.d("mytag","----onReleasing...");
78 | }
79 |
80 | @Override
81 | public void onReleased(RefreshLayout refreshLayout, int height, int extendHeight) {
82 | Log.d("mytag","----onReleased...");
83 | }
84 |
85 | @Override
86 | public void onStartAnimator(@NonNull RefreshLayout refreshLayout, int height, int extendHeight) {
87 | lottieAnimationView.playAnimation();
88 | Log.d("mytag","----onStartAnimator...");
89 | }
90 |
91 | @Override
92 | public int onFinish(@NonNull RefreshLayout refreshLayout, boolean success) {
93 | lottieAnimationView.pauseAnimation();
94 | if (success) {
95 | tipView.setText("刷新成功");
96 | } else {
97 | tipView.setText("刷新失败");
98 | }
99 | return 400;
100 | }
101 |
102 | @Override
103 | public void onHorizontalDrag(float percentX, int offsetX, int offsetMax) {
104 |
105 | }
106 |
107 | @Override
108 | public boolean isSupportHorizontalDrag() {
109 | return false;
110 | }
111 |
112 | @Override
113 | public void onStateChanged(RefreshLayout refreshLayout, RefreshState oldState, RefreshState newState) {
114 | switch (newState) {
115 | case None:
116 | case PullDownToRefresh:
117 | tipView.setText("下拉开始刷新");
118 | arrow.setVisibility(VISIBLE);
119 | arrow.animate().rotation(0);
120 | break;
121 | case ReleaseToRefresh:
122 | tipView.setText("释放刷新");
123 | arrow.animate().rotation(180);
124 | break;
125 | case Refreshing:
126 | tipView.setText("正在刷新...");
127 | arrow.setVisibility(GONE);
128 | Log.d("mytag","----正在刷新...");
129 | break;
130 |
131 | }
132 | }
133 | }
134 |
--------------------------------------------------------------------------------
/app/src/main/java/com/zhl/secondaryscreen/view/ImageProgressBar.java:
--------------------------------------------------------------------------------
1 | package com.zhl.secondaryscreen.view;
2 |
3 | import android.content.Context;
4 | import android.content.res.TypedArray;
5 | import android.graphics.Bitmap;
6 | import android.graphics.BitmapFactory;
7 | import android.graphics.Canvas;
8 | import android.graphics.Paint;
9 | import android.graphics.PorterDuff;
10 | import android.graphics.PorterDuffXfermode;
11 | import android.graphics.Rect;
12 | import android.graphics.RectF;
13 | import android.support.annotation.Nullable;
14 | import android.util.AttributeSet;
15 | import android.view.View;
16 |
17 | import com.zhl.secondaryscreen.R;
18 |
19 |
20 | /**
21 | * 描述:
22 | * Created by zhaohl on 2018-11-27.
23 | */
24 | public class ImageProgressBar extends View {
25 | private Paint paint;
26 | private Bitmap bgBitmap;
27 | private int bgResID = -1;
28 | private int roundConer;
29 | private int max = 100;
30 | private float progress = 0;
31 | private int coverColor = 0x77E6E9E7;
32 | private int mode = 0;
33 | private PorterDuff.Mode styleMode = PorterDuff.Mode.DST_IN;
34 | public ImageProgressBar(Context context) {
35 | this(context,null);
36 | }
37 |
38 | public ImageProgressBar(Context context, @Nullable AttributeSet attrs) {
39 | this(context, attrs,-1);
40 | }
41 |
42 | public ImageProgressBar(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
43 | super(context, attrs, defStyleAttr);
44 | paint = new Paint(Paint.ANTI_ALIAS_FLAG);
45 | TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.ImageProgressBar);
46 | bgResID = array.getResourceId(R.styleable.ImageProgressBar_imagebg,-1);
47 | roundConer = (int) array.getDimension(R.styleable.ImageProgressBar_roundConer,5);
48 | coverColor = array.getColor(R.styleable.ImageProgressBar_coverColor,coverColor);
49 | mode = array.getInt(R.styleable.ImageProgressBar_styleMode,coverColor);
50 | switch (mode){
51 | case 0:
52 | styleMode = PorterDuff.Mode.DST_IN;
53 | break;
54 | case 1:
55 | styleMode = PorterDuff.Mode.SRC_IN;
56 | break;
57 | }
58 | array.recycle();
59 | if(bgResID!=-1){
60 | generateImageBg(bgResID);
61 | }else{
62 | throw new RuntimeException("need a image bg!");
63 | }
64 | setLayerType(View.LAYER_TYPE_SOFTWARE,paint);// 关掉硬件加速 否则 paint.setXfermode 无效
65 | }
66 |
67 | public void setImageBg(Bitmap bgBitmap){
68 | this.bgBitmap = bgBitmap;
69 | invalidate();
70 | }
71 | public void setImageBg(int resID){
72 | this.bgResID = resID;
73 | generateImageBg(bgResID);
74 | invalidate();
75 | }
76 |
77 | private void generateImageBg(int res) {
78 | BitmapFactory.Options options = new BitmapFactory.Options();
79 | bgBitmap = BitmapFactory.decodeResource(getResources(),res,options);
80 | }
81 |
82 | @Override
83 | protected void onDraw(Canvas canvas) {
84 | drawImageBg(canvas);
85 | drawProgress(canvas);
86 | }
87 |
88 | private void drawProgress(Canvas canvas) {
89 | paint.setColor(coverColor);
90 | paint.setXfermode(new PorterDuffXfermode(styleMode));
91 | canvas.drawRect(new Rect((int) ((progress/max)*getWidth()),0,getWidth(),getHeight()),paint);
92 | paint.setXfermode(null);
93 | }
94 |
95 | private void drawImageBg(Canvas canvas) {
96 | paint = new Paint(Paint.ANTI_ALIAS_FLAG);// 这里不重新初始化一个画笔刷新后绘出的底图会出问题
97 | bgBitmap = Bitmap.createScaledBitmap(bgBitmap,getWidth(),getHeight(),true);
98 | canvas.drawRoundRect(new RectF(0,0,getWidth(),getHeight()),roundConer,roundConer,paint);
99 | paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
100 | canvas.drawBitmap(bgBitmap,0,0,paint);
101 | }
102 |
103 |
104 | public int getMax() {
105 | return max;
106 | }
107 |
108 | public void setMax(int max) {
109 | this.max = max;
110 | }
111 |
112 | public float getProgress() {
113 | return progress;
114 | }
115 |
116 | public void setProgress(int progress) {
117 | if (progress > max) {
118 | progress = max;
119 | } else {
120 | this.progress = progress;
121 | postInvalidate();
122 | }
123 | }
124 | }
125 |
--------------------------------------------------------------------------------
/app/src/main/java/com/zhl/secondaryscreen/view/OnSecondFloorScrollistener.java:
--------------------------------------------------------------------------------
1 | package com.zhl.secondaryscreen.view;
2 |
3 | /**
4 | * 描述:
5 | * Created by zhaohl on 2020-3-31.
6 | */
7 | public interface OnSecondFloorScrollistener {
8 | /**
9 | * 滚动回调
10 | * @param scrollY
11 | */
12 | public void onScroll(int scrollY);
13 |
14 | /**
15 | * 切换到第二页
16 | */
17 | public void onSwipeToSecondFloor();
18 |
19 | /**
20 | * 切换到主页
21 | */
22 | public void onSwipeToMain();
23 |
24 | /**
25 | * 刷新
26 | */
27 | public void onRefresh();
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/app/src/main/java/com/zhl/secondaryscreen/view/OnStateListener.java:
--------------------------------------------------------------------------------
1 | package com.zhl.secondaryscreen.view;
2 |
3 | /**
4 | * 描述:
5 | * Created by zhaohl on 2020-4-1.
6 | */
7 | public interface OnStateListener {
8 | public void onStateChanged(String state);
9 | public void onStateRefreshing();
10 | public void onStatePullToRefresh();
11 | public void onStateReleaseToRefresh();
12 | public void onStateReleaseToSecond();
13 | public void onStateReleaseToMain();
14 | public void onStateMain();
15 | public void onStateSecond();
16 | }
17 |
--------------------------------------------------------------------------------
/app/src/main/java/com/zhl/secondaryscreen/view/SecondFloorView.java:
--------------------------------------------------------------------------------
1 | package com.zhl.secondaryscreen.view;
2 |
3 | import android.animation.Animator;
4 | import android.animation.AnimatorSet;
5 | import android.animation.ObjectAnimator;
6 | import android.animation.ValueAnimator;
7 | import android.content.Context;
8 | import android.content.res.TypedArray;
9 | import android.graphics.Rect;
10 | import android.support.v4.view.ViewPager;
11 | import android.support.v7.widget.GridLayoutManager;
12 | import android.support.v7.widget.LinearLayoutManager;
13 | import android.support.v7.widget.RecyclerView;
14 | import android.support.v7.widget.StaggeredGridLayoutManager;
15 | import android.util.AttributeSet;
16 | import android.util.Log;
17 | import android.view.MotionEvent;
18 | import android.view.View;
19 | import android.view.ViewConfiguration;
20 | import android.view.ViewGroup;
21 | import android.view.animation.LinearInterpolator;
22 | import android.widget.AbsListView;
23 | import android.widget.ListView;
24 |
25 | import com.zhl.secondaryscreen.R;
26 |
27 | import java.util.ArrayList;
28 |
29 | /**
30 | * 描述:下拉的展示第二屏的viewgroup(类似mgtv下拉展示广告)
31 | * Created by zhaohl on 2020-03-31.
32 | */
33 | public class SecondFloorView extends ViewGroup {
34 | private View secondaryView;
35 | private View mainView;
36 | private int downX, downY, endY, lastTouchX, lastTouchY;
37 | private boolean isBeingDraged;
38 | private float resistance = 0.60f;// 下拉阻力
39 | private boolean isScrollerDown = true;
40 | private int pullRefreshDistance = 260;
41 | private int topOffset = 0;// mainview头部偏移
42 | private ArrayList viewPagers = new ArrayList<>();
43 | private ArrayList recyclerViews = new ArrayList<>();
44 | private ArrayList absListViews = new ArrayList<>();
45 | private float touchSlop;
46 | private OnSecondFloorScrollistener scrollistener;
47 | private OnStateListener stateListener;
48 | private String curState = State.STATE_MAIN;
49 | private MotionEvent touchEvent;
50 |
51 | public SecondFloorView(Context context) {
52 | this(context, null);
53 | }
54 |
55 | public SecondFloorView(Context context, AttributeSet attrs) {
56 | this(context, attrs, -1);
57 | }
58 |
59 | public SecondFloorView(Context context, AttributeSet attrs, int defStyleAttr) {
60 | super(context, attrs, defStyleAttr);
61 | TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.SecondFloorView);
62 | resistance = array.getFloat(R.styleable.SecondFloorView_resistance, resistance);
63 | pullRefreshDistance = array.getInteger(R.styleable.SecondFloorView_pullRefreshDistance, pullRefreshDistance);
64 | topOffset = array.getDimensionPixelSize(R.styleable.SecondFloorView_topOffset,topOffset);
65 | touchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
66 | if (stateListener != null) {
67 | stateListener.onStateMain();
68 | }
69 | }
70 |
71 | @Override
72 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
73 | int count = getChildCount();
74 | if (count > 2) {
75 | throw new RuntimeException("only can host 2 direct child view");
76 | }
77 | int widthMode = MeasureSpec.getMode(widthMeasureSpec);
78 | int heightMode = MeasureSpec.getMode(heightMeasureSpec);
79 | int widthSize = MeasureSpec.getSize(widthMeasureSpec);
80 | int heightSize = MeasureSpec.getSize(heightMeasureSpec);
81 | int usedWidth = 0;
82 | int usedHeight = 0;
83 | for (int i = 0; i < getChildCount(); i++) {
84 | View childView = getChildAt(i);
85 | if (childView.getVisibility() != View.GONE) {
86 | SecondFloorView.LayoutParams params = (SecondFloorView.LayoutParams) childView.getLayoutParams();
87 | int childWidthSpec = MeasureSpec.AT_MOST;
88 | int childHeightSpec = MeasureSpec.AT_MOST;
89 | switch (params.width) {
90 | case SecondFloorView.LayoutParams.MATCH_PARENT:
91 | if (widthMode == MeasureSpec.EXACTLY || widthMode == MeasureSpec.AT_MOST) {
92 | childWidthSpec = MeasureSpec.makeMeasureSpec(widthSize, MeasureSpec.EXACTLY);
93 | } else {
94 | childWidthSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
95 | }
96 | break;
97 | case SecondFloorView.LayoutParams.WRAP_CONTENT:
98 | if (widthMode == MeasureSpec.EXACTLY || widthMode == MeasureSpec.AT_MOST) {
99 | childWidthSpec = MeasureSpec.makeMeasureSpec(widthSize, MeasureSpec.AT_MOST);
100 | } else {
101 | childWidthSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
102 | }
103 | break;
104 | default:
105 | childWidthSpec = MeasureSpec.makeMeasureSpec(params.width, MeasureSpec.EXACTLY);
106 | break;
107 | }
108 | usedWidth += MeasureSpec.getSize(childWidthSpec) + params.leftMargin + params.rightMargin;
109 | switch (params.height) {
110 | case SecondFloorView.LayoutParams.MATCH_PARENT:
111 | if (heightMode == MeasureSpec.EXACTLY || heightMode == MeasureSpec.AT_MOST) {
112 | childHeightSpec = MeasureSpec.makeMeasureSpec(heightSize+topOffset, MeasureSpec.EXACTLY);
113 | } else {
114 | childHeightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
115 | }
116 | break;
117 | case SecondFloorView.LayoutParams.WRAP_CONTENT:
118 | if (heightMode == MeasureSpec.EXACTLY || heightMode == MeasureSpec.AT_MOST) {
119 | childHeightSpec = MeasureSpec.makeMeasureSpec(heightSize+topOffset, MeasureSpec.AT_MOST);
120 | } else {
121 | childHeightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
122 | }
123 | break;
124 | default:
125 | childHeightSpec = MeasureSpec.makeMeasureSpec(params.height+topOffset, MeasureSpec.EXACTLY);
126 | break;
127 | }
128 | usedHeight += MeasureSpec.getSize(childHeightSpec) + params.bottomMargin + params.topMargin;
129 | measureChild(childView, childWidthSpec, childHeightSpec);
130 | }
131 | }
132 | if (widthMode == MeasureSpec.UNSPECIFIED) {
133 | widthSize = usedWidth;
134 | }
135 | if (heightMode == MeasureSpec.UNSPECIFIED) {
136 | heightSize = usedHeight;
137 | }
138 | setMeasuredDimension(widthSize, heightSize);
139 | secondaryView = getChildAt(0);
140 | mainView = getChildAt(1);
141 | }
142 |
143 | @Override
144 | protected void onLayout(boolean changed, int l, int t, int r, int b) {
145 | getAllRecyclerView(recyclerViews, this);
146 | getAllAbsListView(absListViews, this);
147 | if (secondaryView != null) {
148 | secondaryView.layout(0, -secondaryView.getMeasuredHeight()+topOffset, secondaryView.getMeasuredWidth(), topOffset);
149 | }
150 | if (mainView != null) {
151 | mainView.layout(0, topOffset, mainView.getMeasuredWidth(), secondaryView.getMeasuredHeight());
152 | }
153 | }
154 |
155 | private void getAllViewPager(ArrayList viewPagers, ViewGroup parent) {
156 | int childCount = parent.getChildCount();
157 | for (int i = 0; i < childCount; i++) {
158 | View child = parent.getChildAt(i);
159 | if (child instanceof ViewPager) {
160 | viewPagers.add((ViewPager) child);
161 | } else if (child instanceof ViewGroup) {
162 | getAllViewPager(viewPagers, (ViewGroup) child);
163 | }
164 | }
165 | }
166 |
167 | private void getAllRecyclerView(ArrayList recyclerViews, ViewGroup parent) {
168 | int childCount = parent.getChildCount();
169 | for (int i = 0; i < childCount; i++) {
170 | View child = parent.getChildAt(i);
171 | if (child instanceof RecyclerView) {
172 | recyclerViews.add((RecyclerView) child);
173 | } else if (child instanceof ViewGroup) {
174 | getAllRecyclerView(recyclerViews, (ViewGroup) child);
175 | }
176 | }
177 | }
178 |
179 | private void getAllAbsListView(ArrayList listViews, ViewGroup parent) {
180 | int childCount = parent.getChildCount();
181 | for (int i = 0; i < childCount; i++) {
182 | View child = parent.getChildAt(i);
183 | if (child instanceof ListView) {
184 | listViews.add((ListView) child);
185 | } else if (child instanceof ViewGroup) {
186 | getAllAbsListView(listViews, (ViewGroup) child);
187 | }
188 | }
189 | }
190 |
191 | @Override
192 | public boolean onInterceptTouchEvent(MotionEvent ev) {
193 | // // 处理viewpager的事件冲突
194 | // ViewPager pager = getTouchedViewPager(ev);
195 | // if(pager!=null&&pager.getCurrentItem()!=0){
196 | // return super.onInterceptTouchEvent(ev);
197 | // }
198 | // 处理recyclerview和listview的事件冲突
199 | RecyclerView recyclerView = getTouchedRecyclerView(ev);
200 | boolean recyclerViewFirstItemVisible = false;
201 | boolean absListViewFirstItemVisible = false;
202 | if (recyclerView != null) {
203 | RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
204 | if (layoutManager != null && layoutManager instanceof LinearLayoutManager) {
205 | if (((LinearLayoutManager) layoutManager).findFirstCompletelyVisibleItemPosition() != 0) {
206 | return super.onInterceptTouchEvent(ev);
207 | } else {
208 | recyclerViewFirstItemVisible = true;
209 | }
210 | } else if (layoutManager != null && layoutManager instanceof GridLayoutManager) {
211 | if (((GridLayoutManager) layoutManager).findFirstCompletelyVisibleItemPosition() != 0) {
212 | return super.onInterceptTouchEvent(ev);
213 | } else {
214 | recyclerViewFirstItemVisible = true;
215 | }
216 | } else if (layoutManager != null && layoutManager instanceof StaggeredGridLayoutManager) {
217 | int[] mFirstVisible = null;
218 | mFirstVisible = ((StaggeredGridLayoutManager) layoutManager).findFirstCompletelyVisibleItemPositions(mFirstVisible);
219 | if (mFirstVisible != null && mFirstVisible[0] != 0) {
220 | return super.onInterceptTouchEvent(ev);
221 | } else {
222 | recyclerViewFirstItemVisible = true;
223 | }
224 | }
225 | }
226 | AbsListView absListView = getTouchedAbsListView(ev);
227 | if (absListView != null) {
228 | if (absListView.getFirstVisiblePosition() != 0) {
229 | return super.onInterceptTouchEvent(ev);
230 | } else {
231 | absListViewFirstItemVisible = true;
232 | }
233 | }
234 |
235 | switch (ev.getAction()) {
236 | case MotionEvent.ACTION_DOWN:
237 | downX = (int) ev.getRawX();
238 | downY = (int) ev.getRawY();
239 | break;
240 | case MotionEvent.ACTION_MOVE:
241 | float delX = ev.getRawX() - downX;
242 | float delY = ev.getRawY() - downY;
243 | if (Math.abs(delY) > touchSlop && Math.abs(delY) > Math.abs(delX) && (recyclerViewFirstItemVisible || absListViewFirstItemVisible) && delY > 0) {
244 | return true;
245 | }
246 | if (mainView.getScrollY() == 0 && delY > 0) {
247 | return true;
248 | }
249 | if (curState == State.STATE_REFRESHING) {
250 | return true;
251 | }
252 | // if(secondaryView.getX()==0f&& Math.abs(delX)>touchSlop&& Math.abs(delX)> Math.abs(delY)&&pager!=null&&pager.getCurrentItem()==pager.getChildCount()-1&&delX<0){
253 | // return true;
254 | // }
255 | break;
256 | case MotionEvent.ACTION_UP:
257 | break;
258 | }
259 |
260 | return super.onInterceptTouchEvent(ev);
261 | }
262 |
263 | private ViewPager getTouchedViewPager(MotionEvent ev) {
264 | if (viewPagers == null || viewPagers.size() == 0) {
265 | return null;
266 | }
267 | Rect mRect = new Rect();
268 | for (ViewPager viewPager : viewPagers) {
269 | viewPager.getHitRect(mRect);
270 | if (mRect.contains((int) ev.getX(), (int) ev.getY())) {
271 | return viewPager;
272 | }
273 | }
274 | return null;
275 | }
276 |
277 | private RecyclerView getTouchedRecyclerView(MotionEvent ev) {
278 | if (recyclerViews == null || recyclerViews.size() == 0) {
279 | return null;
280 | }
281 | Rect mRect = new Rect();
282 | for (RecyclerView recyclerView : recyclerViews) {
283 | recyclerView.getHitRect(mRect);
284 | if (mRect.contains((int) ev.getX(), (int) ev.getY())) {
285 | return recyclerView;
286 | }
287 | }
288 | return null;
289 | }
290 |
291 | private AbsListView getTouchedAbsListView(MotionEvent ev) {
292 | if (absListViews == null || absListViews.size() == 0) {
293 | return null;
294 | }
295 | Rect mRect = new Rect();
296 | for (AbsListView listView : absListViews) {
297 | listView.getHitRect(mRect);
298 | if (mRect.contains((int) ev.getX(), (int) ev.getY())) {
299 | return listView;
300 | }
301 | }
302 | return null;
303 | }
304 |
305 | @Override
306 | public boolean onTouchEvent(MotionEvent event) {
307 | touchEvent = event;
308 | switch (event.getAction()) {
309 | case MotionEvent.ACTION_DOWN:
310 | downX = (int) event.getRawX();
311 | downY = (int) event.getRawY();
312 | break;
313 | case MotionEvent.ACTION_MOVE:
314 | isBeingDraged = true;
315 | int moveX = (int) (event.getRawX() - downX);
316 | int moveY = (int) (event.getRawY() - downY);
317 | if (secondaryView.getY() < 0) {
318 | moveY *= resistance;
319 | }
320 | if (moveY > 0) {
321 | isScrollerDown = true;
322 | } else {
323 | isScrollerDown = false;
324 | }
325 | int translateY_second = endY + moveY;
326 | int translateY_main = endY + moveY;
327 | if (translateY_second >= secondaryView.getHeight()) {
328 | translateY_second = secondaryView.getHeight();
329 | translateY_main = mainView.getHeight();
330 | }
331 | if (translateY_second <= 0) {
332 | translateY_second = 0;
333 | translateY_main = 0;
334 | }
335 | secondaryView.setTranslationY(translateY_second);
336 | mainView.setTranslationY(translateY_main);
337 | if (isScrollerDown) {
338 | if (Math.abs(translateY_main) > 0 && Math.abs(translateY_main) <= pullRefreshDistance) {
339 | curState = State.STATE_PULL_TO_REFRESH;
340 | if (stateListener != null) {
341 | stateListener.onStatePullToRefresh();
342 | stateListener.onStateChanged(curState);
343 | }
344 | } else if (Math.abs(translateY_main) > pullRefreshDistance && Math.abs(translateY_main) < mainView.getHeight() / 3) {
345 | if(curState!=State.STATE_REFRESHING){
346 | curState = State.STATE_RELEASE_TO_REFRESH;
347 | if (stateListener != null) {
348 | stateListener.onStateReleaseToRefresh();
349 | stateListener.onStateChanged(curState);
350 | }
351 | }
352 | } else if (Math.abs(translateY_main) >= mainView.getHeight() / 3) {
353 | if(curState!=State.STATE_REFRESHING){
354 | curState = State.STATE_RELEASE_TO_SECOND;
355 | if (stateListener != null) {
356 | stateListener.onStateReleaseToSecond();
357 | stateListener.onStateChanged(curState);
358 | }
359 | }
360 | }
361 | } else {
362 | if (Math.abs(translateY_main) >= mainView.getHeight() / 3) {
363 | curState = State.STATE_RELEASE_TO_MAIN;
364 | if (stateListener != null) {
365 | stateListener.onStateReleaseToMain();
366 | stateListener.onStateChanged(curState);
367 | }
368 | } else {
369 | curState = State.STATE_SECOND;
370 | if (stateListener != null) {
371 | stateListener.onStateSecond();
372 | stateListener.onStateChanged(curState);
373 | }
374 | }
375 | }
376 | if (scrollistener != null) {
377 | scrollistener.onScroll(translateY_main);
378 | }
379 | lastTouchX = (int) event.getRawX();
380 | lastTouchY = (int) event.getRawY();
381 | break;
382 | case MotionEvent.ACTION_UP:
383 | isBeingDraged = false;
384 | endY = (int) mainView.getTranslationY();
385 | if (curState == State.STATE_RELEASE_TO_REFRESH) {
386 | if (scrollistener != null) {
387 | startReleaseAnim();
388 | } else {
389 | startTranslateAnim();
390 | }
391 | }else if(curState == State.STATE_REFRESHING){
392 | startReleaseAnim();
393 | }else {
394 | startTranslateAnim();
395 | }
396 |
397 | break;
398 | }
399 | return true;
400 | }
401 |
402 | public void translateToSecondaryView() {
403 | endY = mainView.getHeight();
404 | isScrollerDown = true;
405 | startTranslateAnim();
406 | }
407 |
408 | public void translateToMainView() {
409 | endY = mainView.getHeight() / 3;
410 | isScrollerDown = false;
411 | startTranslateAnim();
412 | }
413 |
414 | public void finishRefresh() {
415 | translateToMainView();
416 | }
417 |
418 | public boolean isStillMainView() {
419 | return endY == 0 && mainView.getTranslationY() == 0;
420 | }
421 |
422 | public String getCurState() {
423 | return curState;
424 | }
425 |
426 | public void setCurState(String curState) {
427 | this.curState = curState;
428 | }
429 |
430 | private void startReleaseAnim() {
431 | float secondTranslationY = pullRefreshDistance;
432 | float mainTranslationY = pullRefreshDistance;
433 | AnimatorSet animator = new AnimatorSet();
434 | ObjectAnimator animator_secondaryView = ObjectAnimator.ofFloat(secondaryView, "translationY", secondTranslationY);
435 | ObjectAnimator animator_mainView = ObjectAnimator.ofFloat(mainView, "translationY", mainTranslationY);
436 | animator_mainView.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
437 | @Override
438 | public void onAnimationUpdate(ValueAnimator animation) {
439 | float value = (float) animation.getAnimatedValue();
440 | if (scrollistener != null) {
441 | scrollistener.onScroll((int) value);
442 | }
443 | }
444 | });
445 | animator.setDuration(200);
446 | animator.setInterpolator(new LinearInterpolator());
447 | animator.addListener(new Animator.AnimatorListener() {
448 | @Override
449 | public void onAnimationStart(Animator animation) {
450 |
451 | }
452 |
453 | @Override
454 | public void onAnimationEnd(Animator animation) {
455 | curState = State.STATE_REFRESHING;
456 | endY = (int) mainView.getTranslationY();
457 | if (scrollistener != null) {
458 | scrollistener.onRefresh();
459 | }
460 | if (stateListener != null) {
461 | stateListener.onStateRefreshing();
462 | }
463 | Log.d("mytag", "----curState===" + curState);
464 | }
465 |
466 | @Override
467 | public void onAnimationCancel(Animator animation) {
468 |
469 | }
470 |
471 | @Override
472 | public void onAnimationRepeat(Animator animation) {
473 |
474 | }
475 | });
476 | animator.play(animator_secondaryView).with(animator_mainView);
477 | animator.start();
478 |
479 | }
480 |
481 | private void startTranslateAnim() {
482 | float secondTranslationY = 0;
483 | float mainTranslationY = 0;
484 | if (isScrollerDown) {//下滑
485 | if (endY > secondaryView.getHeight() / 3-100) {
486 | secondTranslationY = secondaryView.getHeight()-topOffset;
487 | mainTranslationY = mainView.getHeight();
488 | isScrollerDown = false;
489 | } else {
490 | secondTranslationY = 0;
491 | mainTranslationY = 0;
492 | isScrollerDown = true;
493 | }
494 | } else {
495 | if (endY < mainView.getHeight() * 2 / 3+100) {
496 | secondTranslationY = 0;
497 | mainTranslationY = 0;
498 | isScrollerDown = true;
499 | } else {
500 | secondTranslationY = secondaryView.getHeight()-topOffset;
501 | mainTranslationY = mainView.getHeight();
502 | isScrollerDown = false;
503 | }
504 | }
505 | AnimatorSet animator = new AnimatorSet();
506 | ObjectAnimator animator_secondaryView = ObjectAnimator.ofFloat(secondaryView, "translationY", secondTranslationY);
507 | ObjectAnimator animator_mainView = ObjectAnimator.ofFloat(mainView, "translationY", mainTranslationY);
508 | animator_mainView.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
509 | @Override
510 | public void onAnimationUpdate(ValueAnimator animation) {
511 | float value = (float) animation.getAnimatedValue();
512 | if (scrollistener != null) {
513 | scrollistener.onScroll((int) value);
514 | }
515 | }
516 | });
517 | animator.setDuration(200);
518 | animator.setInterpolator(new LinearInterpolator());
519 | animator.addListener(new Animator.AnimatorListener() {
520 | @Override
521 | public void onAnimationStart(Animator animation) {
522 |
523 | }
524 |
525 | @Override
526 | public void onAnimationEnd(Animator animation) {
527 | endY = (int) mainView.getTranslationY();
528 | Log.d("mytag", "----endy==" + endY);
529 | if (endY == 0) {
530 | curState = State.STATE_MAIN;
531 | if (stateListener != null) {
532 | stateListener.onStateMain();
533 | }
534 | } else if (endY >= mainView.getHeight()) {
535 | curState = State.STATE_SECOND;
536 | if (stateListener != null) {
537 | stateListener.onStateSecond();
538 | }
539 | }
540 | long time = System.currentTimeMillis();
541 | if (isBeingDraged) {
542 | isBeingDraged = false;
543 | SecondFloorView.super.dispatchTouchEvent(MotionEvent.obtain(time, time, MotionEvent.ACTION_DOWN, lastTouchX, lastTouchY, 0));
544 | SecondFloorView.super.dispatchTouchEvent(MotionEvent.obtain(time, time, MotionEvent.ACTION_MOVE, lastTouchX, lastTouchY, 0));
545 | }
546 | Log.d("mytag", "----curState===" + curState);
547 | }
548 |
549 | @Override
550 | public void onAnimationCancel(Animator animation) {
551 |
552 | }
553 |
554 | @Override
555 | public void onAnimationRepeat(Animator animation) {
556 |
557 | }
558 | });
559 | animator.play(animator_secondaryView).with(animator_mainView);
560 | animator.start();
561 |
562 | }
563 |
564 | public static class LayoutParams extends MarginLayoutParams {
565 |
566 | public LayoutParams(Context c, AttributeSet attrs) {
567 | super(c, attrs);
568 | }
569 |
570 | public LayoutParams(int width, int height) {
571 | super(width, height);
572 | }
573 |
574 | public LayoutParams(ViewGroup.LayoutParams source) {
575 | super(source);
576 | }
577 | }
578 |
579 | @Override
580 | protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
581 | return new SecondFloorView.LayoutParams(p);
582 | }
583 |
584 | @Override
585 | protected ViewGroup.LayoutParams generateDefaultLayoutParams() {
586 | return new SecondFloorView.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
587 | }
588 |
589 | @Override
590 | public ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs) {
591 | return new SecondFloorView.LayoutParams(getContext(), attrs);
592 | }
593 |
594 | @Override
595 | protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
596 | return p instanceof SecondFloorView.LayoutParams;
597 | }
598 |
599 | public float getResistance() {
600 | return resistance;
601 | }
602 |
603 | public void setResistance(float resistance) {
604 | this.resistance = resistance;
605 | }
606 |
607 | public OnSecondFloorScrollistener getSecondFloorScrollistener() {
608 | return scrollistener;
609 | }
610 |
611 | public void setOnSecondFloorScrollistener(OnSecondFloorScrollistener scrollistener) {
612 | this.scrollistener = scrollistener;
613 | }
614 |
615 | public OnStateListener getOnStateListener() {
616 | return stateListener;
617 | }
618 |
619 | public void setOnStateListener(OnStateListener stateListener) {
620 | this.stateListener = stateListener;
621 | }
622 |
623 | public static class State {
624 | public static final String STATE_IDAL = "STATE_IDAL";
625 | public static final String STATE_PULL_TO_REFRESH = "STATE_PULL_TO_REFRESH";
626 | public static final String STATE_RELEASE_TO_REFRESH = "STATE_RELEASE_TO_REFRESH";
627 | public static final String STATE_REFRESHING = "STATE_REFRESHING";
628 | public static final String STATE_RELEASE_TO_SECOND = "STATE_RELEASE_TO_SECOND";
629 | public static final String STATE_RELEASE_TO_MAIN = "STATE_RELEASE_TO_MAIN";
630 | public static final String STATE_MAIN = "STATE_MAIN";
631 | public static final String STATE_SECOND = "STATE_SECOND";
632 | }
633 | }
634 |
--------------------------------------------------------------------------------
/app/src/main/java/com/zhl/secondaryscreen/view/SecondaryScreenView.java:
--------------------------------------------------------------------------------
1 | package com.zhl.secondaryscreen.view;
2 |
3 | import android.animation.Animator;
4 | import android.animation.AnimatorSet;
5 | import android.animation.ObjectAnimator;
6 | import android.content.Context;
7 | import android.content.res.TypedArray;
8 | import android.graphics.Rect;
9 | import android.support.v4.view.ViewPager;
10 | import android.util.AttributeSet;
11 | import android.view.MotionEvent;
12 | import android.view.View;
13 | import android.view.ViewConfiguration;
14 | import android.view.ViewGroup;
15 | import android.view.animation.LinearInterpolator;
16 |
17 | import com.zhl.secondaryscreen.R;
18 |
19 | import java.util.ArrayList;
20 |
21 | /**
22 | * 描述:左滑负一屏的viewgroup
23 | * Created by zhaohl on 2019-1-18.
24 | */
25 | public class SecondaryScreenView extends ViewGroup {
26 | private View secondaryView;
27 | private View mainView;
28 | private int downX, downY, endX;
29 | private float rate = 0.60f;
30 | private boolean isScrollerRight = true;
31 | private ArrayList viewPagers = new ArrayList<>();
32 | private float touchSlop;
33 |
34 | public SecondaryScreenView(Context context) {
35 | this(context, null);
36 | }
37 |
38 | public SecondaryScreenView(Context context, AttributeSet attrs) {
39 | this(context, attrs, -1);
40 | }
41 |
42 | public SecondaryScreenView(Context context, AttributeSet attrs, int defStyleAttr) {
43 | super(context, attrs, defStyleAttr);
44 | TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.SecondaryScreenView);
45 | rate = array.getFloat(R.styleable.SecondaryScreenView_rate, rate);
46 | touchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
47 | }
48 |
49 | @Override
50 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
51 | int count = getChildCount();
52 | if (count > 2) {
53 | throw new RuntimeException("only can host 2 direct child view");
54 | }
55 | int widthMode = MeasureSpec.getMode(widthMeasureSpec);
56 | int heightMode = MeasureSpec.getMode(heightMeasureSpec);
57 | int widthSize = MeasureSpec.getSize(widthMeasureSpec);
58 | int heightSize = MeasureSpec.getSize(heightMeasureSpec);
59 | int usedWidth = 0;
60 | int usedHeight = 0;
61 | for (int i = 0; i < getChildCount(); i++) {
62 | View childView = getChildAt(i);
63 | if (childView.getVisibility() != View.GONE) {
64 | SecondaryScreenView.LayoutParams params = (SecondaryScreenView.LayoutParams) childView.getLayoutParams();
65 | int childWidthSpec = MeasureSpec.AT_MOST;
66 | int childHeightSpec = MeasureSpec.AT_MOST;
67 | switch (params.width) {
68 | case SecondaryScreenView.LayoutParams.MATCH_PARENT:
69 | if (widthMode == MeasureSpec.EXACTLY || widthMode == MeasureSpec.AT_MOST) {
70 | childWidthSpec = MeasureSpec.makeMeasureSpec(widthSize, MeasureSpec.EXACTLY);
71 | } else {
72 | childWidthSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
73 | }
74 | break;
75 | case SecondaryScreenView.LayoutParams.WRAP_CONTENT:
76 | if (widthMode == MeasureSpec.EXACTLY || widthMode == MeasureSpec.AT_MOST) {
77 | childWidthSpec = MeasureSpec.makeMeasureSpec(widthSize, MeasureSpec.AT_MOST);
78 | } else {
79 | childWidthSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
80 | }
81 | break;
82 | default:
83 | childWidthSpec = MeasureSpec.makeMeasureSpec(params.width, MeasureSpec.EXACTLY);
84 | break;
85 | }
86 | usedWidth += MeasureSpec.getSize(childWidthSpec) + params.leftMargin + params.rightMargin;
87 | switch (params.height) {
88 | case SecondaryScreenView.LayoutParams.MATCH_PARENT:
89 | if (heightMode == MeasureSpec.EXACTLY || heightMode == MeasureSpec.AT_MOST) {
90 | childHeightSpec = MeasureSpec.makeMeasureSpec(heightSize, MeasureSpec.EXACTLY);
91 | } else {
92 | childHeightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
93 | }
94 | break;
95 | case SecondaryScreenView.LayoutParams.WRAP_CONTENT:
96 | if (heightMode == MeasureSpec.EXACTLY || heightMode == MeasureSpec.AT_MOST) {
97 | childHeightSpec = MeasureSpec.makeMeasureSpec(heightSize, MeasureSpec.AT_MOST);
98 | } else {
99 | childHeightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
100 | }
101 | break;
102 | default:
103 | childHeightSpec = MeasureSpec.makeMeasureSpec(params.height, MeasureSpec.EXACTLY);
104 | break;
105 | }
106 | usedHeight += MeasureSpec.getSize(childHeightSpec) + params.bottomMargin + params.topMargin;
107 | measureChild(childView, childWidthSpec, childHeightSpec);
108 | }
109 | }
110 | if (widthMode == MeasureSpec.UNSPECIFIED) {
111 | widthSize = usedWidth;
112 | }
113 | if (heightMode == MeasureSpec.UNSPECIFIED) {
114 | heightSize = usedHeight;
115 | }
116 | setMeasuredDimension(widthSize, heightSize);
117 | secondaryView = getChildAt(0);
118 | mainView = getChildAt(1);
119 | }
120 |
121 | @Override
122 | protected void onLayout(boolean changed, int l, int t, int r, int b) {
123 | getAllViewPager(viewPagers, this);
124 | if (secondaryView != null) {
125 | secondaryView.layout(-secondaryView.getMeasuredWidth(), 0, 0, secondaryView.getMeasuredHeight());
126 | }
127 | if (mainView != null) {
128 | mainView.layout(0, 0, mainView.getMeasuredWidth(), secondaryView.getMeasuredHeight());
129 | }
130 | }
131 |
132 | private void getAllViewPager(ArrayList viewPagers, ViewGroup parent) {
133 | int childCount = parent.getChildCount();
134 | for (int i = 0; i < childCount; i++) {
135 | View child = parent.getChildAt(i);
136 | if (child instanceof ViewPager) {
137 | viewPagers.add((ViewPager) child);
138 | } else if (child instanceof ViewGroup) {
139 | getAllViewPager(viewPagers, (ViewGroup) child);
140 | }
141 | }
142 | }
143 |
144 | @Override
145 | public boolean onInterceptTouchEvent(MotionEvent ev) {
146 | // 处理viewpager的事件冲突
147 | ViewPager pager = getTouchedViewPager(ev);
148 | if (pager != null && pager.getCurrentItem() != 0) {
149 | return super.onInterceptTouchEvent(ev);
150 | }
151 | switch (ev.getAction()) {
152 | case MotionEvent.ACTION_DOWN:
153 | downX = (int) ev.getRawX();
154 | downY = (int) ev.getRawY();
155 | break;
156 | case MotionEvent.ACTION_MOVE:
157 | float delX = ev.getRawX() - downX;
158 | float delY = ev.getRawY() - downY;
159 | if (Math.abs(delX) > touchSlop && Math.abs(delX) > Math.abs(delY) && pager != null && pager.getCurrentItem() == 0 && delX > 0) {
160 | return true;
161 | }
162 | // if(secondaryView.getX()==0f&& Math.abs(delX)>touchSlop&& Math.abs(delX)> Math.abs(delY)&&pager!=null&&pager.getCurrentItem()==pager.getChildCount()-1&&delX<0){
163 | // return true;
164 | // }
165 | case MotionEvent.ACTION_UP:
166 | break;
167 | }
168 |
169 | return super.onInterceptTouchEvent(ev);
170 | }
171 |
172 | private ViewPager getTouchedViewPager(MotionEvent ev) {
173 | if (viewPagers == null || viewPagers.size() == 0) {
174 | return null;
175 | }
176 | Rect mRect = new Rect();
177 | for (ViewPager viewPager : viewPagers) {
178 | viewPager.getHitRect(mRect);
179 | if (mRect.contains((int) ev.getX(), (int) ev.getY())) {
180 | return viewPager;
181 | }
182 | }
183 | return null;
184 | }
185 |
186 | @Override
187 | public boolean onTouchEvent(MotionEvent event) {
188 | switch (event.getAction()) {
189 | case MotionEvent.ACTION_DOWN:
190 | downX = (int) event.getRawX();
191 | downY = (int) event.getRawY();
192 | break;
193 | case MotionEvent.ACTION_MOVE:
194 | int moveX = (int) (event.getRawX() - downX);
195 | int moveY = (int) (event.getRawY() - downY);
196 | if (secondaryView.getX() < 0 && moveX > 0) {
197 | moveX *= rate;
198 | }
199 | if (moveX > 0) {
200 | isScrollerRight = true;
201 | } else {
202 | isScrollerRight = false;
203 | }
204 | int translateX_second = endX + moveX;
205 | int translateX_main = endX + moveX;
206 | if (translateX_second >= secondaryView.getWidth()) {
207 | translateX_second = secondaryView.getWidth();
208 | translateX_main = mainView.getWidth();
209 | }
210 | if (translateX_second <= 0) {
211 | translateX_second = 0;
212 | translateX_main = 0;
213 | }
214 | secondaryView.setTranslationX(translateX_second);
215 | mainView.setTranslationX(translateX_main);
216 | break;
217 | case MotionEvent.ACTION_UP:
218 | endX = (int) mainView.getTranslationX();
219 | startTranslateAnim();
220 | break;
221 | }
222 | return true;
223 | }
224 |
225 | public void translateToSecondaryView() {
226 | endX = secondaryView.getWidth();
227 | isScrollerRight = true;
228 | startTranslateAnim();
229 | }
230 |
231 | public void translateToMainView() {
232 | endX = mainView.getWidth() * 1 / 3;
233 | isScrollerRight = false;
234 | startTranslateAnim();
235 | }
236 |
237 | public boolean isStillMainView() {
238 | return endX == 0 && mainView.getTranslationX() == 0;
239 | }
240 |
241 | private void startTranslateAnim() {
242 | float secondTranslationX = 0;
243 | float mainTranslationX = 0;
244 | if (isScrollerRight) {//右滑
245 | if (endX > secondaryView.getWidth() / 3) {
246 | secondTranslationX = secondaryView.getWidth();
247 | mainTranslationX = mainView.getWidth();
248 | isScrollerRight = false;
249 | } else {
250 | secondTranslationX = 0;
251 | mainTranslationX = 0;
252 | isScrollerRight = true;
253 | }
254 | } else {
255 | if (endX < mainView.getWidth() * 2 / 3) {
256 | secondTranslationX = 0;
257 | mainTranslationX = 0;
258 | isScrollerRight = true;
259 | } else {
260 | secondTranslationX = secondaryView.getWidth();
261 | mainTranslationX = mainView.getWidth();
262 | isScrollerRight = false;
263 | }
264 | }
265 | AnimatorSet animator = new AnimatorSet();
266 | ObjectAnimator animator_secondaryView = ObjectAnimator.ofFloat(secondaryView, "translationX", secondTranslationX);
267 | ObjectAnimator animator_mainView = ObjectAnimator.ofFloat(mainView, "translationX", mainTranslationX);
268 | animator.setDuration(200);
269 | animator.setInterpolator(new LinearInterpolator());
270 | animator.addListener(new Animator.AnimatorListener() {
271 | @Override
272 | public void onAnimationStart(Animator animation) {
273 |
274 | }
275 |
276 | @Override
277 | public void onAnimationEnd(Animator animation) {
278 | endX = (int) mainView.getTranslationX();
279 | }
280 |
281 | @Override
282 | public void onAnimationCancel(Animator animation) {
283 |
284 | }
285 |
286 | @Override
287 | public void onAnimationRepeat(Animator animation) {
288 |
289 | }
290 | });
291 | animator.play(animator_secondaryView).with(animator_mainView);
292 | animator.start();
293 |
294 | }
295 |
296 | public static class LayoutParams extends MarginLayoutParams {
297 |
298 | public LayoutParams(Context c, AttributeSet attrs) {
299 | super(c, attrs);
300 | }
301 |
302 | public LayoutParams(int width, int height) {
303 | super(width, height);
304 | }
305 |
306 | public LayoutParams(ViewGroup.LayoutParams source) {
307 | super(source);
308 | }
309 | }
310 |
311 | @Override
312 | protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
313 | return new SecondaryScreenView.LayoutParams(p);
314 | }
315 |
316 | @Override
317 | protected ViewGroup.LayoutParams generateDefaultLayoutParams() {
318 | return new SecondaryScreenView.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
319 | }
320 |
321 | @Override
322 | public ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs) {
323 | return new SecondaryScreenView.LayoutParams(getContext(), attrs);
324 | }
325 |
326 | @Override
327 | protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
328 | return p instanceof SecondaryScreenView.LayoutParams;
329 | }
330 | }
331 |
--------------------------------------------------------------------------------
/app/src/main/java/com/zhl/secondaryscreen/view/TagImageView.java:
--------------------------------------------------------------------------------
1 | package com.zhl.secondaryscreen.view;
2 |
3 | import android.content.Context;
4 | import android.content.res.TypedArray;
5 | import android.graphics.Canvas;
6 | import android.graphics.Paint;
7 | import android.graphics.Path;
8 | import android.graphics.Rect;
9 | import android.util.AttributeSet;
10 |
11 | import com.zhl.secondaryscreen.R;
12 |
13 |
14 | /**
15 | * 描述:
16 | * Created by zhaohl on 2018-5-21.
17 | */
18 | public class TagImageView extends android.support.v7.widget.AppCompatImageView {
19 | private Paint tagPaint;
20 | private Paint backgroundPaint;
21 | private int tagSize = 40;
22 | private String tag = "NEW";
23 | private int tagBackgroud = 0XFFFB0C0C;
24 | private int textColor = 0XFFFFFFFF;
25 | private Location location = Location.ON_TOP_RIGHT;
26 | private boolean showTag = true;
27 |
28 | public enum Location{
29 | ON_TOP_lEFT,ON_TOP_RIGHT
30 | }
31 |
32 | public TagImageView(Context context) {
33 | this(context,null);
34 | }
35 |
36 | public TagImageView(Context context, AttributeSet attrs) {
37 | this(context, attrs,-1);
38 | }
39 |
40 | public TagImageView(Context context, AttributeSet attrs, int defStyleAttr) {
41 | super(context, attrs, defStyleAttr);
42 | TypedArray array = getContext().obtainStyledAttributes(attrs, R.styleable.TagImageAttr);
43 | if(array!=null&&array.length()>0){
44 | textColor = array.getColor(R.styleable.TagImageAttr_tagTextColor,0XFFFFFFFF);
45 | tagSize = array.getInt(R.styleable.TagImageAttr_tagSize,40);
46 | tagBackgroud = array.getColor(R.styleable.TagImageAttr_tagBackgroud,0XFFFB0C0C);
47 | showTag = array.getBoolean(R.styleable.TagImageAttr_showTag,true);
48 | int loc = array.getInt(R.styleable.TagImageAttr_tagLocation,1);
49 | switch (loc){
50 | case 0:
51 | location = Location.ON_TOP_lEFT;
52 | break;
53 | case 1:
54 | location = Location.ON_TOP_RIGHT;
55 | break;
56 | }
57 | array.recycle();
58 | }
59 | tagPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
60 | backgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
61 | tagPaint.setColor(textColor);
62 | tagPaint.setFakeBoldText(true);
63 | backgroundPaint.setColor(tagBackgroud);
64 | tagPaint.setTextSize(tagSize);
65 | setScaleType(ScaleType.FIT_XY);
66 | }
67 |
68 | @Override
69 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
70 | super.onMeasure(widthMeasureSpec, heightMeasureSpec);
71 | }
72 |
73 | @Override
74 | protected void onDraw(Canvas canvas) {
75 | super.onDraw(canvas);
76 | if(showTag){
77 | double sin45 = Math.sin(Math.toRadians(45));
78 | // 先测出文字大小
79 | Paint.FontMetrics metrics = new Paint.FontMetrics();
80 | tagPaint.getFontMetrics(metrics);
81 |
82 | Rect bounds = new Rect();
83 | tagPaint.getTextBounds(tag,1,tag.length(),bounds);
84 |
85 | float textW = tagPaint.measureText(tag);
86 | float textH = metrics.bottom-metrics.top;
87 |
88 | float bgH = textH*1.2f;
89 | float offsetV = -(bgH-(bounds.bottom-bounds.top))/2;
90 | float unit = (float) (bgH/sin45);
91 | float wrapW = (float) (unit/sin45);
92 | float offsetH = bgH+((wrapW-textW)/2);
93 |
94 | switch (location){
95 | case ON_TOP_lEFT:
96 | drawOnLeft(canvas,unit,offsetH,offsetV);
97 | break;
98 | case ON_TOP_RIGHT:
99 | drawOnRight(canvas,unit,offsetH,offsetV);
100 | break;
101 | }
102 | }
103 | }
104 |
105 | private void drawOnLeft(Canvas canvas, float unit, float offsetH, float offsetV) {
106 | Path path = new Path();
107 | path.moveTo(unit,0);
108 | path.lineTo(2*unit,0);
109 | path.lineTo(0,2*unit);
110 | path.lineTo(0,unit);
111 | path.close();
112 | canvas.drawPath(path,backgroundPaint);
113 |
114 | Path tagPath = new Path();
115 | tagPath.moveTo(0,2*unit);
116 | tagPath.lineTo(2*unit,0);
117 |
118 | canvas.drawTextOnPath(tag,tagPath, offsetH,offsetV,tagPaint);
119 | }
120 |
121 | private void drawOnRight(Canvas canvas, float unit, float offsetH, float offsetV){
122 | Path path = new Path();
123 | path.moveTo(getMeasuredWidth()-2*unit,0);
124 | path.lineTo(getMeasuredWidth()-unit,0);
125 | path.lineTo(getMeasuredWidth(),unit);
126 | path.lineTo(getMeasuredWidth(),2*unit);
127 | path.close();
128 | canvas.drawPath(path,backgroundPaint);
129 |
130 | Path tagPath = new Path();
131 | tagPath.moveTo(getMeasuredWidth()-2*unit,0);
132 | tagPath.lineTo(getMeasuredWidth(),2*unit);
133 |
134 | canvas.drawTextOnPath(tag,tagPath, offsetH,offsetV,tagPaint);
135 | }
136 |
137 | public void setTagSize(int size){
138 | if(size<=0||size>200){
139 | return ;
140 | }
141 | tagSize = size;
142 | tagPaint.setTextSize(tagSize);
143 | invalidate();
144 | }
145 |
146 | public void setTagBackgroud(int color){
147 | tagBackgroud = color;
148 | backgroundPaint.setColor(tagBackgroud);
149 | invalidate();
150 | }
151 | public void setTagTextColor(int color){
152 | textColor = color;
153 | tagPaint.setColor(textColor);
154 | invalidate();
155 | }
156 |
157 | public void setTagLocation(Location location){
158 | this.location = location;
159 | invalidate();
160 | }
161 |
162 | public void showTag(boolean show){
163 | this.showTag = show;
164 | invalidate();
165 | }
166 |
167 | }
168 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v24/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
12 |
13 |
19 |
22 |
25 |
26 |
27 |
28 |
34 |
35 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/drawable_refresh_tv.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
14 |
15 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
10 |
15 |
20 |
25 |
30 |
35 |
40 |
45 |
50 |
55 |
60 |
65 |
70 |
75 |
80 |
85 |
90 |
95 |
100 |
105 |
110 |
115 |
120 |
125 |
130 |
135 |
140 |
145 |
150 |
155 |
160 |
165 |
170 |
171 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_custom_progress_bar.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
21 |
22 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_custom_refresh_header.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
11 |
12 |
16 |
17 |
32 |
33 |
34 |
35 |
36 |
40 |
41 |
44 |
45 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_custom_view_test.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
21 |
22 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
12 |
13 |
21 |
22 |
26 |
27 |
31 |
32 |
38 |
39 |
43 |
44 |
45 |
46 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_pull_secondview.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
12 |
13 |
14 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/custom_refresh_header.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
16 |
17 |
27 |
28 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fg_second_floor.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
13 |
14 |
18 |
19 |
34 |
35 |
36 |
37 |
38 |
41 |
42 |
46 |
47 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_cardview.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yilylong/SecondaryScreen/29aecc544c33043315acb9624a82db8b0a7b8ef5/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yilylong/SecondaryScreen/29aecc544c33043315acb9624a82db8b0a7b8ef5/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yilylong/SecondaryScreen/29aecc544c33043315acb9624a82db8b0a7b8ef5/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yilylong/SecondaryScreen/29aecc544c33043315acb9624a82db8b0a7b8ef5/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yilylong/SecondaryScreen/29aecc544c33043315acb9624a82db8b0a7b8ef5/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yilylong/SecondaryScreen/29aecc544c33043315acb9624a82db8b0a7b8ef5/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/arrow_down.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yilylong/SecondaryScreen/29aecc544c33043315acb9624a82db8b0a7b8ef5/app/src/main/res/mipmap-xxhdpi/arrow_down.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/bg2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yilylong/SecondaryScreen/29aecc544c33043315acb9624a82db8b0a7b8ef5/app/src/main/res/mipmap-xxhdpi/bg2.jpg
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yilylong/SecondaryScreen/29aecc544c33043315acb9624a82db8b0a7b8ef5/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yilylong/SecondaryScreen/29aecc544c33043315acb9624a82db8b0a7b8ef5/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/img_1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yilylong/SecondaryScreen/29aecc544c33043315acb9624a82db8b0a7b8ef5/app/src/main/res/mipmap-xxhdpi/img_1.jpg
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/img_3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yilylong/SecondaryScreen/29aecc544c33043315acb9624a82db8b0a7b8ef5/app/src/main/res/mipmap-xxhdpi/img_3.jpg
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/progressbar_bg.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yilylong/SecondaryScreen/29aecc544c33043315acb9624a82db8b0a7b8ef5/app/src/main/res/mipmap-xxhdpi/progressbar_bg.jpg
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/second_floor_main.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yilylong/SecondaryScreen/29aecc544c33043315acb9624a82db8b0a7b8ef5/app/src/main/res/mipmap-xxhdpi/second_floor_main.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/secondary_screen.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yilylong/SecondaryScreen/29aecc544c33043315acb9624a82db8b0a7b8ef5/app/src/main/res/mipmap-xxhdpi/secondary_screen.jpg
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/top_right_search_black.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yilylong/SecondaryScreen/29aecc544c33043315acb9624a82db8b0a7b8ef5/app/src/main/res/mipmap-xxhdpi/top_right_search_black.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/v1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yilylong/SecondaryScreen/29aecc544c33043315acb9624a82db8b0a7b8ef5/app/src/main/res/mipmap-xxhdpi/v1.jpg
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/v2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yilylong/SecondaryScreen/29aecc544c33043315acb9624a82db8b0a7b8ef5/app/src/main/res/mipmap-xxhdpi/v2.jpg
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/v3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yilylong/SecondaryScreen/29aecc544c33043315acb9624a82db8b0a7b8ef5/app/src/main/res/mipmap-xxhdpi/v3.jpg
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yilylong/SecondaryScreen/29aecc544c33043315acb9624a82db8b0a7b8ef5/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yilylong/SecondaryScreen/29aecc544c33043315acb9624a82db8b0a7b8ef5/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/values/attrs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #008577
4 | #00574B
5 | #D81B60
6 | #666666
7 | #33FF66
8 | #FF3333
9 | #55c8c6c6
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | SecondaryScreen
3 |
4 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/test/java/com/zhl/secondaryscreen/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.zhl.secondaryscreen;
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() {
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 | google()
6 | jcenter()
7 | maven { url "https://jitpack.io" }
8 |
9 | }
10 | dependencies {
11 | classpath 'com.android.tools.build:gradle:3.5.3'
12 |
13 | // NOTE: Do not place your application dependencies here; they belong
14 | // in the individual module build.gradle files
15 | }
16 | }
17 |
18 | allprojects {
19 | repositories {
20 | google()
21 | jcenter()
22 | maven { url "https://jitpack.io" }
23 | }
24 | }
25 |
26 | task clean(type: Delete) {
27 | delete rootProject.buildDir
28 | }
29 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 | # IDE (e.g. Android Studio) users:
3 | # Gradle settings configured through the IDE *will override*
4 | # any settings specified in this file.
5 | # For more details on how to configure your build environment visit
6 | # http://www.gradle.org/docs/current/userguide/build_environment.html
7 | # Specifies the JVM arguments used for the daemon process.
8 | # The setting is particularly useful for tweaking memory settings.
9 | org.gradle.jvmargs=-Xmx1536m
10 | # When configured, Gradle will run in incubating parallel mode.
11 | # This option should only be used with decoupled projects. More details, visit
12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
13 | # org.gradle.parallel=true
14 |
15 |
16 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yilylong/SecondaryScreen/29aecc544c33043315acb9624a82db8b0a7b8ef5/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Wed Jun 26 10:34:38 CST 2019
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip
7 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Attempt to set APP_HOME
10 | # Resolve links: $0 may be a link
11 | PRG="$0"
12 | # Need this for relative symlinks.
13 | while [ -h "$PRG" ] ; do
14 | ls=`ls -ld "$PRG"`
15 | link=`expr "$ls" : '.*-> \(.*\)$'`
16 | if expr "$link" : '/.*' > /dev/null; then
17 | PRG="$link"
18 | else
19 | PRG=`dirname "$PRG"`"/$link"
20 | fi
21 | done
22 | SAVED="`pwd`"
23 | cd "`dirname \"$PRG\"`/" >/dev/null
24 | APP_HOME="`pwd -P`"
25 | cd "$SAVED" >/dev/null
26 |
27 | APP_NAME="Gradle"
28 | APP_BASE_NAME=`basename "$0"`
29 |
30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
31 | DEFAULT_JVM_OPTS=""
32 |
33 | # Use the maximum available, or set MAX_FD != -1 to use that value.
34 | MAX_FD="maximum"
35 |
36 | warn () {
37 | echo "$*"
38 | }
39 |
40 | die () {
41 | echo
42 | echo "$*"
43 | echo
44 | exit 1
45 | }
46 |
47 | # OS specific support (must be 'true' or 'false').
48 | cygwin=false
49 | msys=false
50 | darwin=false
51 | nonstop=false
52 | case "`uname`" in
53 | CYGWIN* )
54 | cygwin=true
55 | ;;
56 | Darwin* )
57 | darwin=true
58 | ;;
59 | MINGW* )
60 | msys=true
61 | ;;
62 | NONSTOP* )
63 | nonstop=true
64 | ;;
65 | esac
66 |
67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
68 |
69 | # Determine the Java command to use to start the JVM.
70 | if [ -n "$JAVA_HOME" ] ; then
71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
72 | # IBM's JDK on AIX uses strange locations for the executables
73 | JAVACMD="$JAVA_HOME/jre/sh/java"
74 | else
75 | JAVACMD="$JAVA_HOME/bin/java"
76 | fi
77 | if [ ! -x "$JAVACMD" ] ; then
78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
79 |
80 | Please set the JAVA_HOME variable in your environment to match the
81 | location of your Java installation."
82 | fi
83 | else
84 | JAVACMD="java"
85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
86 |
87 | Please set the JAVA_HOME variable in your environment to match the
88 | location of your Java installation."
89 | fi
90 |
91 | # Increase the maximum file descriptors if we can.
92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
93 | MAX_FD_LIMIT=`ulimit -H -n`
94 | if [ $? -eq 0 ] ; then
95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
96 | MAX_FD="$MAX_FD_LIMIT"
97 | fi
98 | ulimit -n $MAX_FD
99 | if [ $? -ne 0 ] ; then
100 | warn "Could not set maximum file descriptor limit: $MAX_FD"
101 | fi
102 | else
103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
104 | fi
105 | fi
106 |
107 | # For Darwin, add options to specify how the application appears in the dock
108 | if $darwin; then
109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
110 | fi
111 |
112 | # For Cygwin, switch paths to Windows format before running java
113 | if $cygwin ; then
114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
116 | JAVACMD=`cygpath --unix "$JAVACMD"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Escape application args
158 | save () {
159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
160 | echo " "
161 | }
162 | APP_ARGS=$(save "$@")
163 |
164 | # Collect all arguments for the java command, following the shell quoting and substitution rules
165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
166 |
167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
169 | cd "$(dirname "$0")"
170 | fi
171 |
172 | exec "$JAVACMD" "$@"
173 |
--------------------------------------------------------------------------------
/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 | set DIRNAME=%~dp0
12 | if "%DIRNAME%" == "" set DIRNAME=.
13 | set APP_BASE_NAME=%~n0
14 | set APP_HOME=%DIRNAME%
15 |
16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
17 | set DEFAULT_JVM_OPTS=
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 Windows variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 |
53 | :win9xME_args
54 | @rem Slurp the command line arguments.
55 | set CMD_LINE_ARGS=
56 | set _SKIP=2
57 |
58 | :win9xME_args_slurp
59 | if "x%~1" == "x" goto execute
60 |
61 | set CMD_LINE_ARGS=%*
62 |
63 | :execute
64 | @rem Setup the command line
65 |
66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
67 |
68 | @rem Execute Gradle
69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
70 |
71 | :end
72 | @rem End local scope for the variables with windows NT shell
73 | if "%ERRORLEVEL%"=="0" goto mainEnd
74 |
75 | :fail
76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
77 | rem the _cmd.exe /c_ return code!
78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
79 | exit /b 1
80 |
81 | :mainEnd
82 | if "%OS%"=="Windows_NT" endlocal
83 |
84 | :omega
85 |
--------------------------------------------------------------------------------
/image/show.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yilylong/SecondaryScreen/29aecc544c33043315acb9624a82db8b0a7b8ef5/image/show.gif
--------------------------------------------------------------------------------
/image/show_video.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yilylong/SecondaryScreen/29aecc544c33043315acb9624a82db8b0a7b8ef5/image/show_video.jpg
--------------------------------------------------------------------------------
/image/show_video.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yilylong/SecondaryScreen/29aecc544c33043315acb9624a82db8b0a7b8ef5/image/show_video.mp4
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
--------------------------------------------------------------------------------
/show.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yilylong/SecondaryScreen/29aecc544c33043315acb9624a82db8b0a7b8ef5/show.gif
--------------------------------------------------------------------------------
/show2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yilylong/SecondaryScreen/29aecc544c33043315acb9624a82db8b0a7b8ef5/show2.jpg
--------------------------------------------------------------------------------
/show3.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yilylong/SecondaryScreen/29aecc544c33043315acb9624a82db8b0a7b8ef5/show3.gif
--------------------------------------------------------------------------------
/video_show_secondfloorview.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yilylong/SecondaryScreen/29aecc544c33043315acb9624a82db8b0a7b8ef5/video_show_secondfloorview.gif
--------------------------------------------------------------------------------